Skip to content

Commit

Permalink
fix: system tray causing crash on linux
Browse files Browse the repository at this point in the history
The
[system_tray](https://pub.dev/packages/system_tray)
package appears abandoned, with no update or
comments for 13 months. The issue this PR fixes
is due to a known bug in the system_tray package:
antler119/system_tray#64

This PR replaces the system_tray package with the
[tray_manager](https://pub.dev/packages/tray_manager)
package, which is actively maintained and doesn't
cause the crash. `tray_manager` has beem around
for 3+ years and had a release just 11 days ago.

Resolves #232
  • Loading branch information
Merrit authored and anandnet committed Jun 24, 2024
1 parent 8c9c7c2 commit d27153f
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 85 deletions.
126 changes: 68 additions & 58 deletions lib/utils/system_tray.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import 'package:audio_service/audio_service.dart';
import 'package:get/get.dart';
import 'package:harmonymusic/ui/player/player_controller.dart';
import 'package:harmonymusic/ui/screens/Settings/settings_screen_controller.dart';
import 'package:system_tray/system_tray.dart';
import 'package:tray_manager/tray_manager.dart';
import 'package:window_manager/window_manager.dart';


class DesktopSystemTray extends GetxService {
class DesktopSystemTray extends GetxService with TrayListener {
late WindowListener listener;

@override
void onInit() {
trayManager.addListener(this);
Future.delayed(const Duration(seconds: 2), () => initSystemTray());
super.onInit();
}
Expand All @@ -23,79 +23,89 @@ class DesktopSystemTray extends GetxService {
: 'assets/icons/icon.png';

await windowManager.ensureInitialized();
final SystemTray systemTray = SystemTray();
final playerController = Get.find<PlayerController>();

// We first init the systray menu
await systemTray.initSystemTray(
title: "system tray",
iconPath: path,
);
await trayManager.setIcon(path);

// create context menu
final Menu menu = Menu();
await menu.buildFrom([
MenuItemLabel(
label: 'Show/Hide',
onClicked: (menuItem) async => await windowManager.isVisible()
? await windowManager.hide()
: await windowManager.show()),
MenuSeparator(),
MenuItemLabel(
label: 'Prev',
onClicked: (menuItem) {
if (playerController.currentQueue.isNotEmpty) {
playerController.prev();
}
}),
MenuItemLabel(
label: 'Play/Pause',
onClicked: (menuItem) {
if (playerController.currentQueue.isNotEmpty) {
playerController.playPause();
}
}),
MenuItemLabel(
label: 'Next',
onClicked: (menuItem) {
if (playerController.currentQueue.isNotEmpty) {
playerController.next();
}
}),
MenuSeparator(),
MenuItemLabel(
label: 'Quit',
onClicked: (menuItem) async {
await Get.find<AudioHandler>().customAction("saveSession");
exit(0);
}),
final Menu menu = Menu(items: [
MenuItem(
label: 'Show/Hide',
onClick: (menuItem) async => await windowManager.isVisible()
? await windowManager.hide()
: await windowManager.show(),
),
MenuItem.separator(),
MenuItem(
label: 'Prev',
onClick: (menuItem) {
if (playerController.currentQueue.isNotEmpty) {
playerController.prev();
}
},
),
MenuItem(
label: 'Play/Pause',
onClick: (menuItem) {
if (playerController.currentQueue.isNotEmpty) {
playerController.playPause();
}
},
),
MenuItem(
label: 'Next',
onClick: (menuItem) {
if (playerController.currentQueue.isNotEmpty) {
playerController.next();
}
},
),
MenuItem.separator(),
MenuItem(
label: 'Quit',
onClick: (menuItem) async {
await Get.find<AudioHandler>().customAction("saveSession");
exit(0);
},
),
]);

// set context menu
await systemTray.setContextMenu(menu);
await trayManager.setContextMenu(menu);

// handle system tray event
systemTray.registerSystemTrayEventHandler((eventName) {
if (eventName == kSystemTrayEventClick) {
GetPlatform.isWindows
? windowManager.show()
: systemTray.popUpContextMenu();
} else if (eventName == kSystemTrayEventRightClick) {
GetPlatform.isWindows
? systemTray.popUpContextMenu()
: windowManager.show();
}
});
await windowManager.setPreventClose(true);
listener = CloseWindowListener();
windowManager.addListener(listener);
}

@override
void onClose() {
trayManager.removeListener(this);
windowManager.removeListener(listener);
super.onClose();
}

@override
void onTrayIconMouseDown() {
if (GetPlatform.isWindows) {
windowManager.show();
} else {
trayManager.popUpContextMenu();
}

super.onTrayIconMouseDown();
}

@override
void onTrayIconRightMouseDown() {
if (GetPlatform.isWindows) {
trayManager.popUpContextMenu();
} else {
windowManager.show();
}

super.onTrayIconRightMouseDown();
}
}

class CloseWindowListener extends WindowListener {
Expand Down
8 changes: 4 additions & 4 deletions linux/flutter/generated_plugin_registrant.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include <audiotags/audiotags_plugin.h>
#include <media_kit_libs_linux/media_kit_libs_linux_plugin.h>
#include <screen_retriever/screen_retriever_plugin.h>
#include <system_tray/system_tray_plugin.h>
#include <tray_manager/tray_manager_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h>
#include <window_manager/window_manager_plugin.h>

Expand All @@ -23,9 +23,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) 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 =
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);
Expand Down
2 changes: 1 addition & 1 deletion linux/flutter/generated_plugins.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
audiotags
media_kit_libs_linux
screen_retriever
system_tray
tray_manager
url_launcher_linux
window_manager
)
Expand Down
82 changes: 61 additions & 21 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.4.9"
leak_tracker:
dependency: transitive
description:
name: leak_tracker
sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
url: "https://pub.dev"
source: hosted
version: "10.0.0"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
url: "https://pub.dev"
source: hosted
version: "2.0.1"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
url: "https://pub.dev"
source: hosted
version: "2.0.1"
lints:
dependency: transitive
description:
Expand All @@ -510,18 +534,18 @@ packages:
dependency: transitive
description:
name: matcher
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
url: "https://pub.dev"
source: hosted
version: "0.12.16"
version: "0.12.16+1"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
url: "https://pub.dev"
source: hosted
version: "0.5.0"
version: "0.8.0"
media_kit:
dependency: transitive
description:
Expand All @@ -546,14 +570,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.9"
menu_base:
dependency: transitive
description:
name: menu_base
sha256: "820368014a171bd1241030278e6c2617354f492f5c703d7b7d4570a6b8b84405"
url: "https://pub.dev"
source: hosted
version: "0.1.1"
meta:
dependency: transitive
description:
name: meta
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
url: "https://pub.dev"
source: hosted
version: "1.10.0"
version: "1.11.0"
mime:
dependency: transitive
description:
Expand Down Expand Up @@ -582,10 +614,10 @@ packages:
dependency: "direct main"
description:
name: path
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
url: "https://pub.dev"
source: hosted
version: "1.8.3"
version: "1.9.0"
path_provider:
dependency: "direct main"
description:
Expand Down Expand Up @@ -803,6 +835,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.0"
shortid:
dependency: transitive
description:
name: shortid
sha256: d0b40e3dbb50497dad107e19c54ca7de0d1a274eb9b4404991e443dadb9ebedb
url: "https://pub.dev"
source: hosted
version: "0.1.2"
sidebar_with_animation:
dependency: "direct main"
description:
Expand Down Expand Up @@ -880,14 +920,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.1.0"
system_tray:
dependency: "direct main"
description:
name: system_tray
sha256: "40444e5de8ed907822a98694fd031b8accc3cb3c0baa547634ce76189cf3d9cf"
url: "https://pub.dev"
source: hosted
version: "2.0.3"
term_glyph:
dependency: transitive
description:
Expand All @@ -912,6 +944,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.0"
tray_manager:
dependency: "direct main"
description:
name: tray_manager
sha256: c9a63fd88bd3546287a7eb8ccc978d707eef82c775397af17dda3a4f4c039e64
url: "https://pub.dev"
source: hosted
version: "0.2.3"
tuple:
dependency: transitive
description:
Expand Down Expand Up @@ -1024,14 +1064,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.4"
web:
vm_service:
dependency: transitive
description:
name: web
sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
name: vm_service
sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
url: "https://pub.dev"
source: hosted
version: "0.3.0"
version: "13.0.0"
web_socket_channel:
dependency: transitive
description:
Expand Down Expand Up @@ -1089,5 +1129,5 @@ packages:
source: hosted
version: "2.0.2"
sdks:
dart: ">=3.2.0-194.0.dev <4.0.0"
dart: ">=3.2.0-0 <4.0.0"
flutter: ">=3.13.0"
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,13 @@ dependencies:
url: https://github.com/anandnet/just_audio_media_kit.git
ref: 06de226da469f5c55dd780b215bcc45a0d6269fb
sidebar_with_animation: ^0.0.3
system_tray: ^2.0.3
window_manager: ^0.3.7
smtc_windows: ^0.1.2
audio_service_mpris: ^0.1.3
ionicons: ^0.2.2
archive: ^3.1.6
path: ^1.8.3
tray_manager: ^0.2.3
dev_dependencies:
flutter_test:
sdk: flutter
Expand Down

0 comments on commit d27153f

Please sign in to comment.