Workaround for #2818

Signed-off-by: Joel Jothiprakasam <hijoelj@gmail.com>
This commit is contained in:
Joel Jothiprakasam
2024-10-24 00:54:26 -05:00
parent ce1b428e7c
commit c3d9e46970
8 changed files with 114 additions and 57 deletions

View File

@ -8,7 +8,6 @@ import 'package:bitsdojo_window/bitsdojo_window.dart';
import 'package:bluebubbles/app/components/custom/custom_error_box.dart'; import 'package:bluebubbles/app/components/custom/custom_error_box.dart';
import 'package:bluebubbles/helpers/backend/startup_tasks.dart'; import 'package:bluebubbles/helpers/backend/startup_tasks.dart';
import 'package:bluebubbles/helpers/helpers.dart'; import 'package:bluebubbles/helpers/helpers.dart';
import 'package:bluebubbles/database/database.dart';
import 'package:bluebubbles/services/network/http_overrides.dart'; import 'package:bluebubbles/services/network/http_overrides.dart';
import 'package:bluebubbles/utils/logger/logger.dart'; import 'package:bluebubbles/utils/logger/logger.dart';
import 'package:bluebubbles/utils/window_effects.dart'; import 'package:bluebubbles/utils/window_effects.dart';
@ -40,6 +39,7 @@ import 'package:path/path.dart' as p;
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'package:screen_retriever/screen_retriever.dart'; import 'package:screen_retriever/screen_retriever.dart';
import 'package:secure_application/secure_application.dart'; import 'package:secure_application/secure_application.dart';
import 'package:system_tray/system_tray.dart' as st;
import 'package:timezone/data/latest.dart' as tz; import 'package:timezone/data/latest.dart' as tz;
import 'package:timezone/timezone.dart' as tz; import 'package:timezone/timezone.dart' as tz;
import 'package:tray_manager/tray_manager.dart'; import 'package:tray_manager/tray_manager.dart';
@ -49,6 +49,7 @@ import 'package:window_manager/window_manager.dart';
import 'package:windows_taskbar/windows_taskbar.dart'; import 'package:windows_taskbar/windows_taskbar.dart';
bool isAuthing = false; bool isAuthing = false;
final systemTray = st.SystemTray();
@pragma('vm:entry-point') @pragma('vm:entry-point')
//ignore: prefer_void_to_null //ignore: prefer_void_to_null
@ -247,37 +248,6 @@ class DesktopWindowListener extends WindowListener {
} }
} }
class DesktopTrayListener extends TrayListener {
DesktopTrayListener._();
static final DesktopTrayListener instance = DesktopTrayListener._();
@override
void onTrayIconMouseDown() async {
await windowManager.show();
}
@override
void onTrayIconRightMouseDown() async {
await trayManager.popUpContextMenu();
}
@override
void onTrayMenuItemClick(MenuItem menuItem) async {
switch (menuItem.key) {
case 'show_app':
await windowManager.show();
break;
case 'hide_app':
await windowManager.hide();
break;
case 'close_app':
await windowManager.close();
break;
}
}
}
class Main extends StatelessWidget { class Main extends StatelessWidget {
final ThemeData darkTheme; final ThemeData darkTheme;
final ThemeData lightTheme; final ThemeData lightTheme;
@ -445,7 +415,7 @@ class Home extends StatefulWidget {
State<Home> createState() => _HomeState(); State<Home> createState() => _HomeState();
} }
class _HomeState extends OptimizedState<Home> with WidgetsBindingObserver { class _HomeState extends OptimizedState<Home> with WidgetsBindingObserver, TrayListener {
final ReceivePort port = ReceivePort(); final ReceivePort port = ReceivePort();
bool serverCompatible = true; bool serverCompatible = true;
bool fullyLoaded = false; bool fullyLoaded = false;
@ -527,7 +497,17 @@ class _HomeState extends OptimizedState<Home> with WidgetsBindingObserver {
/* ----- SYSTEM TRAY INITIALIZATION ----- */ /* ----- SYSTEM TRAY INITIALIZATION ----- */
await initSystemTray(); await initSystemTray();
trayManager.addListener(DesktopTrayListener.instance); if (Platform.isWindows) {
systemTray.registerSystemTrayEventHandler((eventName) {
if (eventName == st.kSystemTrayEventClick) {
onTrayIconMouseDown();
} else if (eventName == st.kSystemTrayEventRightClick) {
onTrayIconRightMouseDown();
}
});
} else {
trayManager.addListener(this);
}
/* ----- NOTIFICATIONS INITIALIZATION ----- */ /* ----- NOTIFICATIONS INITIALIZATION ----- */
await localNotifier.setup(appName: "BlueBubbles"); await localNotifier.setup(appName: "BlueBubbles");
@ -543,12 +523,43 @@ class _HomeState extends OptimizedState<Home> with WidgetsBindingObserver {
}); });
} }
@override
void onTrayIconMouseDown() async {
await windowManager.show();
}
@override
void onTrayIconRightMouseDown() async {
if (Platform.isWindows) {
await systemTray.popUpContextMenu();
} else {
await trayManager.popUpContextMenu();
}
}
@override
void onTrayMenuItemClick(MenuItem menuItem) async {
switch (menuItem.key) {
case 'show_app':
await windowManager.show();
break;
case 'hide_app':
await windowManager.hide();
break;
case 'close_app':
await windowManager.close();
break;
}
}
@override @override
void dispose() { void dispose() {
// Clean up observer when app is fully closed // Clean up observer when app is fully closed
WidgetsBinding.instance.removeObserver(this); WidgetsBinding.instance.removeObserver(this);
windowManager.removeListener(DesktopWindowListener.instance); windowManager.removeListener(DesktopWindowListener.instance);
trayManager.removeListener(DesktopTrayListener.instance); if (Platform.isLinux) {
trayManager.removeListener(this);
}
super.dispose(); super.dispose();
} }
@ -629,32 +640,58 @@ class _HomeState extends OptimizedState<Home> with WidgetsBindingObserver {
} }
Future<void> initSystemTray() async { Future<void> initSystemTray() async {
String path;
if (Platform.isWindows) { if (Platform.isWindows) {
path = 'assets/icon/icon.ico'; await systemTray.initSystemTray(
} else if (isFlatpak) { iconPath: 'assets/icon/icon.ico',
path = 'app.bluebubbles.BlueBubbles'; toolTip: "BlueBubbles",
} else if (isSnap) { );
path = p.joinAll([p.dirname(Platform.resolvedExecutable), 'data/flutter_assets/assets/icon', 'icon.png']);
} else { } else {
path = 'assets/icon/icon.png'; String path;
if (isFlatpak) {
path = 'app.bluebubbles.BlueBubbles';
} else if (isSnap) {
path = p.joinAll([p.dirname(Platform.resolvedExecutable), 'data/flutter_assets/assets/icon', 'icon.png']);
} else {
path = 'assets/icon/icon.png';
}
await trayManager.setIcon(path);
} }
// We first init the systray menu and then add the menu entries
await trayManager.setIcon(path);
if (Platform.isWindows) {
await trayManager.setToolTip("BlueBubbles");
}
await setSystemTrayContextMenu(windowHidden: !appWindow.isVisible); await setSystemTrayContextMenu(windowHidden: !appWindow.isVisible);
} }
Future<void> setSystemTrayContextMenu({bool windowHidden = false}) async { Future<void> setSystemTrayContextMenu({bool windowHidden = false}) async {
await trayManager.setContextMenu(Menu( if (Platform.isWindows) {
items: [ st.Menu menu = st.Menu();
MenuItem(label: windowHidden ? 'Show App' : 'Hide App', key: windowHidden ? 'show_app' : 'hide_app'), menu.buildFrom([
MenuItem.separator(), st.MenuItemLabel(
MenuItem(label: 'Close App', key: 'close_app'), label: windowHidden ? 'Show App' : 'Hide App',
], onClicked: (st.MenuItemBase menuItem) async {
)); if (windowHidden) {
} await windowManager.show();
} else {
await windowManager.hide();
}
},
),
st.MenuSeparator(),
st.MenuItemLabel(
label: 'Close App',
onClicked: (_) async {
await windowManager.close();
},
),
]);
await systemTray.setContextMenu(menu);
} else {
await trayManager.setContextMenu(Menu(
items: [
MenuItem(label: windowHidden ? 'Show App' : 'Hide App', key: windowHidden ? 'show_app' : 'hide_app'),
MenuItem.separator(),
MenuItem(label: 'Close App', key: 'close_app'),
],
));
}
}

View File

@ -24,6 +24,7 @@
#include <record_linux/record_linux_plugin.h> #include <record_linux/record_linux_plugin.h>
#include <screen_retriever/screen_retriever_plugin.h> #include <screen_retriever/screen_retriever_plugin.h>
#include <super_native_extensions/super_native_extensions_plugin.h> #include <super_native_extensions/super_native_extensions_plugin.h>
#include <system_tray/system_tray_plugin.h>
#include <tray_manager/tray_manager_plugin.h> #include <tray_manager/tray_manager_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h> #include <url_launcher_linux/url_launcher_plugin.h>
#include <window_manager/window_manager_plugin.h> #include <window_manager/window_manager_plugin.h>
@ -83,6 +84,9 @@ void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) super_native_extensions_registrar = g_autoptr(FlPluginRegistrar) super_native_extensions_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "SuperNativeExtensionsPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "SuperNativeExtensionsPlugin");
super_native_extensions_plugin_register_with_registrar(super_native_extensions_registrar); super_native_extensions_plugin_register_with_registrar(super_native_extensions_registrar);
g_autoptr(FlPluginRegistrar) system_tray_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "SystemTrayPlugin");
system_tray_plugin_register_with_registrar(system_tray_registrar);
g_autoptr(FlPluginRegistrar) tray_manager_registrar = g_autoptr(FlPluginRegistrar) tray_manager_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "TrayManagerPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "TrayManagerPlugin");
tray_manager_plugin_register_with_registrar(tray_manager_registrar); tray_manager_plugin_register_with_registrar(tray_manager_registrar);

View File

@ -21,6 +21,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
record_linux record_linux
screen_retriever screen_retriever
super_native_extensions super_native_extensions
system_tray
tray_manager tray_manager
url_launcher_linux url_launcher_linux
window_manager window_manager

View File

@ -41,6 +41,7 @@ import share_plus
import shared_preferences_foundation import shared_preferences_foundation
import store_checker import store_checker
import super_native_extensions import super_native_extensions
import system_tray
import tray_manager import tray_manager
import url_launcher_macos import url_launcher_macos
import video_player_avfoundation import video_player_avfoundation
@ -84,6 +85,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
StoreCheckerPlugin.register(with: registry.registrar(forPlugin: "StoreCheckerPlugin")) StoreCheckerPlugin.register(with: registry.registrar(forPlugin: "StoreCheckerPlugin"))
SuperNativeExtensionsPlugin.register(with: registry.registrar(forPlugin: "SuperNativeExtensionsPlugin")) SuperNativeExtensionsPlugin.register(with: registry.registrar(forPlugin: "SuperNativeExtensionsPlugin"))
SystemTrayPlugin.register(with: registry.registrar(forPlugin: "SystemTrayPlugin"))
TrayManagerPlugin.register(with: registry.registrar(forPlugin: "TrayManagerPlugin")) TrayManagerPlugin.register(with: registry.registrar(forPlugin: "TrayManagerPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin")) FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin"))

View File

@ -2906,6 +2906,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.0" version: "4.0.0"
system_tray:
dependency: "direct main"
description:
name: system_tray
sha256: "40444e5de8ed907822a98694fd031b8accc3cb3c0baa547634ce76189cf3d9cf"
url: "https://pub.dev"
source: hosted
version: "2.0.3"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
@ -2966,10 +2974,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: tray_manager name: tray_manager
sha256: c9a63fd88bd3546287a7eb8ccc978d707eef82c775397af17dda3a4f4c039e64 sha256: bdc3ac6c36f3d12d871459e4a9822705ce5a1165a17fa837103bc842719bf3f7
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.2.3" version: "0.2.4"
try_catch: try_catch:
dependency: transitive dependency: transitive
description: description:

View File

@ -172,6 +172,7 @@ dependencies:
url: https://github.com/ravitejaavv/store_checker url: https://github.com/ravitejaavv/store_checker
ref: master ref: master
synchronized: ^3.1.0+1 synchronized: ^3.1.0+1
system_tray: ^2.0.3
super_drag_and_drop: ^0.8.20 super_drag_and_drop: ^0.8.20
supercharged: ^2.1.1 supercharged: ^2.1.1
system_info2: ^4.0.0 system_info2: ^4.0.0

View File

@ -32,6 +32,7 @@
#include <secure_application/secure_application_plugin.h> #include <secure_application/secure_application_plugin.h>
#include <share_plus/share_plus_windows_plugin_c_api.h> #include <share_plus/share_plus_windows_plugin_c_api.h>
#include <super_native_extensions/super_native_extensions_plugin_c_api.h> #include <super_native_extensions/super_native_extensions_plugin_c_api.h>
#include <system_tray/system_tray_plugin.h>
#include <tray_manager/tray_manager_plugin.h> #include <tray_manager/tray_manager_plugin.h>
#include <url_launcher_windows/url_launcher_windows.h> #include <url_launcher_windows/url_launcher_windows.h>
#include <window_manager/window_manager_plugin.h> #include <window_manager/window_manager_plugin.h>
@ -90,6 +91,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi")); registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi"));
SuperNativeExtensionsPluginCApiRegisterWithRegistrar( SuperNativeExtensionsPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("SuperNativeExtensionsPluginCApi")); registry->GetRegistrarForPlugin("SuperNativeExtensionsPluginCApi"));
SystemTrayPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("SystemTrayPlugin"));
TrayManagerPluginRegisterWithRegistrar( TrayManagerPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("TrayManagerPlugin")); registry->GetRegistrarForPlugin("TrayManagerPlugin"));
UrlLauncherWindowsRegisterWithRegistrar( UrlLauncherWindowsRegisterWithRegistrar(

View File

@ -29,6 +29,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
secure_application secure_application
share_plus share_plus
super_native_extensions super_native_extensions
system_tray
tray_manager tray_manager
url_launcher_windows url_launcher_windows
window_manager window_manager