Allow hiding the window.

This commit is contained in:
Dain Nilsson 2023-02-24 14:10:39 +01:00
parent ac3f0c47d4
commit fc3238e829
No known key found for this signature in database
GPG Key ID: F04367096FBA95E8
6 changed files with 86 additions and 28 deletions

View File

@ -134,5 +134,6 @@ class WindowState with _$WindowState {
required bool focused,
required bool visible,
required bool active,
@Default(false) bool hidden,
}) = _WindowState;
}

View File

@ -799,6 +799,7 @@ mixin _$WindowState {
bool get focused => throw _privateConstructorUsedError;
bool get visible => throw _privateConstructorUsedError;
bool get active => throw _privateConstructorUsedError;
bool get hidden => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$WindowStateCopyWith<WindowState> get copyWith =>
@ -811,7 +812,7 @@ abstract class $WindowStateCopyWith<$Res> {
WindowState value, $Res Function(WindowState) then) =
_$WindowStateCopyWithImpl<$Res, WindowState>;
@useResult
$Res call({bool focused, bool visible, bool active});
$Res call({bool focused, bool visible, bool active, bool hidden});
}
/// @nodoc
@ -830,6 +831,7 @@ class _$WindowStateCopyWithImpl<$Res, $Val extends WindowState>
Object? focused = null,
Object? visible = null,
Object? active = null,
Object? hidden = null,
}) {
return _then(_value.copyWith(
focused: null == focused
@ -844,6 +846,10 @@ class _$WindowStateCopyWithImpl<$Res, $Val extends WindowState>
? _value.active
: active // ignore: cast_nullable_to_non_nullable
as bool,
hidden: null == hidden
? _value.hidden
: hidden // ignore: cast_nullable_to_non_nullable
as bool,
) as $Val);
}
}
@ -856,7 +862,7 @@ abstract class _$$_WindowStateCopyWith<$Res>
__$$_WindowStateCopyWithImpl<$Res>;
@override
@useResult
$Res call({bool focused, bool visible, bool active});
$Res call({bool focused, bool visible, bool active, bool hidden});
}
/// @nodoc
@ -873,6 +879,7 @@ class __$$_WindowStateCopyWithImpl<$Res>
Object? focused = null,
Object? visible = null,
Object? active = null,
Object? hidden = null,
}) {
return _then(_$_WindowState(
focused: null == focused
@ -887,6 +894,10 @@ class __$$_WindowStateCopyWithImpl<$Res>
? _value.active
: active // ignore: cast_nullable_to_non_nullable
as bool,
hidden: null == hidden
? _value.hidden
: hidden // ignore: cast_nullable_to_non_nullable
as bool,
));
}
}
@ -895,7 +906,10 @@ class __$$_WindowStateCopyWithImpl<$Res>
class _$_WindowState implements _WindowState {
_$_WindowState(
{required this.focused, required this.visible, required this.active});
{required this.focused,
required this.visible,
required this.active,
this.hidden = false});
@override
final bool focused;
@ -903,10 +917,13 @@ class _$_WindowState implements _WindowState {
final bool visible;
@override
final bool active;
@override
@JsonKey()
final bool hidden;
@override
String toString() {
return 'WindowState(focused: $focused, visible: $visible, active: $active)';
return 'WindowState(focused: $focused, visible: $visible, active: $active, hidden: $hidden)';
}
@override
@ -916,11 +933,13 @@ class _$_WindowState implements _WindowState {
other is _$_WindowState &&
(identical(other.focused, focused) || other.focused == focused) &&
(identical(other.visible, visible) || other.visible == visible) &&
(identical(other.active, active) || other.active == active));
(identical(other.active, active) || other.active == active) &&
(identical(other.hidden, hidden) || other.hidden == hidden));
}
@override
int get hashCode => Object.hash(runtimeType, focused, visible, active);
int get hashCode =>
Object.hash(runtimeType, focused, visible, active, hidden);
@JsonKey(ignore: true)
@override
@ -933,7 +952,8 @@ abstract class _WindowState implements WindowState {
factory _WindowState(
{required final bool focused,
required final bool visible,
required final bool active}) = _$_WindowState;
required final bool active,
final bool hidden}) = _$_WindowState;
@override
bool get focused;
@ -942,6 +962,8 @@ abstract class _WindowState implements WindowState {
@override
bool get active;
@override
bool get hidden;
@override
@JsonKey(ignore: true)
_$$_WindowStateCopyWith<_$_WindowState> get copyWith =>
throw _privateConstructorUsedError;

View File

@ -52,9 +52,9 @@ final _log = Logger('desktop.init');
const String _keyWidth = 'DESKTOP_WINDOW_WIDTH';
const String _keyHeight = 'DESKTOP_WINDOW_HEIGHT';
class _WindowResizeListener extends WindowListener {
class _WindowEventListener extends WindowListener {
final SharedPreferences _prefs;
_WindowResizeListener(this._prefs);
_WindowEventListener(this._prefs);
@override
void onWindowResize() async {
@ -62,6 +62,13 @@ class _WindowResizeListener extends WindowListener {
await _prefs.setDouble(_keyWidth, size.width);
await _prefs.setDouble(_keyHeight, size.height);
}
@override
void onWindowClose() async {
if (Platform.isMacOS) {
await windowManager.destroy();
}
}
}
Future<Widget> initialize(List<String> argv) async {
@ -69,14 +76,24 @@ Future<Widget> initialize(List<String> argv) async {
await windowManager.ensureInitialized();
final prefs = await SharedPreferences.getInstance();
final isHidden = prefs.getBool(windowHidden) ?? false;
unawaited(windowManager.waitUntilReadyToShow().then((_) async {
await windowManager.setMinimumSize(const Size(270, 0));
final width = prefs.getDouble(_keyWidth) ?? 400;
final height = prefs.getDouble(_keyHeight) ?? 720;
await windowManager.setSize(Size(width, height));
await windowManager.show();
windowManager.addListener(_WindowResizeListener(prefs));
unawaited(windowManager
.waitUntilReadyToShow(WindowOptions(
minimumSize: const Size(270, 0),
size: Size(
prefs.getDouble(_keyWidth) ?? 400,
prefs.getDouble(_keyHeight) ?? 720,
),
skipTaskbar: isHidden,
))
.then((_) async {
if (isHidden) {
await windowManager.setSkipTaskbar(true);
} else {
await windowManager.show();
}
windowManager.addListener(_WindowEventListener(prefs));
}));
// Either use the _HELPER_PATH environment variable, or look relative to executable.

View File

@ -24,8 +24,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:logging/logging.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:window_manager/window_manager.dart';
import 'package:yubico_authenticator/app/logging.dart';
import '../app/logging.dart';
import '../app/models.dart';
import '../app/state.dart';
import '../core/state.dart';
@ -58,20 +58,23 @@ class _RpcStateNotifier extends StateNotifier<RpcState> {
}
}
final _windowStateProvider =
StateNotifierProvider<_WindowStateNotifier, WindowState>(
(ref) => _WindowStateNotifier());
final desktopWindowStateProvider =
StateNotifierProvider<DesktopWindowStateNotifier, WindowState>(
(ref) => DesktopWindowStateNotifier(ref.watch(prefProvider)));
final desktopWindowStateProvider = Provider<WindowState>(
(ref) => ref.watch(_windowStateProvider),
);
const String windowHidden = 'DESKTOP_WINDOW_HIDDEN';
class _WindowStateNotifier extends StateNotifier<WindowState>
class DesktopWindowStateNotifier extends StateNotifier<WindowState>
with WindowListener {
final SharedPreferences _prefs;
Timer? _idleTimer;
_WindowStateNotifier()
: super(WindowState(focused: true, visible: true, active: true)) {
DesktopWindowStateNotifier(this._prefs)
: super(WindowState(
focused: true,
visible: true,
active: true,
hidden: _prefs.getBool(windowHidden) ?? false)) {
_init();
}
@ -88,6 +91,17 @@ class _WindowStateNotifier extends StateNotifier<WindowState>
}
}
void setWindowHidden(bool hidden) async {
if (hidden) {
await windowManager.hide();
} else {
await windowManager.show();
}
await windowManager.setSkipTaskbar(hidden);
await _prefs.setBool(windowHidden, hidden);
state = state.copyWith(hidden: hidden);
}
@override
void dispose() {
windowManager.removeListener(this);
@ -101,6 +115,7 @@ class _WindowStateNotifier extends StateNotifier<WindowState>
}
@override
@protected
void onWindowEvent(String eventName) {
if (mounted) {
switch (eventName) {

View File

@ -4,6 +4,7 @@ import FlutterMacOS
@NSApplicationMain
class AppDelegate: FlutterAppDelegate {
override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
return true
// Keep app running if window closes
return false
}
}

View File

@ -172,7 +172,9 @@ bool Win32Window::Create(const std::wstring& title,
}
bool Win32Window::Show() {
return ShowWindow(window_handle_, SW_SHOWNORMAL);
// We show the mindow manually
return true;
//return ShowWindow(window_handle_, SW_SHOWNORMAL);
}
// static