From 45e72e0ad9165fe9e888c2683055a53e1ba169ec Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Wed, 11 Feb 2026 09:29:15 +0100 Subject: [PATCH] fix: unmaximize window before entering fullscreen on Windows --- lib/screens/video_player_screen.dart | 14 ++----- lib/services/fullscreen_state_manager.dart | 42 +++++++++++++++++++ .../video_controls/video_controls.dart | 23 +--------- 3 files changed, 47 insertions(+), 32 deletions(-) diff --git a/lib/screens/video_player_screen.dart b/lib/screens/video_player_screen.dart index 1809fc19..b527f976 100644 --- a/lib/screens/video_player_screen.dart +++ b/lib/screens/video_player_screen.dart @@ -26,6 +26,7 @@ import '../models/companion_remote/remote_command_type.dart'; import '../providers/companion_remote_provider.dart'; import '../services/companion_remote/companion_remote_receiver.dart'; import '../services/macos_window_service.dart'; +import '../services/fullscreen_state_manager.dart'; import '../services/discord_rpc_service.dart'; import '../services/episode_navigation_service.dart'; import '../services/media_controls_manager.dart'; @@ -1270,16 +1271,7 @@ class VideoPlayerScreenState extends State with WidgetsBindin Future _toggleFullscreen() async { if (PlatformDetector.isMobile(context)) return; - final isCurrentlyFullscreen = await windowManager.isFullScreen(); - if (Platform.isMacOS) { - if (isCurrentlyFullscreen) { - await MacOSWindowService.exitFullscreen(); - } else { - await MacOSWindowService.enterFullscreen(); - } - } else { - await windowManager.setFullScreen(!isCurrentlyFullscreen); - } + await FullscreenStateManager().toggleFullscreen(); } /// Exit fullscreen before leaving the player (Windows/Linux only). @@ -1289,7 +1281,7 @@ class VideoPlayerScreenState extends State with WidgetsBindin if (Platform.isWindows || Platform.isLinux) { final isFullscreen = await windowManager.isFullScreen(); if (isFullscreen) { - await windowManager.setFullScreen(false); + await FullscreenStateManager().exitFullscreen(); await Future.delayed(const Duration(milliseconds: 100)); } } diff --git a/lib/services/fullscreen_state_manager.dart b/lib/services/fullscreen_state_manager.dart index 072984fa..5ea00837 100644 --- a/lib/services/fullscreen_state_manager.dart +++ b/lib/services/fullscreen_state_manager.dart @@ -1,6 +1,7 @@ import 'dart:io' show Platform; import 'package:flutter/foundation.dart'; import 'package:window_manager/window_manager.dart'; +import 'macos_window_service.dart'; /// Global manager for tracking fullscreen state across the app class FullscreenStateManager extends ChangeNotifier with WindowListener { @@ -12,6 +13,7 @@ class FullscreenStateManager extends ChangeNotifier with WindowListener { bool _isFullscreen = false; bool _isListening = false; + bool _wasMaximized = false; bool get isFullscreen => _isFullscreen; @@ -23,6 +25,46 @@ class FullscreenStateManager extends ChangeNotifier with WindowListener { } } + /// Toggle fullscreen state, handling maximized-to-fullscreen transition on Windows/Linux + Future toggleFullscreen() async { + final isCurrentlyFullscreen = await windowManager.isFullScreen(); + + if (Platform.isMacOS) { + if (isCurrentlyFullscreen) { + await MacOSWindowService.exitFullscreen(); + } else { + await MacOSWindowService.enterFullscreen(); + } + } else { + if (isCurrentlyFullscreen) { + await windowManager.setFullScreen(false); + if (_wasMaximized) { + await windowManager.maximize(); + _wasMaximized = false; + } + } else { + _wasMaximized = await windowManager.isMaximized(); + if (_wasMaximized) { + await windowManager.unmaximize(); + } + await windowManager.setFullScreen(true); + } + } + } + + /// Exit fullscreen, restoring maximized state if needed + Future exitFullscreen() async { + if (Platform.isMacOS) { + await MacOSWindowService.exitFullscreen(); + } else { + await windowManager.setFullScreen(false); + if (_wasMaximized) { + await windowManager.maximize(); + _wasMaximized = false; + } + } + } + /// Start monitoring fullscreen state void startMonitoring() { if (!_shouldMonitor() || _isListening) return; diff --git a/lib/widgets/video_controls/video_controls.dart b/lib/widgets/video_controls/video_controls.dart index 5ea3b6df..300c95ce 100644 --- a/lib/widgets/video_controls/video_controls.dart +++ b/lib/widgets/video_controls/video_controls.dart @@ -15,6 +15,7 @@ import 'package:flutter/services.dart' KeyEvent, KeyDownEvent, HardwareKeyboard; +import '../../services/fullscreen_state_manager.dart'; import '../../services/macos_window_service.dart'; import '../../services/pip_service.dart'; import 'package:window_manager/window_manager.dart'; @@ -1236,27 +1237,7 @@ class _PlexVideoControlsState extends State with WindowListen Future _toggleFullscreen() async { if (!PlatformDetector.isMobile(context)) { - // Query actual window state to determine what action to take - // This ensures we always toggle correctly regardless of local state - final isCurrentlyFullscreen = await windowManager.isFullScreen(); - - if (Platform.isMacOS) { - // Use native macOS fullscreen - titlebar is handled automatically - // Window listener will update _isFullscreen for UI - if (isCurrentlyFullscreen) { - await MacOSWindowService.exitFullscreen(); - } else { - await MacOSWindowService.enterFullscreen(); - } - } else { - // For Windows/Linux, use window_manager - // Window listener will update _isFullscreen for UI - if (isCurrentlyFullscreen) { - await windowManager.setFullScreen(false); - } else { - await windowManager.setFullScreen(true); - } - } + await FullscreenStateManager().toggleFullscreen(); } }