From 7543a8c55b8849d5b2b98add79d29ad00eb5bf8c Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Tue, 10 Mar 2026 22:24:14 +0100 Subject: [PATCH] refactor: clean up windows code --- windows/runner/mpv/mpv_container.cpp | 45 +++------------------- windows/runner/mpv/mpv_container.h | 7 +--- windows/runner/mpv/mpv_core.cpp | 34 +---------------- windows/runner/mpv/mpv_core.h | 10 +---- windows/runner/mpv/mpv_player.cpp | 57 +--------------------------- windows/runner/mpv/mpv_plugin.cpp | 40 +------------------ 6 files changed, 13 insertions(+), 180 deletions(-) diff --git a/windows/runner/mpv/mpv_container.cpp b/windows/runner/mpv/mpv_container.cpp index 2b332a08..1121de89 100644 --- a/windows/runner/mpv/mpv_container.cpp +++ b/windows/runner/mpv/mpv_container.cpp @@ -2,20 +2,10 @@ #include -#include "mpv_core.h" -#include "utils.h" - namespace mpv { MpvContainer* MpvContainer::GetInstance() { return instance_.get(); } -MpvContainer::~MpvContainer() { - if (taskbar_) { - taskbar_->Release(); - taskbar_ = nullptr; - } -} - HWND MpvContainer::Create() { auto window_class = WNDCLASSEX{}; ::SecureZeroMemory(&window_class, sizeof(window_class)); @@ -59,15 +49,6 @@ HWND MpvContainer::Get(HWND flutter_window) { ::SetWindowLongPtr(handle_, GWLP_USERDATA, reinterpret_cast(flutter_window)); - // Remove taskbar entry using cached ITaskbarList3. - if (!taskbar_) { - ::CoCreateInstance(CLSID_TaskbarList, 0, CLSCTX_INPROC_SERVER, - IID_PPV_ARGS(&taskbar_)); - } - if (taskbar_) { - taskbar_->DeleteTab(handle_); - } - ::ShowWindow(handle_, SW_SHOWNOACTIVATE); ::SetFocus(flutter_window); @@ -83,12 +64,13 @@ LRESULT CALLBACK MpvContainer::WindowProc(HWND const window, ::PostQuitMessage(0); return 0; } - case WM_MOUSEMOVE: { + case WM_MOUSEMOVE: + case WM_SIZE: + case WM_MOVE: + case WM_MOVING: + case WM_ACTIVATE: + case WM_WINDOWPOSCHANGED: { // Redirect focus to Flutter window. - auto* core = MpvCore::GetInstance(); - if (core) { - core->SetHitTestBehavior(0); - } auto user_data = ::GetWindowLongPtr(window, GWLP_USERDATA); if (user_data) { ::SetForegroundWindow(reinterpret_cast(user_data)); @@ -99,21 +81,6 @@ LRESULT CALLBACK MpvContainer::WindowProc(HWND const window, // Prevent erasing to avoid flicker. return 1; } - case WM_SIZE: - case WM_MOVE: - case WM_MOVING: - case WM_ACTIVATE: - case WM_WINDOWPOSCHANGED: { - auto* core = MpvCore::GetInstance(); - if (core) { - core->SetHitTestBehavior(0); - } - auto user_data = ::GetWindowLongPtr(window, GWLP_USERDATA); - if (user_data) { - ::SetForegroundWindow(reinterpret_cast(user_data)); - } - break; - } default: break; } diff --git a/windows/runner/mpv/mpv_container.h b/windows/runner/mpv/mpv_container.h index e071315b..1fd75534 100644 --- a/windows/runner/mpv/mpv_container.h +++ b/windows/runner/mpv/mpv_container.h @@ -1,16 +1,12 @@ #ifndef MPV_CONTAINER_H_ #define MPV_CONTAINER_H_ -#include #include #include namespace mpv { -// Forward declaration -class MpvCore; - // Container window that holds the mpv video window behind Flutter. // This is a singleton that creates a hidden window with no taskbar entry. class MpvContainer { @@ -18,7 +14,7 @@ class MpvContainer { static MpvContainer* GetInstance(); MpvContainer() = default; - ~MpvContainer(); + ~MpvContainer() = default; // Creates the container window. HWND Create(); @@ -34,7 +30,6 @@ class MpvContainer { LPARAM lparam) noexcept; HWND handle_ = nullptr; - ITaskbarList3* taskbar_ = nullptr; static constexpr wchar_t kClassName[] = L"MPV_CONTAINER"; static constexpr wchar_t kWindowName[] = L""; diff --git a/windows/runner/mpv/mpv_core.cpp b/windows/runner/mpv/mpv_core.cpp index b34148c0..c787f196 100644 --- a/windows/runner/mpv/mpv_core.cpp +++ b/windows/runner/mpv/mpv_core.cpp @@ -13,13 +13,8 @@ void MpvCore::SetInstance(std::unique_ptr instance) { instance_ = std::move(instance); } -std::optional MpvCore::GetProcId() { return proc_id_; } - -void MpvCore::SetProcId(std::optional proc_id) { proc_id_ = proc_id; } - -MpvCore::MpvCore(HWND flutter_window, HWND flutter_child_window) - : flutter_window_(flutter_window), - flutter_child_window_(flutter_child_window) {} +MpvCore::MpvCore(HWND flutter_window) + : flutter_window_(flutter_window) {} MpvCore::~MpvCore() { // Close all mpv views. @@ -71,24 +66,6 @@ void MpvCore::DisposeMpvView(HWND mpv_hwnd) { mpv_views_.erase(mpv_hwnd); } -void MpvCore::SetHitTestBehavior(int32_t hittest_behavior) { - LONG ex_style = ::GetWindowLong(flutter_window_, GWL_EXSTYLE); - if (hittest_behavior) { - ex_style |= (WS_EX_TRANSPARENT | WS_EX_LAYERED); - } else { - ex_style &= ~(WS_EX_TRANSPARENT | WS_EX_LAYERED); - } - ::SetWindowLong(flutter_window_, GWL_EXSTYLE, ex_style); - - // Force Windows to recalculate window frame after extended style changes. - // This ensures the render surface dimensions match the new window state. - ::SetWindowPos(flutter_window_, nullptr, 0, 0, 0, 0, - SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); - - // Sync with DWM to ensure render target is updated - ::DwmFlush(); -} - void MpvCore::SetVisible(bool visible) { visible_ = visible; if (container_) { @@ -173,8 +150,6 @@ std::optional MpvCore::WindowProc(HWND hwnd, UINT message, } break; } - case WM_MOVE: - case WM_MOVING: case WM_WINDOWPOSCHANGED: { RECT window_rect; ::GetWindowRect(flutter_window_, &window_rect); @@ -209,10 +184,6 @@ std::optional MpvCore::WindowProc(HWND hwnd, UINT message, return std::nullopt; } -void MpvCore::RedrawMpvViews() { - ::RedrawWindow(container_, 0, 0, RDW_INVALIDATE | RDW_ALLCHILDREN); -} - RECT MpvCore::GetGlobalRect(int32_t left, int32_t top, int32_t right, int32_t bottom) { // Expand client area to prevent transparent gaps. @@ -232,6 +203,5 @@ RECT MpvCore::GetGlobalRect(int32_t left, int32_t top, int32_t right, } std::unique_ptr MpvCore::instance_ = nullptr; -std::optional MpvCore::proc_id_ = std::nullopt; } // namespace mpv diff --git a/windows/runner/mpv/mpv_core.h b/windows/runner/mpv/mpv_core.h index 945d153c..0deab605 100644 --- a/windows/runner/mpv/mpv_core.h +++ b/windows/runner/mpv/mpv_core.h @@ -19,10 +19,8 @@ class MpvCore { static MpvCore* GetInstance(); static void SetInstance(std::unique_ptr instance); - static std::optional GetProcId(); - static void SetProcId(std::optional proc_id); - MpvCore(HWND flutter_window, HWND flutter_child_window); + explicit MpvCore(HWND flutter_window); ~MpvCore(); // Initializes transparency on the Flutter window. @@ -37,9 +35,6 @@ class MpvCore { // Disposes the mpv view. void DisposeMpvView(HWND mpv_hwnd); - // Sets hit test behavior for mouse passthrough. - void SetHitTestBehavior(int32_t hittest_behavior); - // Shows or hides the mpv view. void SetVisible(bool visible); @@ -48,11 +43,9 @@ class MpvCore { LPARAM lparam); private: - void RedrawMpvViews(); RECT GetGlobalRect(int32_t left, int32_t top, int32_t right, int32_t bottom); HWND flutter_window_ = nullptr; - HWND flutter_child_window_ = nullptr; HWND container_ = nullptr; double device_pixel_ratio_ = 1.0; std::map mpv_views_; @@ -62,7 +55,6 @@ class MpvCore { bool composition_enabled_ = false; static std::unique_ptr instance_; - static std::optional proc_id_; }; } // namespace mpv diff --git a/windows/runner/mpv/mpv_player.cpp b/windows/runner/mpv/mpv_player.cpp index c9c076eb..0dd82041 100644 --- a/windows/runner/mpv/mpv_player.cpp +++ b/windows/runner/mpv/mpv_player.cpp @@ -1,7 +1,6 @@ #include "mpv_player.h" #include -#include #include // Sanitize a C string that may contain invalid UTF-8 sequences. @@ -44,16 +43,6 @@ static std::string SanitizeUtf8(const char* input) { return result; } -static void LogToFile(const char* message) { - std::ofstream log("C:\\Users\\admin\\mpv_debug.log", std::ios::app); - if (log.is_open()) { - log << message << std::endl; - log.close(); - } - OutputDebugStringA(message); - OutputDebugStringA("\n"); -} - namespace mpv { MpvPlayer::MpvPlayer() {} @@ -61,56 +50,34 @@ MpvPlayer::MpvPlayer() {} MpvPlayer::~MpvPlayer() { Dispose(); } bool MpvPlayer::Initialize(HWND container, HWND flutter_window) { - LogToFile("MpvPlayer::Initialize called"); - if (mpv_) { - LogToFile("MpvPlayer::Initialize - already initialized"); return true; // Already initialized. } container_ = container; flutter_window_ = flutter_window; - char msg[256]; - snprintf(msg, sizeof(msg), "MpvPlayer::Initialize - container: %p", container); - LogToFile(msg); // Create mpv instance. - LogToFile("MpvPlayer::Initialize - calling mpv_create()"); mpv_ = mpv_create(); if (!mpv_) { - LogToFile("MPV: mpv_create() failed"); return false; } - LogToFile("MpvPlayer::Initialize - mpv_create() succeeded"); // Create a child window for mpv to render into. - LogToFile("MpvPlayer::Initialize - creating child window"); hwnd_ = ::CreateWindowW(L"STATIC", L"", WS_CHILD | WS_VISIBLE, 0, 0, 100, 100, container, nullptr, GetModuleHandle(nullptr), nullptr); if (!hwnd_) { - DWORD error = GetLastError(); - snprintf(msg, sizeof(msg), "MPV: CreateWindowW failed with error %lu", error); - LogToFile(msg); mpv_destroy(mpv_); mpv_ = nullptr; return false; } - snprintf(msg, sizeof(msg), "MpvPlayer::Initialize - child window created: %p", hwnd_); - LogToFile(msg); // Set the wid option to embed mpv in our window. int64_t wid = reinterpret_cast(hwnd_); - int err = mpv_set_option(mpv_, "wid", MPV_FORMAT_INT64, &wid); - if (err < 0) { - snprintf(msg, sizeof(msg), "MPV: Failed to set wid option: %d %s", err, mpv_error_string(err)); - LogToFile(msg); - } else { - LogToFile("MpvPlayer::Initialize - wid option set successfully"); - } + mpv_set_option(mpv_, "wid", MPV_FORMAT_INT64, &wid); // Configure mpv for embedded playback. - LogToFile("MpvPlayer::Initialize - setting mpv options"); // Use gpu-next + Vulkan to avoid D3D11 driver crashes (GH-653) mpv_set_option_string(mpv_, "vo", "gpu-next"); mpv_set_option_string(mpv_, "gpu-api", "vulkan"); @@ -132,12 +99,8 @@ bool MpvPlayer::Initialize(HWND container, HWND flutter_window) { mpv_request_log_messages(mpv_, "warn"); // Initialize mpv. - LogToFile("MpvPlayer::Initialize - calling mpv_initialize()"); - err = mpv_initialize(mpv_); + int err = mpv_initialize(mpv_); if (err < 0) { - snprintf(msg, sizeof(msg), "MPV: mpv_initialize() failed with error %d: %s", - err, mpv_error_string(err)); - LogToFile(msg); ::DestroyWindow(hwnd_); hwnd_ = nullptr; mpv_destroy(mpv_); @@ -145,14 +108,11 @@ bool MpvPlayer::Initialize(HWND container, HWND flutter_window) { return false; } - LogToFile("MPV: Initialization successful"); - // Observe video-params/sig-peak for HDR detection mpv_observe_property(mpv_, 0, "video-params/sig-peak", MPV_FORMAT_DOUBLE); // Start event loop. StartEventLoop(); - LogToFile("MpvPlayer::Initialize - event loop started"); return true; } @@ -523,9 +483,6 @@ void MpvPlayer::SendEvent(const std::string& name, void MpvPlayer::SetHDREnabled(bool enabled) { hdr_enabled_ = enabled; - char msg[128]; - snprintf(msg, sizeof(msg), "[MpvPlayer] HDR enabled: %s", enabled ? "true" : "false"); - LogToFile(msg); if (mpv_) { mpv_set_property_string(mpv_, "target-colorspace-hint", enabled ? "yes" : "no"); @@ -535,16 +492,6 @@ void MpvPlayer::SetHDREnabled(bool enabled) { } void MpvPlayer::UpdateHDRMode(double sigPeak) { - bool isHDRContent = sigPeak > 1.0; - - char msg[256]; - snprintf(msg, sizeof(msg), - "[MpvPlayer] HDR mode update (hdrEnabled: %s, sigPeak: %.2f, isHDR: %s)", - hdr_enabled_ ? "true" : "false", - sigPeak, - isHDRContent ? "true" : "false"); - LogToFile(msg); - // On Windows, mpv handles HDR passthrough automatically when: // - target-colorspace-hint=yes // - Windows HDR is enabled in Display Settings diff --git a/windows/runner/mpv/mpv_plugin.cpp b/windows/runner/mpv/mpv_plugin.cpp index e28327af..7aec4fe5 100644 --- a/windows/runner/mpv/mpv_plugin.cpp +++ b/windows/runner/mpv/mpv_plugin.cpp @@ -1,27 +1,13 @@ #include "mpv_plugin.h" -#include - #include "mpv_container.h" #include "mpv_core.h" -static void LogToFile(const char* message) { - std::ofstream log("C:\\Users\\admin\\mpv_debug.log", std::ios::app); - if (log.is_open()) { - log << message << std::endl; - log.close(); - } - OutputDebugStringA(message); - OutputDebugStringA("\n"); -} - void MpvPlayerPluginRegisterWithRegistrar( FlutterDesktopPluginRegistrarRef registrar) { - LogToFile("MpvPlayerPlugin: RegisterWithRegistrar called"); mpv::MpvPlayerPlugin::RegisterWithRegistrar( flutter::PluginRegistrarManager::GetInstance() ->GetRegistrar(registrar)); - LogToFile("MpvPlayerPlugin: RegisterWithRegistrar completed"); } namespace mpv { @@ -34,22 +20,14 @@ void MpvPlayerPlugin::RegisterWithRegistrar( MpvPlayerPlugin::MpvPlayerPlugin(flutter::PluginRegistrarWindows* registrar) : registrar_(registrar) { - LogToFile("MpvPlayerPlugin: Constructor called"); - // Create method channel. method_channel_ = std::make_unique>( registrar->messenger(), "com.plezy/mpv_player", &flutter::StandardMethodCodec::GetInstance()); - LogToFile("MpvPlayerPlugin: Method channel created"); - method_channel_->SetMethodCallHandler( [this](const auto& call, auto result) { - char msg[256]; - snprintf(msg, sizeof(msg), "MpvPlayerPlugin: Method call received: %s", - call.method_name().c_str()); - LogToFile(msg); HandleMethodCall(call, std::move(result)); }); @@ -100,8 +78,6 @@ void MpvPlayerPlugin::HandleMethodCall( const auto& method = method_call.method_name(); if (method == "initialize") { - LogToFile("MPV Plugin: initialize called"); - // Set up MpvCore for z-order management. if (proc_id_) { registrar_->UnregisterTopLevelWindowProcDelegate(proc_id_.value()); @@ -109,15 +85,9 @@ void MpvPlayerPlugin::HandleMethodCall( } HWND flutter_window = GetWindow(); - HWND child_window = GetChildWindow(); - - char msg[256]; - snprintf(msg, sizeof(msg), "MPV Plugin: Flutter window: %p, Child window: %p", - flutter_window, child_window); - LogToFile(msg); MpvCore::SetInstance( - std::make_unique(flutter_window, child_window)); + std::make_unique(flutter_window)); proc_id_ = registrar_->RegisterTopLevelWindowProcDelegate( [](HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { @@ -128,27 +98,20 @@ void MpvPlayerPlugin::HandleMethodCall( return std::optional(std::nullopt); }); - LogToFile("MPV Plugin: Calling EnsureInitialized"); MpvCore::GetInstance()->EnsureInitialized(); // Create player - use the container from MpvCore which was set up by EnsureInitialized player_ = std::make_unique(); HWND container = MpvContainer::GetInstance()->handle(); - snprintf(msg, sizeof(msg), "MPV Plugin: Container handle: %p", container); - LogToFile(msg); - if (!container) { - LogToFile("MPV Plugin: ERROR - container is null"); result->Error("INIT_FAILED", "Failed to create container window"); return; } - LogToFile("MPV Plugin: Initializing player"); bool success = player_->Initialize(container, flutter_window); if (success) { - LogToFile("MPV Plugin: Player initialized successfully"); // Set up event callback. player_->SetEventCallback([this](const flutter::EncodableValue& event) { SendEvent(event); @@ -162,7 +125,6 @@ void MpvPlayerPlugin::HandleMethodCall( MpvCore::GetInstance()->SetVisible(false); result->Success(flutter::EncodableValue(true)); } else { - OutputDebugStringA("MPV Plugin: Player initialization FAILED\n"); player_.reset(); // Clear the player so we don't have a half-initialized state result->Error("INIT_FAILED", "Failed to initialize MPV player"); }