new gesture/toolbar actions

This commit is contained in:
Fabian Freund
2026-08-04 16:16:25 +02:00
parent dbfcd1daaa
commit 31b863427f
8 changed files with 89 additions and 2 deletions
@@ -45,7 +45,7 @@ final class HomeTargetControllerProvider
} }
String _$homeTargetControllerHash() => String _$homeTargetControllerHash() =>
r'1bb3a879ee569261b1dfcc4c0d8b28ef0cb7f7d3'; r'db486c85ce71b99a67fde8ca142da43aef402973';
/// Applies the configured [HomeTarget] when the browser has nothing to show. /// Applies the configured [HomeTarget] when the browser has nothing to show.
@@ -21,6 +21,7 @@
enum ToolbarButtonId { enum ToolbarButtonId {
back, back,
forward, forward,
home,
history, history,
bookmarks, bookmarks,
bookmarkToggle, bookmarkToggle,
@@ -44,5 +45,6 @@ enum ToolbarButtonId {
font, font,
extensionShortcut, extensionShortcut,
toggleGestures, toggleGestures,
hideTabBar,
quit, quit,
} }
@@ -46,6 +46,11 @@ const forwardToolbarButtonSpec = ToolbarButtonSpec(
defaultFallback: ToolbarButtonId.share, defaultFallback: ToolbarButtonId.share,
); );
const homeToolbarButtonSpec = ToolbarButtonSpec(
id: ToolbarButtonId.home,
defaultVisible: false,
);
const historyToolbarButtonSpec = ToolbarButtonSpec( const historyToolbarButtonSpec = ToolbarButtonSpec(
id: ToolbarButtonId.history, id: ToolbarButtonId.history,
defaultVisible: false, defaultVisible: false,
@@ -174,9 +179,16 @@ const toggleGesturesToolbarButtonSpec = ToolbarButtonSpec(
defaultVisible: false, defaultVisible: false,
); );
const hideTabBarToolbarButtonSpec = ToolbarButtonSpec(
id: ToolbarButtonId.hideTabBar,
defaultVisible: false,
canBeFallbackTarget: false,
);
const toolbarButtonSpecs = [ const toolbarButtonSpecs = [
backToolbarButtonSpec, backToolbarButtonSpec,
forwardToolbarButtonSpec, forwardToolbarButtonSpec,
homeToolbarButtonSpec,
historyToolbarButtonSpec, historyToolbarButtonSpec,
bookmarksToolbarButtonSpec, bookmarksToolbarButtonSpec,
bookmarkToggleToolbarButtonSpec, bookmarkToggleToolbarButtonSpec,
@@ -200,6 +212,7 @@ const toolbarButtonSpecs = [
fontToolbarButtonSpec, fontToolbarButtonSpec,
extensionShortcutToolbarButtonSpec, extensionShortcutToolbarButtonSpec,
toggleGesturesToolbarButtonSpec, toggleGesturesToolbarButtonSpec,
hideTabBarToolbarButtonSpec,
quitToolbarButtonSpec, quitToolbarButtonSpec,
]; ];
@@ -40,6 +40,7 @@ import 'package:weblibre/features/geckoview/features/browser/features/contextual
import 'package:weblibre/features/geckoview/features/browser/features/contextual_toolbar/domain/entities/toolbar_config_location.dart'; import 'package:weblibre/features/geckoview/features/browser/features/contextual_toolbar/domain/entities/toolbar_config_location.dart';
import 'package:weblibre/features/geckoview/features/browser/features/contextual_toolbar/presentation/models/contextual_toolbar_scope.dart'; import 'package:weblibre/features/geckoview/features/browser/features/contextual_toolbar/presentation/models/contextual_toolbar_scope.dart';
import 'package:weblibre/features/geckoview/features/browser/features/contextual_toolbar/presentation/widgets/contextual_bar_buttons.dart'; import 'package:weblibre/features/geckoview/features/browser/features/contextual_toolbar/presentation/widgets/contextual_bar_buttons.dart';
import 'package:weblibre/features/geckoview/features/browser/presentation/controllers/toolbar_visibility.dart';
import 'package:weblibre/features/geckoview/features/browser/presentation/utils/tab_close_confirmation.dart'; import 'package:weblibre/features/geckoview/features/browser/presentation/utils/tab_close_confirmation.dart';
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/extension_shortcut_menu.dart'; import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/extension_shortcut_menu.dart';
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/font_size_bottom_sheet.dart'; import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/font_size_bottom_sheet.dart';
@@ -49,6 +50,7 @@ import 'package:weblibre/features/geckoview/features/browser/presentation/widget
import 'package:weblibre/features/geckoview/features/find_in_page/presentation/controllers/find_in_page.dart'; import 'package:weblibre/features/geckoview/features/find_in_page/presentation/controllers/find_in_page.dart';
import 'package:weblibre/features/geckoview/features/readerview/presentation/controllers/readerable.dart'; import 'package:weblibre/features/geckoview/features/readerview/presentation/controllers/readerable.dart';
import 'package:weblibre/features/geckoview/features/tabs/data/entities/tab_mode.dart'; import 'package:weblibre/features/geckoview/features/tabs/data/entities/tab_mode.dart';
import 'package:weblibre/features/geckoview/features/tabs/domain/providers/selected_container.dart';
import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/tab.dart'; import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/tab.dart';
import 'package:weblibre/features/gestures/data/models/gesture_settings.dart'; import 'package:weblibre/features/gestures/data/models/gesture_settings.dart';
import 'package:weblibre/features/gestures/domain/repositories/gesture_settings.dart'; import 'package:weblibre/features/gestures/domain/repositories/gesture_settings.dart';
@@ -146,6 +148,22 @@ final List<ToolbarButtonDefinition> toolbarButtonRegistry = [
return NavigateForwardButton(selectedTabId: scope.selectedTabId); return NavigateForwardButton(selectedTabId: scope.selectedTabId);
}, },
), ),
ToolbarButtonDefinition(
spec: homeToolbarButtonSpec,
label: 'Home',
icon: Icons.home_outlined,
builder: (scope, context, ref) {
return IconButton(
tooltip: 'Home',
onPressed: scope.isPreview
? () {}
: () {
ref.read(forceBrowserHomeProvider.notifier).request();
},
icon: const Icon(Icons.home_outlined),
);
},
),
ToolbarButtonDefinition( ToolbarButtonDefinition(
spec: historyToolbarButtonSpec, spec: historyToolbarButtonSpec,
label: 'History', label: 'History',
@@ -450,6 +468,30 @@ final List<ToolbarButtonDefinition> toolbarButtonRegistry = [
); );
}, },
), ),
ToolbarButtonDefinition(
spec: hideTabBarToolbarButtonSpec,
label: 'Hide Tab Bar',
icon: MdiIcons.dockBottom,
builder: (scope, context, ref) {
return IconButton(
tooltip: 'Hide tab bar',
// Same dismissal the swipe on the bar performs; the dock FAB brings it
// back afterwards, since this button goes away with the bar.
onPressed: scope.isPreview
? () {}
: () {
ref
.read(
toolbarVisibilityControllerProvider(
scope.selectedTabId,
).notifier,
)
.dismiss();
},
icon: const Icon(MdiIcons.dockBottom),
);
},
),
ToolbarButtonDefinition( ToolbarButtonDefinition(
spec: pageUpToolbarButtonSpec, spec: pageUpToolbarButtonSpec,
label: 'Page Up', label: 'Page Up',
@@ -162,6 +162,12 @@ enum GestureAction {
), ),
// Open // Open
showHome(
'Home',
'Open the home screen',
Icons.home_outlined,
GestureActionCategory.open,
),
showHistory( showHistory(
'History', 'History',
'Open browsing history', 'Open browsing history',
@@ -176,6 +182,12 @@ enum GestureAction {
), ),
// App // App
toggleTabBar(
'Hide / Show Tab Bar',
'Hide the tab bar, or bring it back',
MdiIcons.dockBottom,
GestureActionCategory.app,
),
moveToBackground( moveToBackground(
'Minimize', 'Minimize',
'Send WebLibre to the background', 'Send WebLibre to the background',
@@ -259,8 +259,10 @@ const _$GestureActionEnumMap = {
GestureAction.decreaseFontSize: 'decreaseFontSize', GestureAction.decreaseFontSize: 'decreaseFontSize',
GestureAction.toggleBookmark: 'toggleBookmark', GestureAction.toggleBookmark: 'toggleBookmark',
GestureAction.translatePage: 'translatePage', GestureAction.translatePage: 'translatePage',
GestureAction.showHome: 'showHome',
GestureAction.showHistory: 'showHistory', GestureAction.showHistory: 'showHistory',
GestureAction.showBookmarks: 'showBookmarks', GestureAction.showBookmarks: 'showBookmarks',
GestureAction.toggleTabBar: 'toggleTabBar',
GestureAction.moveToBackground: 'moveToBackground', GestureAction.moveToBackground: 'moveToBackground',
GestureAction.quitBrowser: 'quitBrowser', GestureAction.quitBrowser: 'quitBrowser',
}; };
@@ -35,10 +35,12 @@ import 'package:weblibre/features/geckoview/domain/providers/tab_state.dart';
import 'package:weblibre/features/geckoview/domain/repositories/tab.dart'; import 'package:weblibre/features/geckoview/domain/repositories/tab.dart';
import 'package:weblibre/features/geckoview/features/bookmarks/domain/repositories/bookmarks.dart'; import 'package:weblibre/features/geckoview/features/bookmarks/domain/repositories/bookmarks.dart';
import 'package:weblibre/features/geckoview/features/browser/domain/entities/font_size_constants.dart'; import 'package:weblibre/features/geckoview/features/browser/domain/entities/font_size_constants.dart';
import 'package:weblibre/features/geckoview/features/browser/presentation/controllers/toolbar_visibility.dart';
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/translation_bottom_sheet.dart'; import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/translation_bottom_sheet.dart';
import 'package:weblibre/features/geckoview/features/find_in_page/presentation/controllers/find_in_page.dart'; import 'package:weblibre/features/geckoview/features/find_in_page/presentation/controllers/find_in_page.dart';
import 'package:weblibre/features/geckoview/features/readerview/presentation/controllers/readerable.dart'; import 'package:weblibre/features/geckoview/features/readerview/presentation/controllers/readerable.dart';
import 'package:weblibre/features/geckoview/features/tabs/domain/providers.dart'; import 'package:weblibre/features/geckoview/features/tabs/domain/providers.dart';
import 'package:weblibre/features/geckoview/features/tabs/domain/providers/selected_container.dart';
import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/tab.dart'; import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/tab.dart';
import 'package:weblibre/features/gestures/data/models/gesture_action.dart'; import 'package:weblibre/features/gestures/data/models/gesture_action.dart';
import 'package:weblibre/features/gestures/data/models/gesture_settings.dart'; import 'package:weblibre/features/gestures/data/models/gesture_settings.dart';
@@ -193,6 +195,20 @@ class GestureControlService extends _$GestureControlService {
await _adjustFontSize(increase: true); await _adjustFontSize(increase: true);
case GestureAction.decreaseFontSize: case GestureAction.decreaseFontSize:
await _adjustFontSize(increase: false); await _adjustFontSize(increase: false);
case GestureAction.showHome:
ref.read(forceBrowserHomeProvider.notifier).request();
case GestureAction.toggleTabBar:
final controller = ref.read(
toolbarVisibilityControllerProvider(tabId).notifier,
);
// Dismissing is the only state the user cannot leave by scrolling, so
// the same gesture has to bring the bar back.
if (ref.read(toolbarVisibilityControllerProvider(tabId)) ==
ToolbarVisibility.dismissed) {
controller.forceShow();
} else {
controller.dismiss();
}
case GestureAction.showHistory: case GestureAction.showHistory:
await _pushLocation(const HistoryRoute().location); await _pushLocation(const HistoryRoute().location);
case GestureAction.showBookmarks: case GestureAction.showBookmarks:
@@ -66,7 +66,7 @@ final class GestureControlServiceProvider
} }
String _$gestureControlServiceHash() => String _$gestureControlServiceHash() =>
r'3741c0a3d9cb6726c044bab1efd4ce80208f21d8'; r'be774bb3a9cd7793167c7b6f6c656caf2abff380';
/// Bridges gesture settings and recognized-gesture events to app actions. /// Bridges gesture settings and recognized-gesture events to app actions.
/// ///