From 6371d7a36e3ec8b82877879de9aa92a0859a466a Mon Sep 17 00:00:00 2001 From: Cameron <25990062+crtdll@users.noreply.github.com> Date: Sun, 26 Apr 2026 16:59:50 +0100 Subject: [PATCH] fix(windows): fixed black screen while navigating between videos in full screen --- lib/screens/video_player_screen.dart | 9 ++++++--- lib/services/display_mode_service.dart | 12 ++++++++++++ windows/runner/CMakeLists.txt | 5 ++++- windows/runner/mpv/mpv_plugin.cpp | 4 ++++ windows/runner/pch.h | 19 +++++++++++++++++++ 5 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 windows/runner/pch.h diff --git a/lib/screens/video_player_screen.dart b/lib/screens/video_player_screen.dart index 16e3bc84..c4cf3973 100644 --- a/lib/screens/video_player_screen.dart +++ b/lib/screens/video_player_screen.dart @@ -613,6 +613,7 @@ class VideoPlayerScreenState extends State with WidgetsBindin // Initialize Windows display mode service. if (Platform.isWindows) { _displayModeService = DisplayModeService(settingsService, FullscreenStateManager()); + await _displayModeService!.syncWithNative(); FullscreenStateManager().addListener(_onFullscreenChanged); } @@ -2108,11 +2109,11 @@ class VideoPlayerScreenState extends State with WidgetsBindin } // Detach and dispose current player before switching to avoid sync calls on a disposed instance + _isReplacingWithVideo = true; await disposePlayerForNavigation(); if (!mounted) return; // Use same navigation as local episode change (pushReplacement from player context) - _isReplacingWithVideo = true; unawaited(navigateToVideoPlayer(context, metadata: metadata, usePushReplacement: true)); } @@ -2363,7 +2364,7 @@ class VideoPlayerScreenState extends State with WidgetsBindin if (Platform.isWindows && _displayModeService != null) { FullscreenStateManager().removeListener(_onFullscreenChanged); } - if (Platform.isWindows && _displayModeService != null && _displayModeService!.anyChangeApplied) { + if (!_isReplacingWithVideo && Platform.isWindows && _displayModeService != null && _displayModeService!.anyChangeApplied) { if (_displayModeService!.hdrStateChanged && player != null) { player!.setProperty('target-colorspace-hint', 'no'); } @@ -3371,7 +3372,9 @@ class VideoPlayerScreenState extends State with WidgetsBindin // Clear frame rate matching before disposing (Android only) await _clearFrameRateMatching(); // Restore Windows display mode before disposing - await _restoreWindowsDisplayMode(); + if (!_isReplacingWithVideo) { + await _restoreWindowsDisplayMode(); + } await player?.dispose(); } catch (e) { appLogger.d('Error disposing player before navigation', error: e); diff --git a/lib/services/display_mode_service.dart b/lib/services/display_mode_service.dart index 86772882..3948a2cd 100644 --- a/lib/services/display_mode_service.dart +++ b/lib/services/display_mode_service.dart @@ -172,4 +172,16 @@ class DisplayModeService { return bestRate; } + + Future syncWithNative() async { + if (!Platform.isWindows) return; + try { + final modeChanged = await _channel.invokeMethod('isModeChanged'); + _displayModeChanged = modeChanged ?? false; + final hdrChanged = await _channel.invokeMethod('isHDRChanged'); + _hdrStateChanged = hdrChanged ?? false; + } catch (e) { + appLogger.w('Failed syncing native state', error: e); + } + } } diff --git a/windows/runner/CMakeLists.txt b/windows/runner/CMakeLists.txt index a4afe274..1c942a08 100644 --- a/windows/runner/CMakeLists.txt +++ b/windows/runner/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(runner LANGUAGES CXX) # Define the application target. To change its name, change BINARY_NAME in the @@ -26,6 +26,9 @@ add_executable(${BINARY_NAME} WIN32 # that need different build settings. apply_standard_settings(${BINARY_NAME}) +# Setup precompiled header +target_precompile_headers(${BINARY_NAME} PRIVATE "pch.h") + # Add preprocessor definitions for the build version. target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") diff --git a/windows/runner/mpv/mpv_plugin.cpp b/windows/runner/mpv/mpv_plugin.cpp index 48585f71..cd0964cc 100644 --- a/windows/runner/mpv/mpv_plugin.cpp +++ b/windows/runner/mpv/mpv_plugin.cpp @@ -438,6 +438,10 @@ void MpvPlayerPlugin::HandleMethodCall( HWND hwnd = GetWindow(); bool success = display_mode_manager_.RestoreOriginalHDRState(hwnd); result->Success(flutter::EncodableValue(success)); + } else if (method == "isModeChanged") { + result->Success(flutter::EncodableValue(display_mode_manager_.IsModeChanged())); + } else if (method == "isHDRChanged") { + result->Success(flutter::EncodableValue(display_mode_manager_.IsHDRChanged())); } else { result->NotImplemented(); } diff --git a/windows/runner/pch.h b/windows/runner/pch.h new file mode 100644 index 00000000..b7c26ecd --- /dev/null +++ b/windows/runner/pch.h @@ -0,0 +1,19 @@ +#ifndef PCH_H +#define PCH_H + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif \ No newline at end of file