fix(windows): fixed black screen while navigating between videos in full screen

This commit is contained in:
Cameron
2026-04-26 16:59:50 +01:00
committed by GitHub
parent 425da3ab7d
commit 6371d7a36e
5 changed files with 45 additions and 4 deletions
+6 -3
View File
@@ -613,6 +613,7 @@ class VideoPlayerScreenState extends State<VideoPlayerScreen> 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<VideoPlayerScreen> 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<VideoPlayerScreen> 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<VideoPlayerScreen> 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);
+12
View File
@@ -172,4 +172,16 @@ class DisplayModeService {
return bestRate;
}
Future<void> syncWithNative() async {
if (!Platform.isWindows) return;
try {
final modeChanged = await _channel.invokeMethod<bool>('isModeChanged');
_displayModeChanged = modeChanged ?? false;
final hdrChanged = await _channel.invokeMethod<bool>('isHDRChanged');
_hdrStateChanged = hdrChanged ?? false;
} catch (e) {
appLogger.w('Failed syncing native state', error: e);
}
}
}
+4 -1
View File
@@ -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}")
+4
View File
@@ -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();
}
+19
View File
@@ -0,0 +1,19 @@
#ifndef PCH_H
#define PCH_H
#include <Windows.h>
#include <dwmapi.h>
#include <optional>
#include <memory>
#include <io.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <vector>
#include <functional>
#include <cmath>
#include <algorithm>
#include <map>
#endif