From 05a38ef0f13262513f97ff13eab6f64df0b8b36f Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Tue, 1 Oct 2024 01:53:42 -0300 Subject: [PATCH 01/20] chore: Dependencies --- linux/flutter/generated_plugins.cmake | 1 - .../unity_video_player_main/pubspec.yaml | 4 -- pubspec.lock | 37 +++++++------------ windows/flutter/generated_plugins.cmake | 1 - 4 files changed, 14 insertions(+), 29 deletions(-) diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 9d520730..1f4aaf58 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -13,7 +13,6 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST - media_kit_native_event_loop ) set(PLUGIN_BUNDLED_LIBRARIES) diff --git a/packages/unity_video_player/unity_video_player_main/pubspec.yaml b/packages/unity_video_player/unity_video_player_main/pubspec.yaml index 6effe1af..021c5ede 100644 --- a/packages/unity_video_player/unity_video_player_main/pubspec.yaml +++ b/packages/unity_video_player/unity_video_player_main/pubspec.yaml @@ -22,10 +22,6 @@ dependencies: # git: # url: https://github.com/media-kit/media-kit/ # path: media_kit/ - media_kit_native_event_loop: - git: - url: https://github.com/media-kit/media-kit/ - path: media_kit_native_event_loop/ # media_kit_video: # git: # url: https://github.com/media-kit/media-kit/ diff --git a/pubspec.lock b/pubspec.lock index 677c3793..c4f31236 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -562,7 +562,7 @@ packages: description: path: "libs/android/media_kit_libs_android_video" ref: HEAD - resolved-ref: e41e50c8cfb370e69612b205dcfd9f3ca80690f5 + resolved-ref: "88c49c6c0f6187a131a4053f0f1a3a42f2922a8a" url: "https://github.com/media-kit/media-kit/" source: git version: "1.3.6" @@ -571,7 +571,7 @@ packages: description: path: "libs/ios/media_kit_libs_ios_video" ref: HEAD - resolved-ref: e41e50c8cfb370e69612b205dcfd9f3ca80690f5 + resolved-ref: "88c49c6c0f6187a131a4053f0f1a3a42f2922a8a" url: "https://github.com/media-kit/media-kit/" source: git version: "1.1.4" @@ -580,7 +580,7 @@ packages: description: path: "libs/macos/media_kit_libs_macos_video" ref: HEAD - resolved-ref: e41e50c8cfb370e69612b205dcfd9f3ca80690f5 + resolved-ref: "88c49c6c0f6187a131a4053f0f1a3a42f2922a8a" url: "https://github.com/media-kit/media-kit/" source: git version: "1.1.4" @@ -589,19 +589,10 @@ packages: description: path: "libs/windows/media_kit_libs_windows_video" ref: HEAD - resolved-ref: e41e50c8cfb370e69612b205dcfd9f3ca80690f5 + resolved-ref: "88c49c6c0f6187a131a4053f0f1a3a42f2922a8a" url: "https://github.com/media-kit/media-kit/" source: git version: "1.0.10" - media_kit_native_event_loop: - dependency: transitive - description: - path: media_kit_native_event_loop - ref: HEAD - resolved-ref: e41e50c8cfb370e69612b205dcfd9f3ca80690f5 - url: "https://github.com/media-kit/media-kit/" - source: git - version: "1.0.9" media_kit_video: dependency: transitive description: @@ -955,10 +946,10 @@ packages: dependency: transitive description: name: synchronized - sha256: "51b08572b9f091f8c3eb4d9d4be253f196ff0075d5ec9b10a884026d5b55d7bc" + sha256: "69fe30f3a8b04a0be0c15ae6490fc859a78ef4c43ae2dd5e8a623d45bfcf9225" url: "https://pub.dev" source: hosted - version: "3.3.0+2" + version: "3.3.0+3" term_glyph: dependency: transitive description: @@ -1078,10 +1069,10 @@ packages: dependency: transitive description: name: url_launcher_macos - sha256: "9a1a42d5d2d95400c795b2914c36fdcb525870c752569438e4ebb09a2b5d90de" + sha256: "769549c999acdb42b8bcfa7c43d72bf79a382ca7441ab18a808e101149daf672" url: "https://pub.dev" source: hosted - version: "3.2.0" + version: "3.2.1" url_launcher_platform_interface: dependency: transitive description: @@ -1110,10 +1101,10 @@ packages: dependency: "direct main" description: name: uuid - sha256: f33d6bb662f0e4f79dcd7ada2e6170f3b3a2530c28fc41f49a411ddedd576a77 + sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff url: "https://pub.dev" source: hosted - version: "4.5.0" + version: "4.5.1" vector_math: dependency: transitive description: @@ -1142,10 +1133,10 @@ packages: dependency: transitive description: name: video_player_android - sha256: "38d8fe136c427abdce68b5e8c3c08ea29d7a794b453c7a51b12ecfad4aad9437" + sha256: "45d21bbba3d10b7182aa08ade5d4c68ed3367016d40f29732bb04a799b26842d" url: "https://pub.dev" source: hosted - version: "2.7.3" + version: "2.7.5" video_player_avfoundation: dependency: transitive description: @@ -1206,10 +1197,10 @@ packages: dependency: transitive description: name: web - sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062 + sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.1.0" win32: dependency: transitive description: diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index ed265f3e..7f90e002 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -17,7 +17,6 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST - media_kit_native_event_loop ) set(PLUGIN_BUNDLED_LIBRARIES) From 8fa59aedc6c16028d3a3aa32c1e06b28050c03a2 Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Tue, 1 Oct 2024 01:56:49 -0300 Subject: [PATCH 02/20] chore(deps): Add launch_at_startup dependency --- pubspec.lock | 8 ++++++++ pubspec.yaml | 1 + 2 files changed, 9 insertions(+) diff --git a/pubspec.lock b/pubspec.lock index c4f31236..0ea938b7 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -493,6 +493,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.9.0" + launch_at_startup: + dependency: "direct main" + description: + name: launch_at_startup + sha256: "1f8a75520913d1038630049e6c44a2575a23ffd28cc8b14fdf37401d1d21de84" + url: "https://pub.dev" + source: hosted + version: "0.3.1" leak_tracker: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 016178cf..f7c4c4ad 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -57,6 +57,7 @@ dependencies: # Desktop window_manager: ^0.4.2 titlebar_buttons: ^1.0.0 + launch_at_startup: ^0.3.1 unity_multi_window: path: packages/unity_multi_window/ From 62741659a28f40514a1b17cb353eb9f442eb9997 Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Tue, 1 Oct 2024 01:56:59 -0300 Subject: [PATCH 03/20] feat: Setup Launch at Startup --- lib/main.dart | 2 ++ lib/utils/window.dart | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/lib/main.dart b/lib/main.dart index 80b9d323..d8e6f96e 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -164,6 +164,8 @@ Future main(List args) async { runApp(const UnityApp()); + await setupLaunchAtStartup(); + // Request notifications permission for iOS, Android 13+ and Windows. // // permission_handler only supports these platforms diff --git a/lib/utils/window.dart b/lib/utils/window.dart index 818350f9..4f7e5c7e 100644 --- a/lib/utils/window.dart +++ b/lib/utils/window.dart @@ -27,6 +27,8 @@ import 'package:bluecherry_client/providers/update_provider.dart'; import 'package:bluecherry_client/utils/methods.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:launch_at_startup/launch_at_startup.dart'; +import 'package:package_info_plus/package_info_plus.dart'; import 'package:unity_multi_window/unity_multi_window.dart'; import 'package:window_manager/window_manager.dart'; @@ -150,3 +152,18 @@ void launchFileExplorer(String path) { ); } } + +bool get canLaunchAtStartup => isDesktopPlatform; + +Future setupLaunchAtStartup() async { + final packageInfo = await PackageInfo.fromPlatform(); + + launchAtStartup.setup( + appName: packageInfo.appName, + appPath: Platform.resolvedExecutable, + // Set packageName parameter to support MSIX. + // This is required to check if the app is running in MSIX container. + // We do not support MSIX for now. + // packageName: 'dev.leanflutter.examples.launchatstartupexample', + ); +} From cd19d0f63b5bc87ecd77052c883ec7417feeec5d Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Thu, 10 Oct 2024 15:30:32 -0300 Subject: [PATCH 04/20] feat: Toggle launch at startup --- lib/providers/settings_provider.dart | 21 +++++--- lib/screens/settings/application.dart | 74 +++++++++++++-------------- 2 files changed, 52 insertions(+), 43 deletions(-) diff --git a/lib/providers/settings_provider.dart b/lib/providers/settings_provider.dart index 5a884e1f..6e24f004 100644 --- a/lib/providers/settings_provider.dart +++ b/lib/providers/settings_provider.dart @@ -33,6 +33,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:intl/intl.dart'; +import 'package:launch_at_startup/launch_at_startup.dart'; import 'package:unity_video_player/unity_video_player.dart'; import 'package:unity_video_player_main/unity_video_player_main.dart'; @@ -97,16 +98,16 @@ class _SettingsOption { late final String Function(dynamic value) saveAs; late final T Function(String value) loadFrom; - final ValueChanged? onChanged; + final Future Function(T)? onChanged; final T Function(dynamic value)? valueOverrider; late T _value; T get value => valueOverrider?.call(_value) ?? _value; set value(T newValue) { - SettingsProvider.instance.updateProperty(() { + SettingsProvider.instance.updateProperty(() async { _value = newValue; - onChanged?.call(value); + await onChanged?.call(value); }); } @@ -453,6 +454,14 @@ class SettingsProvider extends UnityProvider { final kLaunchAppOnStartup = _SettingsOption( def: false, key: 'window.launch_app_on_startup', + getDefault: launchAtStartup.isEnabled, + onChanged: (value) async { + if (value) { + await launchAtStartup.enable(); + } else { + await launchAtStartup.disable(); + } + }, ); final kMinimizeToTray = _SettingsOption( def: false, @@ -528,7 +537,7 @@ class SettingsProvider extends UnityProvider { final kSoftwareZooming = _SettingsOption( def: isHardwareZoomSupported ? true : false, key: 'other.software_zoom', - onChanged: (value) { + onChanged: (value) async { for (final player in UnityPlayers.players.values) { player ..resetCrop() @@ -659,8 +668,8 @@ class SettingsProvider extends UnityProvider { super.save(notifyListeners: notifyListeners); } - void updateProperty(VoidCallback update) { - update(); + Future updateProperty(Future Function() update) async { + await update(); save(); } diff --git a/lib/screens/settings/application.dart b/lib/screens/settings/application.dart index 163be6b1..8404f33e 100644 --- a/lib/screens/settings/application.dart +++ b/lib/screens/settings/application.dart @@ -93,45 +93,45 @@ class ApplicationSettings extends StatelessWidget { subtitle: Text(loc.convertToLocalTimeDescription), isThreeLine: true, ), - if (settings.kShowDebugInfo.value) ...[ - const SubHeader('Window'), - CheckboxListTile.adaptive( - value: settings.kLaunchAppOnStartup.value, - onChanged: (v) { - if (v != null) { - settings.kLaunchAppOnStartup.value = v; - } - }, - contentPadding: DesktopSettings.horizontalPadding, - secondary: CircleAvatar( - backgroundColor: Colors.transparent, - foregroundColor: theme.iconTheme.color, - child: const Icon(Icons.launch), - ), - title: const Text('Launch app on startup'), - subtitle: const Text( - 'Whether to launchthe app when the system starts', - ), + const SubHeader('Window'), + CheckboxListTile.adaptive( + value: settings.kLaunchAppOnStartup.value, + onChanged: (v) { + if (v != null) { + settings.kLaunchAppOnStartup.value = v; + } + }, + contentPadding: DesktopSettings.horizontalPadding, + secondary: CircleAvatar( + backgroundColor: Colors.transparent, + foregroundColor: theme.iconTheme.color, + child: const Icon(Icons.launch), ), - CheckboxListTile.adaptive( - value: settings.kMinimizeToTray.value, - onChanged: (v) { - if (v != null) { - settings.kMinimizeToTray.value = v; - } - }, - contentPadding: DesktopSettings.horizontalPadding, - secondary: CircleAvatar( - backgroundColor: Colors.transparent, - foregroundColor: theme.iconTheme.color, - child: const Icon(Icons.sensor_door), - ), - title: const Text('Minimize to tray'), - subtitle: const Text( - 'Whether to minimize app to the system tray when the window is closed. ' - 'This will keep the app running in the background.', - ), + title: const Text('Launch app on startup'), + subtitle: const Text( + 'Whether to launchthe app when the system starts', + ), + ), + CheckboxListTile.adaptive( + value: settings.kMinimizeToTray.value, + onChanged: (v) { + if (v != null) { + settings.kMinimizeToTray.value = v; + } + }, + contentPadding: DesktopSettings.horizontalPadding, + secondary: CircleAvatar( + backgroundColor: Colors.transparent, + foregroundColor: theme.iconTheme.color, + child: const Icon(Icons.sensor_door), ), + title: const Text('Minimize to tray'), + subtitle: const Text( + 'Whether to minimize app to the system tray when the window is closed. ' + 'This will keep the app running in the background.', + ), + ), + if (settings.kShowDebugInfo.value) ...[ const SubHeader('Acessibility'), CheckboxListTile.adaptive( value: settings.kAnimationsEnabled.value, From 3f5e3fa36be4e007c3a25c34341e5ea06677f66d Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Thu, 10 Oct 2024 15:31:49 -0300 Subject: [PATCH 05/20] fix: Only show "Window" options on desktop --- lib/screens/settings/application.dart | 77 ++++++++++++++------------- 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/lib/screens/settings/application.dart b/lib/screens/settings/application.dart index 8404f33e..a5334635 100644 --- a/lib/screens/settings/application.dart +++ b/lib/screens/settings/application.dart @@ -21,6 +21,7 @@ import 'package:bluecherry_client/providers/settings_provider.dart'; import 'package:bluecherry_client/screens/settings/settings_desktop.dart'; import 'package:bluecherry_client/screens/settings/shared/options_chooser_tile.dart'; import 'package:bluecherry_client/utils/extensions.dart'; +import 'package:bluecherry_client/utils/methods.dart'; import 'package:bluecherry_client/widgets/misc.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -93,45 +94,47 @@ class ApplicationSettings extends StatelessWidget { subtitle: Text(loc.convertToLocalTimeDescription), isThreeLine: true, ), - const SubHeader('Window'), - CheckboxListTile.adaptive( - value: settings.kLaunchAppOnStartup.value, - onChanged: (v) { - if (v != null) { - settings.kLaunchAppOnStartup.value = v; - } - }, - contentPadding: DesktopSettings.horizontalPadding, - secondary: CircleAvatar( - backgroundColor: Colors.transparent, - foregroundColor: theme.iconTheme.color, - child: const Icon(Icons.launch), - ), - title: const Text('Launch app on startup'), - subtitle: const Text( - 'Whether to launchthe app when the system starts', - ), - ), - CheckboxListTile.adaptive( - value: settings.kMinimizeToTray.value, - onChanged: (v) { - if (v != null) { - settings.kMinimizeToTray.value = v; - } - }, - contentPadding: DesktopSettings.horizontalPadding, - secondary: CircleAvatar( - backgroundColor: Colors.transparent, - foregroundColor: theme.iconTheme.color, - child: const Icon(Icons.sensor_door), - ), - title: const Text('Minimize to tray'), - subtitle: const Text( - 'Whether to minimize app to the system tray when the window is closed. ' - 'This will keep the app running in the background.', + if (isDesktopPlatform) ...[ + const SubHeader('Window'), + CheckboxListTile.adaptive( + value: settings.kLaunchAppOnStartup.value, + onChanged: (v) { + if (v != null) { + settings.kLaunchAppOnStartup.value = v; + } + }, + contentPadding: DesktopSettings.horizontalPadding, + secondary: CircleAvatar( + backgroundColor: Colors.transparent, + foregroundColor: theme.iconTheme.color, + child: const Icon(Icons.launch), + ), + title: const Text('Launch app on startup'), + subtitle: const Text( + 'Whether to launchthe app when the system starts', + ), ), - ), + ], if (settings.kShowDebugInfo.value) ...[ + CheckboxListTile.adaptive( + value: settings.kMinimizeToTray.value, + onChanged: (v) { + if (v != null) { + settings.kMinimizeToTray.value = v; + } + }, + contentPadding: DesktopSettings.horizontalPadding, + secondary: CircleAvatar( + backgroundColor: Colors.transparent, + foregroundColor: theme.iconTheme.color, + child: const Icon(Icons.sensor_door), + ), + title: const Text('Minimize to tray'), + subtitle: const Text( + 'Whether to minimize app to the system tray when the window is closed. ' + 'This will keep the app running in the background.', + ), + ), const SubHeader('Acessibility'), CheckboxListTile.adaptive( value: settings.kAnimationsEnabled.value, From ae7535c060a10a36add5a912accdf2623b432910 Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Thu, 10 Oct 2024 15:40:27 -0300 Subject: [PATCH 06/20] feat: Full screen --- lib/providers/settings_provider.dart | 23 ++++++++++++++++++++++- lib/screens/settings/application.dart | 20 +++++++++++++++++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/lib/providers/settings_provider.dart b/lib/providers/settings_provider.dart index 6e24f004..9d7f641b 100644 --- a/lib/providers/settings_provider.dart +++ b/lib/providers/settings_provider.dart @@ -36,6 +36,7 @@ import 'package:intl/intl.dart'; import 'package:launch_at_startup/launch_at_startup.dart'; import 'package:unity_video_player/unity_video_player.dart'; import 'package:unity_video_player_main/unity_video_player_main.dart'; +import 'package:window_manager/window_manager.dart'; enum NetworkUsage { auto, @@ -454,8 +455,11 @@ class SettingsProvider extends UnityProvider { final kLaunchAppOnStartup = _SettingsOption( def: false, key: 'window.launch_app_on_startup', - getDefault: launchAtStartup.isEnabled, + getDefault: kIsWeb ? null : launchAtStartup.isEnabled, onChanged: (value) async { + if (kIsWeb) { + return; + } if (value) { await launchAtStartup.enable(); } else { @@ -463,6 +467,22 @@ class SettingsProvider extends UnityProvider { } }, ); + final kFullscreen = _SettingsOption( + def: false, + key: 'window.fullscreen', + getDefault: () async { + if (kIsWeb) { + return false; + } + return windowManager.isFullScreen(); + }, + onChanged: (value) async { + if (kIsWeb) { + return; + } + await windowManager.setFullScreen(value); + }, + ); final kMinimizeToTray = _SettingsOption( def: false, key: 'window.minimize_to_tray', @@ -601,6 +621,7 @@ class SettingsProvider extends UnityProvider { kTimeFormat, kConvertTimeToLocalTimezone, kLaunchAppOnStartup, + kFullscreen, kMinimizeToTray, kAnimationsEnabled, kHighContrast, diff --git a/lib/screens/settings/application.dart b/lib/screens/settings/application.dart index a5334635..e105b37f 100644 --- a/lib/screens/settings/application.dart +++ b/lib/screens/settings/application.dart @@ -111,7 +111,25 @@ class ApplicationSettings extends StatelessWidget { ), title: const Text('Launch app on startup'), subtitle: const Text( - 'Whether to launchthe app when the system starts', + 'Whether to launch the app when the system starts', + ), + ), + CheckboxListTile.adaptive( + value: settings.kFullscreen.value, + onChanged: (v) { + if (v != null) settings.kFullscreen.value = v; + }, + contentPadding: DesktopSettings.horizontalPadding, + secondary: CircleAvatar( + backgroundColor: Colors.transparent, + foregroundColor: theme.iconTheme.color, + child: const Icon(Icons.fullscreen), + ), + title: const Text('Fullscreen Mode'), + subtitle: const Text( + 'Whether the app is in fullscreen mode or not. This will hide the ' + 'title bar and window controls. To show the top bar, hover over the ' + 'top of the window.', ), ), ], From aa9f54bbe5f89923a6354738483505800a45f9d2 Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Thu, 10 Oct 2024 15:59:51 -0300 Subject: [PATCH 07/20] feat: Top Bar as overlay in Full Screen mode --- lib/widgets/desktop_buttons.dart | 107 +++++++++++++++++++++++++++---- 1 file changed, 95 insertions(+), 12 deletions(-) diff --git a/lib/widgets/desktop_buttons.dart b/lib/widgets/desktop_buttons.dart index d76f47e5..097da1c5 100644 --- a/lib/widgets/desktop_buttons.dart +++ b/lib/widgets/desktop_buttons.dart @@ -24,6 +24,7 @@ import 'package:bluecherry_client/main.dart'; import 'package:bluecherry_client/models/device.dart'; import 'package:bluecherry_client/models/event.dart'; import 'package:bluecherry_client/providers/home_provider.dart'; +import 'package:bluecherry_client/providers/settings_provider.dart'; import 'package:bluecherry_client/providers/update_provider.dart'; import 'package:bluecherry_client/screens/events_browser/events_screen.dart'; import 'package:bluecherry_client/screens/events_timeline/events_playback.dart'; @@ -80,7 +81,7 @@ class NObserver extends NavigatorObserver { } } -class WindowButtons extends StatelessWidget { +class WindowButtons extends StatefulWidget { const WindowButtons({ super.key, this.title, @@ -108,6 +109,23 @@ class WindowButtons extends StatelessWidget { /// The widget displayed in the remaining space. final Widget? flexible; + @override + State createState() => _WindowButtonsState(); +} + +class _WindowButtonsState extends State + with SingleTickerProviderStateMixin { + late final _animationController = AnimationController( + vsync: this, + duration: const Duration(milliseconds: 350), + ); + + @override + void dispose() { + _animationController.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { if (!isDesktop || isMobile) return const SizedBox.shrink(); @@ -115,6 +133,7 @@ class WindowButtons extends StatelessWidget { final theme = Theme.of(context); final loc = AppLocalizations.of(context); + final settings = context.watch(); final home = context.watch(); final tab = home.tab; @@ -127,18 +146,18 @@ class WindowButtons extends StatelessWidget { final isLinuxPlatform = !kIsWeb && defaultTargetPlatform == TargetPlatform.linux; final centerTitle = - (AppBarTheme.of(context).centerTitle ?? false) && !showNavigator; + (AppBarTheme.of(context).centerTitle ?? false) && !widget.showNavigator; - return StreamBuilder( + final bar = StreamBuilder( stream: navigationStream.stream, builder: (context, arguments) { final canPop = (navigatorKey.currentState?.canPop() ?? false) && navigatorObserver.poppableRoute; - final showNavigator = !canPop && this.showNavigator; + final showNavigator = !canPop && this.widget.showNavigator; final titleWidget = Text( () { - if (title != null) return title!; + if (widget.title != null) return widget.title!; if (arguments.data != null) { if (arguments.data is Event) { @@ -154,7 +173,7 @@ class WindowButtons extends StatelessWidget { // If it is in another screen, show the title or fallback to "Bluecherry" if (tab.index >= UnityTab.values.length) { - return title ?? 'Bluecherry'; + return widget.title ?? 'Bluecherry'; } if (!(isMacOSPlatform || kIsWeb)) { @@ -190,7 +209,7 @@ class WindowButtons extends StatelessWidget { padding: const EdgeInsetsDirectional.only(start: 8.0), child: SquaredIconButton( onPressed: () async { - await onBack?.call(); + await widget.onBack?.call(); await navigatorKey.currentState?.maybePop(); }, tooltip: @@ -244,11 +263,14 @@ class WindowButtons extends StatelessWidget { icon: const Icon(Icons.refresh, size: 20.0), tooltip: loc.refresh, ), - if (flexible != null) flexible!, - - // Do not render the Window Buttons on web nor macOS. macOS - // render the buttons natively. - if (!kIsWeb && !isMacOSPlatform && !UpdateManager.isEmbedded) + if (widget.flexible != null) widget.flexible!, + + // Do not render the Window Buttons on web nor macOS nor when + // in fullscreen. macOS render the buttons natively. + if (!kIsWeb && + !isMacOSPlatform && + !UpdateManager.isEmbedded && + !settings.kFullscreen.value) SizedBox( width: 138, child: Builder(builder: (context) { @@ -323,6 +345,67 @@ class WindowButtons extends StatelessWidget { ); }, ); + + if (settings.kFullscreen.value) { + return MouseRegion( + onEnter: (_) { + showOverlayEntry(context, bar); + }, + child: const SizedBox( + height: 4, + width: double.infinity, + ), + ); + } + + return bar; + } + + OverlayEntry? _overlayEntry; + void showOverlayEntry(BuildContext context, Widget bar) { + _overlayEntry = OverlayEntry(builder: (context) { + return AnimatedBuilder( + animation: _animationController, + child: bar, + builder: (context, animation) { + return Positioned( + top: 0, + left: 0, + right: 0, + child: IgnorePointer( + ignoring: _animationController.status == AnimationStatus.forward, + child: MouseRegion( + onExit: (_) { + dismissOverlayEntry(); + }, + child: Material( + color: Colors.transparent, + elevation: 8, + child: SlideTransition( + position: Tween( + begin: const Offset(0, -1), + end: Offset.zero, + ).animate(CurvedAnimation( + parent: _animationController, + curve: Curves.easeInOut, + )), + child: animation, + ), + ), + ), + ), + ); + }, + ); + }); + Overlay.of(context).insert(_overlayEntry!); + _animationController.forward(); + } + + Future dismissOverlayEntry() async { + await _animationController.reverse(); + _overlayEntry?.remove(); + _overlayEntry = null; } } From b4010f25685044537683f555fbf076cb3d4f8444 Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Thu, 10 Oct 2024 21:20:55 -0300 Subject: [PATCH 08/20] feat: Implement immersive mode --- lib/providers/settings_provider.dart | 14 ++++++++------ lib/screens/settings/application.dart | 22 +++++++++++++++++++--- lib/widgets/desktop_buttons.dart | 4 ++-- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/lib/providers/settings_provider.dart b/lib/providers/settings_provider.dart index 9d7f641b..d6fa7781 100644 --- a/lib/providers/settings_provider.dart +++ b/lib/providers/settings_provider.dart @@ -26,6 +26,7 @@ import 'package:bluecherry_client/providers/update_provider.dart'; import 'package:bluecherry_client/screens/events_timeline/desktop/timeline.dart'; import 'package:bluecherry_client/screens/settings/shared/options_chooser_tile.dart'; import 'package:bluecherry_client/utils/logging.dart'; +import 'package:bluecherry_client/utils/methods.dart'; import 'package:bluecherry_client/utils/storage.dart'; import 'package:bluecherry_client/utils/video_player.dart'; import 'package:bluecherry_client/widgets/hover_button.dart'; @@ -471,18 +472,18 @@ class SettingsProvider extends UnityProvider { def: false, key: 'window.fullscreen', getDefault: () async { - if (kIsWeb) { - return false; - } + if (!isDesktopPlatform) return false; return windowManager.isFullScreen(); }, onChanged: (value) async { - if (kIsWeb) { - return; - } + if (isDesktopPlatform) return; await windowManager.setFullScreen(value); }, ); + final kImmersiveMode = _SettingsOption( + def: false, + key: 'window.immersive_mode', + ); final kMinimizeToTray = _SettingsOption( def: false, key: 'window.minimize_to_tray', @@ -622,6 +623,7 @@ class SettingsProvider extends UnityProvider { kConvertTimeToLocalTimezone, kLaunchAppOnStartup, kFullscreen, + kImmersiveMode, kMinimizeToTray, kAnimationsEnabled, kHighContrast, diff --git a/lib/screens/settings/application.dart b/lib/screens/settings/application.dart index e105b37f..466599da 100644 --- a/lib/screens/settings/application.dart +++ b/lib/screens/settings/application.dart @@ -126,10 +126,26 @@ class ApplicationSettings extends StatelessWidget { child: const Icon(Icons.fullscreen), ), title: const Text('Fullscreen Mode'), + subtitle: const Text('Whether the app is in fullscreen mode or not.'), + ), + CheckboxListTile.adaptive( + value: settings.kImmersiveMode.value, + onChanged: settings.kFullscreen.value + ? (v) { + if (v != null) settings.kImmersiveMode.value = v; + } + : null, + contentPadding: DesktopSettings.horizontalPadding, + secondary: CircleAvatar( + backgroundColor: Colors.transparent, + foregroundColor: theme.iconTheme.color, + child: const Icon(Icons.web_asset), + ), + title: const Text('Immersive Mode'), subtitle: const Text( - 'Whether the app is in fullscreen mode or not. This will hide the ' - 'title bar and window controls. To show the top bar, hover over the ' - 'top of the window.', + 'This will hide the title bar and window controls. ' + 'To show the top bar, hover over the top of the window. ' + 'This only works in fullscreen mode.', ), ), ], diff --git a/lib/widgets/desktop_buttons.dart b/lib/widgets/desktop_buttons.dart index 097da1c5..4c06a273 100644 --- a/lib/widgets/desktop_buttons.dart +++ b/lib/widgets/desktop_buttons.dart @@ -153,7 +153,7 @@ class _WindowButtonsState extends State builder: (context, arguments) { final canPop = (navigatorKey.currentState?.canPop() ?? false) && navigatorObserver.poppableRoute; - final showNavigator = !canPop && this.widget.showNavigator; + final showNavigator = !canPop && widget.showNavigator; final titleWidget = Text( () { @@ -346,7 +346,7 @@ class _WindowButtonsState extends State }, ); - if (settings.kFullscreen.value) { + if (settings.kFullscreen.value && settings.kImmersiveMode.value) { return MouseRegion( onEnter: (_) { showOverlayEntry(context, bar); From 4a114cb7336121e4104af93d4c8ce5bfe850f9d6 Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Thu, 10 Oct 2024 21:23:36 -0300 Subject: [PATCH 09/20] fix: Setting full screen mode --- lib/providers/settings_provider.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/providers/settings_provider.dart b/lib/providers/settings_provider.dart index d6fa7781..5c0a7aa6 100644 --- a/lib/providers/settings_provider.dart +++ b/lib/providers/settings_provider.dart @@ -476,7 +476,7 @@ class SettingsProvider extends UnityProvider { return windowManager.isFullScreen(); }, onChanged: (value) async { - if (isDesktopPlatform) return; + if (!isDesktopPlatform) return; await windowManager.setFullScreen(value); }, ); From 82aab2afa096ba08ed7ac4290c1d52301e5a955d Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Thu, 10 Oct 2024 21:33:09 -0300 Subject: [PATCH 10/20] feat: Enable immersive mode on mobile platforms --- lib/providers/settings_provider.dart | 16 ++++++++ lib/screens/settings/application.dart | 57 +++++++++++++++++---------- 2 files changed, 53 insertions(+), 20 deletions(-) diff --git a/lib/providers/settings_provider.dart b/lib/providers/settings_provider.dart index 5c0a7aa6..1d3c4dde 100644 --- a/lib/providers/settings_provider.dart +++ b/lib/providers/settings_provider.dart @@ -32,6 +32,7 @@ import 'package:bluecherry_client/utils/video_player.dart'; import 'package:bluecherry_client/widgets/hover_button.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:intl/intl.dart'; import 'package:launch_at_startup/launch_at_startup.dart'; @@ -483,6 +484,21 @@ class SettingsProvider extends UnityProvider { final kImmersiveMode = _SettingsOption( def: false, key: 'window.immersive_mode', + onChanged: (value) async { + if (isMobilePlatform) { + if (value) { + await SystemChrome.setEnabledSystemUIMode( + SystemUiMode.immersive, + overlays: [], + ); + } else { + await SystemChrome.setEnabledSystemUIMode( + SystemUiMode.manual, + overlays: SystemUiOverlay.values, + ); + } + } + }, ); final kMinimizeToTray = _SettingsOption( def: false, diff --git a/lib/screens/settings/application.dart b/lib/screens/settings/application.dart index 466599da..6fda34b3 100644 --- a/lib/screens/settings/application.dart +++ b/lib/screens/settings/application.dart @@ -70,6 +70,7 @@ class ApplicationSettings extends StatelessWidget { settings.kThemeMode.value = v; }, ), + if (isMobilePlatform) _buildImmersiveModeTile(), const LanguageSection(), SubHeader( loc.dateAndTime, @@ -128,26 +129,7 @@ class ApplicationSettings extends StatelessWidget { title: const Text('Fullscreen Mode'), subtitle: const Text('Whether the app is in fullscreen mode or not.'), ), - CheckboxListTile.adaptive( - value: settings.kImmersiveMode.value, - onChanged: settings.kFullscreen.value - ? (v) { - if (v != null) settings.kImmersiveMode.value = v; - } - : null, - contentPadding: DesktopSettings.horizontalPadding, - secondary: CircleAvatar( - backgroundColor: Colors.transparent, - foregroundColor: theme.iconTheme.color, - child: const Icon(Icons.web_asset), - ), - title: const Text('Immersive Mode'), - subtitle: const Text( - 'This will hide the title bar and window controls. ' - 'To show the top bar, hover over the top of the window. ' - 'This only works in fullscreen mode.', - ), - ), + _buildImmersiveModeTile(), ], if (settings.kShowDebugInfo.value) ...[ CheckboxListTile.adaptive( @@ -228,6 +210,41 @@ class ApplicationSettings extends StatelessWidget { ], ]); } + + /// Creates the Immersive Mode tile. + /// + /// On Desktop, this is used alonside the Fullscreen mode tile. When in + /// fullscreen, the immersive mode hides the top bar and only shows it when + /// the user hovers over the top of the window. + /// + /// On Mobile, this makes the app full-screen and hides the system UI. + Widget _buildImmersiveModeTile() { + return Builder(builder: (context) { + final theme = Theme.of(context); + final settings = context.watch(); + + return CheckboxListTile.adaptive( + value: settings.kImmersiveMode.value, + onChanged: settings.kFullscreen.value || isMobilePlatform + ? (v) { + if (v != null) settings.kImmersiveMode.value = v; + } + : null, + contentPadding: DesktopSettings.horizontalPadding, + secondary: CircleAvatar( + backgroundColor: Colors.transparent, + foregroundColor: theme.iconTheme.color, + child: const Icon(Icons.web_asset), + ), + title: const Text('Immersive Mode'), + subtitle: const Text( + 'This will hide the title bar and window controls. ' + 'To show the top bar, hover over the top of the window. ' + 'This only works in fullscreen mode.', + ), + ); + }); + } } class LanguageSection extends StatelessWidget { From fd8f7d840439d05ece9ae3329ae3b7a183024a99 Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Thu, 10 Oct 2024 21:37:03 -0300 Subject: [PATCH 11/20] chore(dependencies): Add tray_manager plugin --- lib/screens/settings/application.dart | 4 ++-- linux/flutter/generated_plugin_registrant.cc | 4 ++++ linux/flutter/generated_plugins.cmake | 1 + macos/Flutter/GeneratedPluginRegistrant.swift | 2 ++ pubspec.lock | 24 +++++++++++++++++++ pubspec.yaml | 1 + .../flutter/generated_plugin_registrant.cc | 3 +++ windows/flutter/generated_plugins.cmake | 1 + 8 files changed, 38 insertions(+), 2 deletions(-) diff --git a/lib/screens/settings/application.dart b/lib/screens/settings/application.dart index 6fda34b3..8165a667 100644 --- a/lib/screens/settings/application.dart +++ b/lib/screens/settings/application.dart @@ -147,8 +147,8 @@ class ApplicationSettings extends StatelessWidget { ), title: const Text('Minimize to tray'), subtitle: const Text( - 'Whether to minimize app to the system tray when the window is closed. ' - 'This will keep the app running in the background.', + 'Whether to minimize app to the system tray when the window is ' + 'closed. This will keep the app running in the background.', ), ), const SubHeader('Acessibility'), diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 25d8069e..8dee3bca 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -30,6 +31,9 @@ void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) screen_retriever_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverPlugin"); screen_retriever_plugin_register_with_registrar(screen_retriever_registrar); + g_autoptr(FlPluginRegistrar) tray_manager_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "TrayManagerPlugin"); + tray_manager_plugin_register_with_registrar(tray_manager_registrar); g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 1f4aaf58..260b5685 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -8,6 +8,7 @@ list(APPEND FLUTTER_PLUGIN_LIST gtk media_kit_video screen_retriever + tray_manager url_launcher_linux window_manager ) diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index b7e2e9f1..706d8e69 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -18,6 +18,7 @@ import package_info_plus import path_provider_foundation import screen_brightness_macos import screen_retriever +import tray_manager import url_launcher_macos import video_player_avfoundation import wakelock_plus @@ -37,6 +38,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) ScreenBrightnessMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenBrightnessMacosPlugin")) ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin")) + TrayManagerPlugin.register(with: registry.registrar(forPlugin: "TrayManagerPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin")) WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin")) diff --git a/pubspec.lock b/pubspec.lock index 0ea938b7..0aa68fb7 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -609,6 +609,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.5" + menu_base: + dependency: transitive + description: + name: menu_base + sha256: "820368014a171bd1241030278e6c2617354f492f5c703d7b7d4570a6b8b84405" + url: "https://pub.dev" + source: hosted + version: "0.1.1" meta: dependency: transitive description: @@ -897,6 +905,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.1.9" + shortid: + dependency: transitive + description: + name: shortid + sha256: d0b40e3dbb50497dad107e19c54ca7de0d1a274eb9b4404991e443dadb9ebedb + url: "https://pub.dev" + source: hosted + version: "0.1.2" sky_engine: dependency: transitive description: flutter @@ -982,6 +998,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.0" + tray_manager: + dependency: "direct main" + description: + name: tray_manager + sha256: bdc3ac6c36f3d12d871459e4a9822705ce5a1165a17fa837103bc842719bf3f7 + url: "https://pub.dev" + source: hosted + version: "0.2.4" typed_data: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index f7c4c4ad..9bc6072a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -60,6 +60,7 @@ dependencies: launch_at_startup: ^0.3.1 unity_multi_window: path: packages/unity_multi_window/ + tray_manager: ^0.2.4 dev_dependencies: flutter_test: diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index a532209f..30498194 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -37,6 +38,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("ScreenBrightnessWindowsPlugin")); ScreenRetrieverPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("ScreenRetrieverPlugin")); + TrayManagerPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("TrayManagerPlugin")); UrlLauncherWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("UrlLauncherWindows")); WindowManagerPluginRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 7f90e002..fef4cee2 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -12,6 +12,7 @@ list(APPEND FLUTTER_PLUGIN_LIST permission_handler_windows screen_brightness_windows screen_retriever + tray_manager url_launcher_windows window_manager ) From cd68ce9e01d6b95788c62bfbeb7cea0acea3aed6 Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Thu, 10 Oct 2024 21:46:26 -0300 Subject: [PATCH 12/20] feat: Show minimize to tray option --- lib/screens/settings/application.dart | 41 ++++++++++++++------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/lib/screens/settings/application.dart b/lib/screens/settings/application.dart index 8165a667..bee13717 100644 --- a/lib/screens/settings/application.dart +++ b/lib/screens/settings/application.dart @@ -17,6 +17,8 @@ * along with this program. If not, see . */ +import 'dart:io'; + import 'package:bluecherry_client/providers/settings_provider.dart'; import 'package:bluecherry_client/screens/settings/settings_desktop.dart'; import 'package:bluecherry_client/screens/settings/shared/options_chooser_tile.dart'; @@ -130,27 +132,28 @@ class ApplicationSettings extends StatelessWidget { subtitle: const Text('Whether the app is in fullscreen mode or not.'), ), _buildImmersiveModeTile(), + if (!Platform.isLinux) + CheckboxListTile.adaptive( + value: settings.kMinimizeToTray.value, + onChanged: (v) { + if (v != null) { + settings.kMinimizeToTray.value = v; + } + }, + contentPadding: DesktopSettings.horizontalPadding, + secondary: CircleAvatar( + backgroundColor: Colors.transparent, + foregroundColor: theme.iconTheme.color, + child: const Icon(Icons.sensor_door), + ), + title: const Text('Minimize to tray'), + subtitle: const Text( + 'Whether to minimize app to the system tray when the window is ' + 'closed. This will keep the app running in the background.', + ), + ), ], if (settings.kShowDebugInfo.value) ...[ - CheckboxListTile.adaptive( - value: settings.kMinimizeToTray.value, - onChanged: (v) { - if (v != null) { - settings.kMinimizeToTray.value = v; - } - }, - contentPadding: DesktopSettings.horizontalPadding, - secondary: CircleAvatar( - backgroundColor: Colors.transparent, - foregroundColor: theme.iconTheme.color, - child: const Icon(Icons.sensor_door), - ), - title: const Text('Minimize to tray'), - subtitle: const Text( - 'Whether to minimize app to the system tray when the window is ' - 'closed. This will keep the app running in the background.', - ), - ), const SubHeader('Acessibility'), CheckboxListTile.adaptive( value: settings.kAnimationsEnabled.value, From 7195b3cf8039451488b09f7a9a7cd53a2d31ce70 Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Thu, 10 Oct 2024 21:50:26 -0300 Subject: [PATCH 13/20] feat: Hide on close when minimize to tray is true --- lib/widgets/desktop_buttons.dart | 51 +++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/lib/widgets/desktop_buttons.dart b/lib/widgets/desktop_buttons.dart index 4c06a273..21068325 100644 --- a/lib/widgets/desktop_buttons.dart +++ b/lib/widgets/desktop_buttons.dart @@ -290,9 +290,7 @@ class _WindowButtonsState extends State } }, ), - DecoratedCloseButton( - onPressed: windowManager.close, - ), + DecoratedCloseButton(onPressed: close), ].map((button) { return Padding( padding: const EdgeInsetsDirectional.all(2.0), @@ -301,10 +299,40 @@ class _WindowButtonsState extends State }).toList(), ); } - return WindowCaption( - brightness: theme.brightness, - backgroundColor: Colors.transparent, - ); + return Row(children: [ + WindowCaptionButton.minimize( + brightness: theme.brightness, + onPressed: () async { + final isMinimized = + await windowManager.isMinimized(); + if (isMinimized) { + windowManager.restore(); + } else { + windowManager.minimize(); + } + }, + ), + FutureBuilder( + future: windowManager.isMaximized(), + builder: (BuildContext context, + AsyncSnapshot snapshot) { + if (snapshot.data == true) { + return WindowCaptionButton.unmaximize( + brightness: theme.brightness, + onPressed: windowManager.unmaximize, + ); + } + return WindowCaptionButton.maximize( + brightness: theme.brightness, + onPressed: windowManager.maximize, + ); + }, + ), + WindowCaptionButton.close( + brightness: theme.brightness, + onPressed: close, + ), + ]); }), ), ]), @@ -407,6 +435,15 @@ class _WindowButtonsState extends State _overlayEntry?.remove(); _overlayEntry = null; } + + Future close() { + final settings = context.read(); + if (settings.kMinimizeToTray.value) { + return windowManager.hide(); + } else { + return windowManager.close(); + } + } } /// A widget that shows whether something in the app is loading From aee6d82e498d3b4de90eadf82620f18123b9876b Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Thu, 10 Oct 2024 22:06:15 -0300 Subject: [PATCH 14/20] feat: Set up tray manager --- lib/main.dart | 5 ++- lib/providers/home_provider.dart | 8 ++-- lib/utils/window.dart | 65 ++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 5 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index d8e6f96e..d5ba92cb 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -80,6 +80,9 @@ Future main(List args) async { // can run the [SplashScreen] widget as the app. if (isDesktopPlatform) { await configureWindow(); + await setupLaunchAtStartup(); + if (!Platform.isLinux) setupSystemTray(); + runApp(const SplashScreen()); } @@ -164,8 +167,6 @@ Future main(List args) async { runApp(const UnityApp()); - await setupLaunchAtStartup(); - // Request notifications permission for iOS, Android 13+ and Windows. // // permission_handler only supports these platforms diff --git a/lib/providers/home_provider.dart b/lib/providers/home_provider.dart index 415fa043..894944b4 100644 --- a/lib/providers/home_provider.dart +++ b/lib/providers/home_provider.dart @@ -120,7 +120,7 @@ class HomeProvider extends ChangeNotifier { /// they come back. Map volumes = {}; - Future setTab(UnityTab tab, BuildContext context) async { + Future setTab(UnityTab tab, [BuildContext? context]) async { if (tab == this.tab) return; final currentTab = this.tab; @@ -159,8 +159,10 @@ class HomeProvider extends ChangeNotifier { volumes.clear(); } - refreshDeviceOrientation(context); - updateWakelock(context); + if (context != null) { + refreshDeviceOrientation(context); + updateWakelock(context); + } notifyListeners(); } diff --git a/lib/utils/window.dart b/lib/utils/window.dart index 4f7e5c7e..65a3607a 100644 --- a/lib/utils/window.dart +++ b/lib/utils/window.dart @@ -22,6 +22,7 @@ import 'dart:io'; import 'package:bluecherry_client/models/device.dart'; import 'package:bluecherry_client/models/layout.dart'; +import 'package:bluecherry_client/providers/home_provider.dart'; import 'package:bluecherry_client/providers/settings_provider.dart'; import 'package:bluecherry_client/providers/update_provider.dart'; import 'package:bluecherry_client/utils/methods.dart'; @@ -29,6 +30,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:launch_at_startup/launch_at_startup.dart'; import 'package:package_info_plus/package_info_plus.dart'; +import 'package:tray_manager/tray_manager.dart'; import 'package:unity_multi_window/unity_multi_window.dart'; import 'package:window_manager/window_manager.dart'; @@ -156,6 +158,7 @@ void launchFileExplorer(String path) { bool get canLaunchAtStartup => isDesktopPlatform; Future setupLaunchAtStartup() async { + assert(isDesktopPlatform); final packageInfo = await PackageInfo.fromPlatform(); launchAtStartup.setup( @@ -167,3 +170,65 @@ Future setupLaunchAtStartup() async { // packageName: 'dev.leanflutter.examples.launchatstartupexample', ); } + +Future setupSystemTray() async { + assert(isDesktopPlatform); + assert(!Platform.isLinux); + + await trayManager.setIcon( + Platform.isWindows ? 'assets/images/icon.ico' : 'assets/images/icon.png', + ); + final menu = Menu( + items: [ + MenuItem( + key: 'screens', + label: 'Layouts', + onClick: (item) { + windowManager.show(); + HomeProvider.instance.setTab(UnityTab.deviceGrid); + }, + ), + MenuItem( + key: 'timeline_of_events', + label: 'Timeline of Events', + onClick: (item) { + windowManager.show(); + HomeProvider.instance.setTab(UnityTab.eventsTimeline); + }, + ), + MenuItem( + key: 'events_browser', + label: 'Events Browser', + onClick: (item) { + windowManager.show(); + HomeProvider.instance.setTab(UnityTab.eventsHistory); + }, + ), + MenuItem( + key: 'downloads', + label: 'Downloads', + onClick: (item) { + windowManager.show(); + HomeProvider.instance.setTab(UnityTab.downloads); + }, + ), + MenuItem( + key: 'settings', + label: 'Settings', + onClick: (item) { + windowManager.show(); + HomeProvider.instance.setTab(UnityTab.settings); + }, + ), + MenuItem.separator(), + MenuItem( + key: 'quit', + label: 'Quit bluecherry', + onClick: (item) { + windowManager.close(); + }, + ), + ], + ); + await trayManager.setContextMenu(menu); +} From faed269c140e2925384142e9c182f3e0b2574fac Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Thu, 10 Oct 2024 22:25:09 -0300 Subject: [PATCH 15/20] feat: Improve tray features --- lib/utils/window.dart | 111 ++++++++++++++++++++++-------------------- 1 file changed, 59 insertions(+), 52 deletions(-) diff --git a/lib/utils/window.dart b/lib/utils/window.dart index 65a3607a..98609ed0 100644 --- a/lib/utils/window.dart +++ b/lib/utils/window.dart @@ -175,60 +175,67 @@ Future setupSystemTray() async { assert(isDesktopPlatform); assert(!Platform.isLinux); + await trayManager.destroy(); await trayManager.setIcon( Platform.isWindows ? 'assets/images/icon.ico' : 'assets/images/icon.png', ); - final menu = Menu( - items: [ - MenuItem( - key: 'screens', - label: 'Layouts', - onClick: (item) { - windowManager.show(); - HomeProvider.instance.setTab(UnityTab.deviceGrid); - }, - ), - MenuItem( - key: 'timeline_of_events', - label: 'Timeline of Events', - onClick: (item) { - windowManager.show(); - HomeProvider.instance.setTab(UnityTab.eventsTimeline); - }, - ), - MenuItem( - key: 'events_browser', - label: 'Events Browser', - onClick: (item) { - windowManager.show(); - HomeProvider.instance.setTab(UnityTab.eventsHistory); - }, - ), - MenuItem( - key: 'downloads', - label: 'Downloads', - onClick: (item) { - windowManager.show(); - HomeProvider.instance.setTab(UnityTab.downloads); - }, - ), - MenuItem( - key: 'settings', - label: 'Settings', - onClick: (item) { - windowManager.show(); - HomeProvider.instance.setTab(UnityTab.settings); - }, - ), - MenuItem.separator(), - MenuItem( - key: 'quit', - label: 'Quit bluecherry', - onClick: (item) { - windowManager.close(); - }, - ), - ], - ); + final menu = Menu(items: [ + MenuItem(key: 'screens', label: 'Layouts'), + MenuItem(key: 'timeline_of_events', label: 'Timeline of Events'), + MenuItem(key: 'events_browser', label: 'Events Browser'), + MenuItem(key: 'downloads', label: 'Downloads'), + MenuItem(key: 'settings', label: 'Settings'), + MenuItem.separator(), + MenuItem(key: 'quit', label: 'Quit bluecherry'), + ]); + await trayManager.setContextMenu(menu); + // await trayManager.setTitle('Bluecherry'); + // await trayManager.setToolTip('Bluecherry Client'); + + trayManager.addListener(UnityTrayListener()); +} + +class UnityTrayListener with TrayListener { + @override + void onTrayIconMouseDown() { + debugPrint('Tray icon mouse down'); + windowManager.show(); + } + + @override + void onTrayIconRightMouseDown() { + debugPrint('Tray icon right mouse down'); + trayManager.popUpContextMenu(); + } + + @override + void onTrayIconRightMouseUp() { + debugPrint('Tray icon right mouse up'); + } + + @override + void onTrayMenuItemClick(MenuItem menuItem) { + print(menuItem.key); + switch (menuItem.key) { + case 'screens': + HomeProvider.instance.setTab(UnityTab.deviceGrid); + break; + case 'timeline_of_events': + HomeProvider.instance.setTab(UnityTab.eventsTimeline); + break; + case 'events_browser': + HomeProvider.instance.setTab(UnityTab.eventsHistory); + break; + case 'downloads': + HomeProvider.instance.setTab(UnityTab.downloads); + break; + case 'settings': + HomeProvider.instance.setTab(UnityTab.settings); + break; + case 'quit': + windowManager.close(); + break; + } + } } From e64088b9a09cc1cc652350bd0c09ca183132dcc4 Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Thu, 10 Oct 2024 22:25:48 -0300 Subject: [PATCH 16/20] fix: Do not show context menu icons due to issues --- lib/utils/window.dart | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/lib/utils/window.dart b/lib/utils/window.dart index 98609ed0..ab30df9f 100644 --- a/lib/utils/window.dart +++ b/lib/utils/window.dart @@ -179,17 +179,17 @@ Future setupSystemTray() async { await trayManager.setIcon( Platform.isWindows ? 'assets/images/icon.ico' : 'assets/images/icon.png', ); - final menu = Menu(items: [ - MenuItem(key: 'screens', label: 'Layouts'), - MenuItem(key: 'timeline_of_events', label: 'Timeline of Events'), - MenuItem(key: 'events_browser', label: 'Events Browser'), - MenuItem(key: 'downloads', label: 'Downloads'), - MenuItem(key: 'settings', label: 'Settings'), - MenuItem.separator(), - MenuItem(key: 'quit', label: 'Quit bluecherry'), - ]); - - await trayManager.setContextMenu(menu); + // final menu = Menu(items: [ + // MenuItem(key: 'screens', label: 'Layouts'), + // MenuItem(key: 'timeline_of_events', label: 'Timeline of Events'), + // MenuItem(key: 'events_browser', label: 'Events Browser'), + // MenuItem(key: 'downloads', label: 'Downloads'), + // MenuItem(key: 'settings', label: 'Settings'), + // MenuItem.separator(), + // MenuItem(key: 'quit', label: 'Quit bluecherry'), + // ]); + + // await trayManager.setContextMenu(menu); // await trayManager.setTitle('Bluecherry'); // await trayManager.setToolTip('Bluecherry Client'); @@ -216,7 +216,6 @@ class UnityTrayListener with TrayListener { @override void onTrayMenuItemClick(MenuItem menuItem) { - print(menuItem.key); switch (menuItem.key) { case 'screens': HomeProvider.instance.setTab(UnityTab.deviceGrid); From 6714eeb52170e36ae85d17f45e5f3413632c3c66 Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Fri, 11 Oct 2024 08:27:50 -0300 Subject: [PATCH 17/20] fix: Do not pop context menu --- lib/utils/window.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/utils/window.dart b/lib/utils/window.dart index ab30df9f..aa15b5ba 100644 --- a/lib/utils/window.dart +++ b/lib/utils/window.dart @@ -206,7 +206,7 @@ class UnityTrayListener with TrayListener { @override void onTrayIconRightMouseDown() { debugPrint('Tray icon right mouse down'); - trayManager.popUpContextMenu(); + // trayManager.popUpContextMenu(); } @override From 06d670bed2685180f9331b6de66faa0373324859 Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Fri, 11 Oct 2024 08:33:19 -0300 Subject: [PATCH 18/20] feat: Add macos support --- macos/Runner/MainFlutterWindow.swift | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/macos/Runner/MainFlutterWindow.swift b/macos/Runner/MainFlutterWindow.swift index 3cc05eb2..b6e45f2f 100644 --- a/macos/Runner/MainFlutterWindow.swift +++ b/macos/Runner/MainFlutterWindow.swift @@ -1,5 +1,8 @@ +// This file was modified according to https://pub.dev/packages/launch_at_startup#macos-support + import Cocoa import FlutterMacOS +import LaunchAtLogin // launch_at_startup class MainFlutterWindow: NSWindow { override func awakeFromNib() { @@ -8,6 +11,26 @@ class MainFlutterWindow: NSWindow { self.contentViewController = flutterViewController self.setFrame(windowFrame, display: true) + // + // Add FlutterMethodChannel platform code + FlutterMethodChannel( + name: "launch_at_startup", binaryMessenger: flutterViewController.engine.binaryMessenger + ) + .setMethodCallHandler { (_ call: FlutterMethodCall, result: @escaping FlutterResult) in + switch call.method { + case "launchAtStartupIsEnabled": + result(LaunchAtLogin.isEnabled) + case "launchAtStartupSetEnabled": + if let arguments = call.arguments as? [String: Any] { + LaunchAtLogin.isEnabled = arguments["setEnabledValue"] as! Bool + } + result(nil) + default: + result(FlutterMethodNotImplemented) + } + } + // + RegisterGeneratedPlugins(registry: flutterViewController) super.awakeFromNib() From b8e1e49d5a62c39a17fd622596b952b685490c3e Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Fri, 11 Oct 2024 08:47:03 -0300 Subject: [PATCH 19/20] fix: Only show options if they are allowed in the current system --- lib/main.dart | 4 +-- lib/screens/settings/application.dart | 40 +++++++++++++-------------- lib/utils/window.dart | 11 ++++++-- 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index d44b2b7a..deb761fc 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -80,8 +80,8 @@ Future main(List args) async { // can run the [SplashScreen] widget as the app. if (isDesktopPlatform) { await configureWindow(); - await setupLaunchAtStartup(); - if (!Platform.isLinux) setupSystemTray(); + if (canLaunchAtStartup) setupLaunchAtStartup(); + if (canUseSystemTray) setupSystemTray(); runApp(const SplashScreen()); } diff --git a/lib/screens/settings/application.dart b/lib/screens/settings/application.dart index bee13717..7ce30dff 100644 --- a/lib/screens/settings/application.dart +++ b/lib/screens/settings/application.dart @@ -17,13 +17,12 @@ * along with this program. If not, see . */ -import 'dart:io'; - import 'package:bluecherry_client/providers/settings_provider.dart'; import 'package:bluecherry_client/screens/settings/settings_desktop.dart'; import 'package:bluecherry_client/screens/settings/shared/options_chooser_tile.dart'; import 'package:bluecherry_client/utils/extensions.dart'; import 'package:bluecherry_client/utils/methods.dart'; +import 'package:bluecherry_client/utils/window.dart'; import 'package:bluecherry_client/widgets/misc.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -99,24 +98,25 @@ class ApplicationSettings extends StatelessWidget { ), if (isDesktopPlatform) ...[ const SubHeader('Window'), - CheckboxListTile.adaptive( - value: settings.kLaunchAppOnStartup.value, - onChanged: (v) { - if (v != null) { - settings.kLaunchAppOnStartup.value = v; - } - }, - contentPadding: DesktopSettings.horizontalPadding, - secondary: CircleAvatar( - backgroundColor: Colors.transparent, - foregroundColor: theme.iconTheme.color, - child: const Icon(Icons.launch), - ), - title: const Text('Launch app on startup'), - subtitle: const Text( - 'Whether to launch the app when the system starts', + if (canLaunchAtStartup) + CheckboxListTile.adaptive( + value: settings.kLaunchAppOnStartup.value, + onChanged: (v) { + if (v != null) { + settings.kLaunchAppOnStartup.value = v; + } + }, + contentPadding: DesktopSettings.horizontalPadding, + secondary: CircleAvatar( + backgroundColor: Colors.transparent, + foregroundColor: theme.iconTheme.color, + child: const Icon(Icons.launch), + ), + title: const Text('Launch app on startup'), + subtitle: const Text( + 'Whether to launch the app when the system starts', + ), ), - ), CheckboxListTile.adaptive( value: settings.kFullscreen.value, onChanged: (v) { @@ -132,7 +132,7 @@ class ApplicationSettings extends StatelessWidget { subtitle: const Text('Whether the app is in fullscreen mode or not.'), ), _buildImmersiveModeTile(), - if (!Platform.isLinux) + if (canUseSystemTray) CheckboxListTile.adaptive( value: settings.kMinimizeToTray.value, onChanged: (v) { diff --git a/lib/utils/window.dart b/lib/utils/window.dart index aa15b5ba..53229956 100644 --- a/lib/utils/window.dart +++ b/lib/utils/window.dart @@ -155,7 +155,11 @@ void launchFileExplorer(String path) { } } -bool get canLaunchAtStartup => isDesktopPlatform; +/// It is only possible to launch at startup on Desktop Systems. +/// +/// MacOS is still lacking configuration at this time, so we are not supporting +/// it for now. +bool get canLaunchAtStartup => isDesktopPlatform && !Platform.isMacOS; Future setupLaunchAtStartup() async { assert(isDesktopPlatform); @@ -171,9 +175,10 @@ Future setupLaunchAtStartup() async { ); } +bool get canUseSystemTray => isDesktopPlatform && !Platform.isLinux; + Future setupSystemTray() async { - assert(isDesktopPlatform); - assert(!Platform.isLinux); + assert(canUseSystemTray); await trayManager.destroy(); await trayManager.setIcon( From 691dbfe86ca286fd098709b75a9bcf2d512bdc82 Mon Sep 17 00:00:00 2001 From: Bruno D'Luka Date: Fri, 11 Oct 2024 08:49:38 -0300 Subject: [PATCH 20/20] chore: Disable tray_manager temporarily --- lib/utils/window.dart | 102 +++++++++--------- linux/flutter/generated_plugin_registrant.cc | 4 - linux/flutter/generated_plugins.cmake | 1 - macos/Flutter/GeneratedPluginRegistrant.swift | 2 - pubspec.lock | 24 ----- pubspec.yaml | 2 +- .../flutter/generated_plugin_registrant.cc | 3 - windows/flutter/generated_plugins.cmake | 1 - 8 files changed, 53 insertions(+), 86 deletions(-) diff --git a/lib/utils/window.dart b/lib/utils/window.dart index 53229956..319449ba 100644 --- a/lib/utils/window.dart +++ b/lib/utils/window.dart @@ -22,7 +22,6 @@ import 'dart:io'; import 'package:bluecherry_client/models/device.dart'; import 'package:bluecherry_client/models/layout.dart'; -import 'package:bluecherry_client/providers/home_provider.dart'; import 'package:bluecherry_client/providers/settings_provider.dart'; import 'package:bluecherry_client/providers/update_provider.dart'; import 'package:bluecherry_client/utils/methods.dart'; @@ -30,7 +29,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:launch_at_startup/launch_at_startup.dart'; import 'package:package_info_plus/package_info_plus.dart'; -import 'package:tray_manager/tray_manager.dart'; +// import 'package:tray_manager/tray_manager.dart'; import 'package:unity_multi_window/unity_multi_window.dart'; import 'package:window_manager/window_manager.dart'; @@ -175,15 +174,18 @@ Future setupLaunchAtStartup() async { ); } -bool get canUseSystemTray => isDesktopPlatform && !Platform.isLinux; +// System tray is temporarily disabled due to issues with the `tray_manager` +// plugin. It will be re-enabled once the issues are resolved. +// bool get canUseSystemTray => isDesktopPlatform && !Platform.isLinux; +bool get canUseSystemTray => false; Future setupSystemTray() async { assert(canUseSystemTray); - await trayManager.destroy(); - await trayManager.setIcon( - Platform.isWindows ? 'assets/images/icon.ico' : 'assets/images/icon.png', - ); + // await trayManager.destroy(); + // await trayManager.setIcon( + // Platform.isWindows ? 'assets/images/icon.ico' : 'assets/images/icon.png', + // ); // final menu = Menu(items: [ // MenuItem(key: 'screens', label: 'Layouts'), // MenuItem(key: 'timeline_of_events', label: 'Timeline of Events'), @@ -198,48 +200,48 @@ Future setupSystemTray() async { // await trayManager.setTitle('Bluecherry'); // await trayManager.setToolTip('Bluecherry Client'); - trayManager.addListener(UnityTrayListener()); + // trayManager.addListener(UnityTrayListener()); } -class UnityTrayListener with TrayListener { - @override - void onTrayIconMouseDown() { - debugPrint('Tray icon mouse down'); - windowManager.show(); - } - - @override - void onTrayIconRightMouseDown() { - debugPrint('Tray icon right mouse down'); - // trayManager.popUpContextMenu(); - } - - @override - void onTrayIconRightMouseUp() { - debugPrint('Tray icon right mouse up'); - } - - @override - void onTrayMenuItemClick(MenuItem menuItem) { - switch (menuItem.key) { - case 'screens': - HomeProvider.instance.setTab(UnityTab.deviceGrid); - break; - case 'timeline_of_events': - HomeProvider.instance.setTab(UnityTab.eventsTimeline); - break; - case 'events_browser': - HomeProvider.instance.setTab(UnityTab.eventsHistory); - break; - case 'downloads': - HomeProvider.instance.setTab(UnityTab.downloads); - break; - case 'settings': - HomeProvider.instance.setTab(UnityTab.settings); - break; - case 'quit': - windowManager.close(); - break; - } - } -} +// class UnityTrayListener with TrayListener { +// @override +// void onTrayIconMouseDown() { +// debugPrint('Tray icon mouse down'); +// windowManager.show(); +// } + +// @override +// void onTrayIconRightMouseDown() { +// debugPrint('Tray icon right mouse down'); +// // trayManager.popUpContextMenu(); +// } + +// @override +// void onTrayIconRightMouseUp() { +// debugPrint('Tray icon right mouse up'); +// } + +// @override +// void onTrayMenuItemClick(MenuItem menuItem) { +// switch (menuItem.key) { +// case 'screens': +// HomeProvider.instance.setTab(UnityTab.deviceGrid); +// break; +// case 'timeline_of_events': +// HomeProvider.instance.setTab(UnityTab.eventsTimeline); +// break; +// case 'events_browser': +// HomeProvider.instance.setTab(UnityTab.eventsHistory); +// break; +// case 'downloads': +// HomeProvider.instance.setTab(UnityTab.downloads); +// break; +// case 'settings': +// HomeProvider.instance.setTab(UnityTab.settings); +// break; +// case 'quit': +// windowManager.close(); +// break; +// } +// } +// } diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 8dee3bca..25d8069e 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -11,7 +11,6 @@ #include #include #include -#include #include #include @@ -31,9 +30,6 @@ void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) screen_retriever_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverPlugin"); screen_retriever_plugin_register_with_registrar(screen_retriever_registrar); - g_autoptr(FlPluginRegistrar) tray_manager_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "TrayManagerPlugin"); - tray_manager_plugin_register_with_registrar(tray_manager_registrar); g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 260b5685..1f4aaf58 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -8,7 +8,6 @@ list(APPEND FLUTTER_PLUGIN_LIST gtk media_kit_video screen_retriever - tray_manager url_launcher_linux window_manager ) diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 706d8e69..b7e2e9f1 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -18,7 +18,6 @@ import package_info_plus import path_provider_foundation import screen_brightness_macos import screen_retriever -import tray_manager import url_launcher_macos import video_player_avfoundation import wakelock_plus @@ -38,7 +37,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) ScreenBrightnessMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenBrightnessMacosPlugin")) ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin")) - TrayManagerPlugin.register(with: registry.registrar(forPlugin: "TrayManagerPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin")) WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin")) diff --git a/pubspec.lock b/pubspec.lock index 0aa68fb7..0ea938b7 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -609,14 +609,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.5" - menu_base: - dependency: transitive - description: - name: menu_base - sha256: "820368014a171bd1241030278e6c2617354f492f5c703d7b7d4570a6b8b84405" - url: "https://pub.dev" - source: hosted - version: "0.1.1" meta: dependency: transitive description: @@ -905,14 +897,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.1.9" - shortid: - dependency: transitive - description: - name: shortid - sha256: d0b40e3dbb50497dad107e19c54ca7de0d1a274eb9b4404991e443dadb9ebedb - url: "https://pub.dev" - source: hosted - version: "0.1.2" sky_engine: dependency: transitive description: flutter @@ -998,14 +982,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.0" - tray_manager: - dependency: "direct main" - description: - name: tray_manager - sha256: bdc3ac6c36f3d12d871459e4a9822705ce5a1165a17fa837103bc842719bf3f7 - url: "https://pub.dev" - source: hosted - version: "0.2.4" typed_data: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 9bc6072a..5b4e3ec3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -58,9 +58,9 @@ dependencies: window_manager: ^0.4.2 titlebar_buttons: ^1.0.0 launch_at_startup: ^0.3.1 + # tray_manager: ^0.2.4 unity_multi_window: path: packages/unity_multi_window/ - tray_manager: ^0.2.4 dev_dependencies: flutter_test: diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 30498194..a532209f 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -38,8 +37,6 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("ScreenBrightnessWindowsPlugin")); ScreenRetrieverPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("ScreenRetrieverPlugin")); - TrayManagerPluginRegisterWithRegistrar( - registry->GetRegistrarForPlugin("TrayManagerPlugin")); UrlLauncherWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("UrlLauncherWindows")); WindowManagerPluginRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index fef4cee2..7f90e002 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -12,7 +12,6 @@ list(APPEND FLUTTER_PLUGIN_LIST permission_handler_windows screen_brightness_windows screen_retriever - tray_manager url_launcher_windows window_manager )