Skip to content

Commit

Permalink
fix: doesn't minimize to tray when system title bar close button is u…
Browse files Browse the repository at this point in the history
…sed #866
  • Loading branch information
KRTirtho committed Dec 2, 2023
1 parent 5f1df5a commit bb8f250
Show file tree
Hide file tree
Showing 4 changed files with 236 additions and 16 deletions.
17 changes: 1 addition & 16 deletions lib/components/shared/page_window_title_bar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,6 @@ import 'dart:io' show Platform, exit;
import 'package:flutter_desktop_tools/flutter_desktop_tools.dart';
import 'package:local_notifier/local_notifier.dart';

final closeNotification = DesktopTools.createNotification(
title: 'Spotube',
message: 'Running in background. Minimized to System Tray',
actions: [
LocalNotificationAction(text: 'Close The App'),
],
)?..onClickAction = (value) {
exit(0);
};

class PageWindowTitleBar extends StatefulHookConsumerWidget
implements PreferredSizeWidget {
final Widget? leading;
Expand Down Expand Up @@ -113,12 +103,7 @@ class WindowTitleBarButtons extends HookConsumerWidget {
const type = ThemeType.auto;

Future<void> onClose() async {
if (preferences.closeBehavior == CloseBehavior.close) {
exit(0);
} else {
await DesktopTools.window.hide();
await closeNotification?.show();
}
await DesktopTools.window.close();
}

useEffect(() {
Expand Down
32 changes: 32 additions & 0 deletions lib/hooks/configurators/use_close_behavior.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import 'dart:io';

import 'package:flutter_desktop_tools/flutter_desktop_tools.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:spotube/hooks/configurators/use_window_listener.dart';
import 'package:spotube/provider/user_preferences/user_preferences_provider.dart';
import 'package:spotube/provider/user_preferences/user_preferences_state.dart';
import 'package:local_notifier/local_notifier.dart';

final closeNotification = DesktopTools.createNotification(
title: 'Spotube',
message: 'Running in background. Minimized to System Tray',
actions: [
LocalNotificationAction(text: 'Close The App'),
],
)?..onClickAction = (value) {
exit(0);
};

void useCloseBehavior(WidgetRef ref) {
useWindowListener(
onWindowClose: () async {
final preferences = ref.read(userPreferencesProvider);
if (preferences.closeBehavior == CloseBehavior.minimizeToTray) {
await DesktopTools.window.hide();
closeNotification?.show();
} else {
exit(0);
}
},
);
}
197 changes: 197 additions & 0 deletions lib/hooks/configurators/use_window_listener.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
import 'package:flutter/widgets.dart';
import 'package:flutter_desktop_tools/flutter_desktop_tools.dart';
import 'package:flutter_hooks/flutter_hooks.dart';

class CallbackWindowListener implements WindowListener {
final VoidCallback? _onWindowClose;
final VoidCallback? _onWindowFocus;
final VoidCallback? _onWindowBlur;
final VoidCallback? _onWindowMaximize;
final VoidCallback? _onWindowUnmaximize;
final VoidCallback? _onWindowMinimize;
final VoidCallback? _onWindowRestore;
final VoidCallback? _onWindowResize;
final VoidCallback? _onWindowResized;
final VoidCallback? _onWindowMove;
final VoidCallback? _onWindowMoved;
final VoidCallback? _onWindowEnterFullScreen;
final VoidCallback? _onWindowLeaveFullScreen;
final VoidCallback? _onWindowDocked;
final VoidCallback? _onWindowUndocked;
final VoidCallback? _onWindowEvent;

const CallbackWindowListener({
VoidCallback? onWindowClose,
VoidCallback? onWindowFocus,
VoidCallback? onWindowBlur,
VoidCallback? onWindowMaximize,
VoidCallback? onWindowUnmaximize,
VoidCallback? onWindowMinimize,
VoidCallback? onWindowRestore,
VoidCallback? onWindowResize,
VoidCallback? onWindowResized,
VoidCallback? onWindowMove,
VoidCallback? onWindowMoved,
VoidCallback? onWindowEnterFullScreen,
VoidCallback? onWindowLeaveFullScreen,
VoidCallback? onWindowDocked,
VoidCallback? onWindowUndocked,
VoidCallback? onWindowEvent,
}) : _onWindowClose = onWindowClose,
_onWindowFocus = onWindowFocus,
_onWindowBlur = onWindowBlur,
_onWindowMaximize = onWindowMaximize,
_onWindowUnmaximize = onWindowUnmaximize,
_onWindowMinimize = onWindowMinimize,
_onWindowRestore = onWindowRestore,
_onWindowResize = onWindowResize,
_onWindowResized = onWindowResized,
_onWindowMove = onWindowMove,
_onWindowMoved = onWindowMoved,
_onWindowEnterFullScreen = onWindowEnterFullScreen,
_onWindowLeaveFullScreen = onWindowLeaveFullScreen,
_onWindowDocked = onWindowDocked,
_onWindowUndocked = onWindowUndocked,
_onWindowEvent = onWindowEvent;

@override
void onWindowBlur() {
return _onWindowBlur?.call();
}

@override
void onWindowClose() {
return _onWindowClose?.call();
}

@override
void onWindowDocked() {
return _onWindowDocked?.call();
}

@override
void onWindowEnterFullScreen() {
return _onWindowEnterFullScreen?.call();
}

@override
void onWindowEvent(String eventName) {
return _onWindowEvent?.call();
}

@override
void onWindowFocus() {
return _onWindowFocus?.call();
}

@override
void onWindowLeaveFullScreen() {
return _onWindowLeaveFullScreen?.call();
}

@override
void onWindowMaximize() {
return _onWindowMaximize?.call();
}

@override
void onWindowMinimize() {
return _onWindowMinimize?.call();
}

@override
void onWindowMove() {
return _onWindowMove?.call();
}

@override
void onWindowMoved() {
return _onWindowMoved?.call();
}

@override
void onWindowResize() {
return _onWindowResize?.call();
}

@override
void onWindowResized() {
return _onWindowResized?.call();
}

@override
void onWindowRestore() {
return _onWindowRestore?.call();
}

@override
void onWindowUndocked() {
return _onWindowUndocked?.call();
}

@override
void onWindowUnmaximize() {
return _onWindowUnmaximize?.call();
}
}

void useWindowListener({
VoidCallback? onWindowClose,
VoidCallback? onWindowFocus,
VoidCallback? onWindowBlur,
VoidCallback? onWindowMaximize,
VoidCallback? onWindowUnmaximize,
VoidCallback? onWindowMinimize,
VoidCallback? onWindowRestore,
VoidCallback? onWindowResize,
VoidCallback? onWindowResized,
VoidCallback? onWindowMove,
VoidCallback? onWindowMoved,
VoidCallback? onWindowEnterFullScreen,
VoidCallback? onWindowLeaveFullScreen,
VoidCallback? onWindowDocked,
VoidCallback? onWindowUndocked,
VoidCallback? onWindowEvent,
}) {
useEffect(() {
final listener = CallbackWindowListener(
onWindowClose: onWindowClose,
onWindowFocus: onWindowFocus,
onWindowBlur: onWindowBlur,
onWindowMaximize: onWindowMaximize,
onWindowUnmaximize: onWindowUnmaximize,
onWindowMinimize: onWindowMinimize,
onWindowRestore: onWindowRestore,
onWindowResize: onWindowResize,
onWindowResized: onWindowResized,
onWindowMove: onWindowMove,
onWindowMoved: onWindowMoved,
onWindowEnterFullScreen: onWindowEnterFullScreen,
onWindowLeaveFullScreen: onWindowLeaveFullScreen,
onWindowDocked: onWindowDocked,
onWindowUndocked: onWindowUndocked,
onWindowEvent: onWindowEvent,
);
DesktopTools.window.addListener(listener);
return () {
DesktopTools.window.removeListener(listener);
};
}, [
onWindowClose,
onWindowFocus,
onWindowBlur,
onWindowMaximize,
onWindowUnmaximize,
onWindowMinimize,
onWindowRestore,
onWindowResize,
onWindowResized,
onWindowMove,
onWindowMoved,
onWindowEnterFullScreen,
onWindowLeaveFullScreen,
onWindowDocked,
onWindowUndocked,
onWindowEvent,
]);
}
6 changes: 6 additions & 0 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import 'package:metadata_god/metadata_god.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:spotube/collections/routes.dart';
import 'package:spotube/collections/intents.dart';
import 'package:spotube/hooks/configurators/use_close_behavior.dart';
import 'package:spotube/hooks/configurators/use_disable_battery_optimizations.dart';
import 'package:spotube/hooks/configurators/use_get_storage_perms.dart';
import 'package:spotube/l10n/l10n.dart';
Expand Down Expand Up @@ -49,6 +50,10 @@ Future<void> main(List<String> rawArgs) async {
await FlutterDisplayMode.setHighRefreshRate();
}

if (DesktopTools.platform.isDesktop) {
await DesktopTools.window.setPreventClose(true);
}

await DesktopTools.ensureInitialized(
DesktopWindowOptions(
hideTitleBar: true,
Expand Down Expand Up @@ -177,6 +182,7 @@ class SpotubeState extends ConsumerState<Spotube> {
ref.watch(paletteProvider.select((s) => s?.dominantColor?.color));

useInitSysTray(ref);
useCloseBehavior(ref);

useEffect(() {
FlutterNativeSplash.remove();
Expand Down

0 comments on commit bb8f250

Please sign in to comment.