mirror of
https://github.com/BlueBubblesApp/bluebubbles-app.git
synced 2025-05-17 13:15:58 +08:00
Workaround for #2818
Signed-off-by: Joel Jothiprakasam <hijoelj@gmail.com>
This commit is contained in:
147
lib/main.dart
147
lib/main.dart
@ -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'),
|
||||||
|
],
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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"))
|
||||||
|
12
pubspec.lock
12
pubspec.lock
@ -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:
|
||||||
|
@ -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
|
||||||
|
@ -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(
|
||||||
|
@ -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
|
||||||
|
Reference in New Issue
Block a user