From 9050dae3c7fa576f067dd39198265741d52becb4 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Sun, 9 Jul 2023 11:49:27 +0200 Subject: [PATCH] WIP: Refactor visible checkForFullScreenWindow Also add not working EVENT_SYSTEM_MINIMIZESTART event hook for even faster notifications. The old way suffers from only triggering the window is done with the minimize animation. --- ScreenPlayWallpaper/qml/MultimediaView.qml | 86 ++++++++----- ScreenPlayWallpaper/src/winwindow.cpp | 141 +++++++++++++-------- ScreenPlayWallpaper/src/winwindow.h | 2 + 3 files changed, 145 insertions(+), 84 deletions(-) diff --git a/ScreenPlayWallpaper/qml/MultimediaView.qml b/ScreenPlayWallpaper/qml/MultimediaView.qml index 49101516..efeb946b 100644 --- a/ScreenPlayWallpaper/qml/MultimediaView.qml +++ b/ScreenPlayWallpaper/qml/MultimediaView.qml @@ -11,14 +11,15 @@ Item { property bool fadeInDone: false onFillModeChanged: { // Convert Web based video modes to the limited Qt fillModes - if (fillMode === "cover" || fillMode === "stretch" || fillMode === "contain") { - return vo.fillMode = VideoOutput.Stretch; + if (fillMode === "cover" || fillMode === "stretch" + || fillMode === "contain") { + return vo.fillMode = VideoOutput.Stretch } if (fillMode === "fill") { - return vo.fillMode = VideoOutput.PreserveAspectFit; + return vo.fillMode = VideoOutput.PreserveAspectFit } if (fillMode === "scale_down") { - return vo.fillMode = VideoOutput.PreserveAspectCrop; + return vo.fillMode = VideoOutput.PreserveAspectCrop } } @@ -28,9 +29,10 @@ Item { property string source: Wallpaper.projectSourceFileAbsolute onSourceChanged: { // Qt 6.3 workaround - mediaPlayer.stop(); - mediaPlayer.source = Qt.resolvedUrl(root.source); - mediaPlayer.play(); + mediaPlayer.videoOutput = vo + mediaPlayer.stop() + mediaPlayer.source = Qt.resolvedUrl(root.source) + mediaPlayer.play() } // Add slight delay to give the multimedia @@ -40,24 +42,31 @@ Item { id: startTimer interval: 50 onTriggered: { - Wallpaper.requestFadeIn(); + Wallpaper.requestFadeIn() } } MediaPlayer { id: mediaPlayer onPlaybackStateChanged: { - if (mediaPlayer.playbackState == MediaPlayer.PlayingState && !fadeInDone) { - fadeInDone = true; + print("playbackState", mediaPlayer.playbackState) + if (mediaPlayer.playbackState == MediaPlayer.PlayingState + && !fadeInDone) { + fadeInDone = true startTimer.start() } } loops: root.loops ? MediaPlayer.Infinite : 1 - videoOutput: vo + //videoOutput: vo audioOutput: ao + Behavior on playbackRate { + NumberAnimation { duration: 100 } + } } VideoOutput { id: vo +// visible: false +// enabled: visible anchors.fill: parent } @@ -68,40 +77,57 @@ Item { } // Wait until Windows window animation is complete // before pausing the wallpaper - Timer { - id: pauseTimer - interval: 100 - onTriggered: { - mediaPlayer.pause() +// Timer { +// id: pauseTimer +// interval: 100 +// onTriggered: { +// mediaPlayer.pause() +// } +// } +// Timer { +// id: startTimerPauseWallpaper +// interval: 1000 +// onTriggered: { +// pauseTimer.start() +// } +// } - } - } Connections { function onFillModeChanged(fillMode) { if (fillMode === "stretch") { - vo.fillMode = VideoOutput.Stretch; - return; + vo.fillMode = VideoOutput.Stretch + return } if (fillMode === "fill") { - vo.fillMode = VideoOutput.PreserveAspectFit; - return; + vo.fillMode = VideoOutput.PreserveAspectFit + return } - if (fillMode === "contain" || fillMode === "cover" || fillMode === "scale-down") { - vo.fillMode = VideoOutput.PreserveAspectCrop; + if (fillMode === "contain" || fillMode === "cover" + || fillMode === "scale-down") { + vo.fillMode = VideoOutput.PreserveAspectCrop } } function onCurrentTimeChanged(currentTime) { - mediaPlayer.position = currentTime * mediaPlayer.duration; + mediaPlayer.position = currentTime * mediaPlayer.duration } function onVisualsPausedChanged(visualsPaused) { - if(!Wallpaper.isPlaying) - return - if(visualsPaused) - pauseTimer.start() - else +// if (!Wallpaper.isPlaying) +// return + print("visualsPaused",visualsPaused) + if (visualsPaused) { + //startTimerPauseWallpaper.start() + mediaPlayer.pause() + //mediaPlayer.playbackRate = 0.2 + //mediaPlayer.videoOutput = null + } else { + // Stop the timer first if + //startTimerPauseWallpaper.stop() mediaPlayer.play() + //mediaPlayer.playbackRate = 1 + //mediaPlayer.videoOutput = vo + } } target: Wallpaper diff --git a/ScreenPlayWallpaper/src/winwindow.cpp b/ScreenPlayWallpaper/src/winwindow.cpp index 0f2a375e..5608296e 100644 --- a/ScreenPlayWallpaper/src/winwindow.cpp +++ b/ScreenPlayWallpaper/src/winwindow.cpp @@ -29,11 +29,29 @@ BOOL WINAPI SearchForWorkerWindow(HWND hwnd, LPARAM lparam) return TRUE; } +HWND m_currentFullScreenWindow {}; HHOOK g_mouseHook; QPoint g_LastMousePosition { 0, 0 }; QPoint g_globalOffset { 0, 0 }; QQuickView* g_winGlobalHook = nullptr; +void CALLBACK WinEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime) +{ + if (hwnd == m_currentFullScreenWindow) + { + if (event == EVENT_SYSTEM_MINIMIZESTART) { + qDebug() << "EVENT_SYSTEM_MINIMIZESTART"; + // Your window is being minimized. + // Perform your checks here. + } + else if (event == EVENT_SYSTEM_MINIMIZEEND) { + qDebug() << "EVENT_SYSTEM_MINIMIZEEND"; + // Your window has been minimized. + // Perform your checks here. + } + } +} + /*! \brief Windows mouse callback. This hook then forwards the event to the Qt window. We must manually call a release event otherwise QML gets stuck. @@ -152,9 +170,22 @@ ScreenPlay::WallpaperExitCode WinWindow::start() // wallpaper than contain audio, see BaseWindow::setup(). if (activeScreensList().length() == 1) { if (checkWallpaperVisible()) { - m_checkForFullScreenWindowTimer.start(10); + m_checkForFullScreenWindowTimer.start(100); } } + hEventHook = SetWinEventHook( + EVENT_SYSTEM_MINIMIZESTART, // Event type range min + EVENT_SYSTEM_MINIMIZEEND, // Event type range max + NULL, // Handle to the DLL that contains the event + WinEventProc, // The callback that gets called when the event is raised + 0, // Process ID (0 for all processes) + 0, // Thread ID (0 for all threads) + WINEVENT_OUTOFCONTEXT // Flags + ); +// if (hEventHook != NULL) { +// UnhookWinEvent(hEventHook); +// hEventHook = NULL; +// } QTimer::singleShot(1000, this, [&]() { setupWindowMouseHook(); @@ -191,8 +222,8 @@ void WinWindow::destroyThis() } struct sEnumInfo { - int iIndex; - HMONITOR hMonitor; + int iIndex = 0; + HMONITOR hMonitor = nullptr; }; BOOL CALLBACK GetMonitorByIndex(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) @@ -413,38 +444,58 @@ void WinWindow::configureWindowGeometry() m_window.hide(); } -BOOL CALLBACK FindTheDesiredWnd(HWND hWnd, LPARAM lParam) +BOOL CALLBACK IsFullscreenOrMaximizedEnumProc(HWND hWnd, LPARAM lParam) { - DWORD dwStyle = (DWORD)GetWindowLong(hWnd, GWL_STYLE); - if ((dwStyle & WS_MAXIMIZE) != 0) { - *(reinterpret_cast(lParam)) = hWnd; - return false; // stop enumerating + if (IsWindowVisible(hWnd)) { + + char title[256]; + GetWindowTextA(hWnd, title, sizeof(title)); + QStringList ignoreWindow ={"ScreenPlayWallpaper","Windows Input Experience"}; + QString strTitle = QString::fromStdString(title); + + + if (!ignoreWindow.contains(strTitle)) { + // Check if the window is maximized + if (IsZoomed(hWnd)) { + *(bool*)lParam = true; + m_currentFullScreenWindow =hWnd; + //qInfo() << "IsZoomed true:" << strTitle; + return FALSE; // Stop enumerating + } + // Check if the window is fullscreen + else { + LONG_PTR style = GetWindowLongPtr(hWnd, GWL_STYLE); + LONG_PTR exstyle = GetWindowLongPtr(hWnd, GWL_EXSTYLE); + + bool isFullscreen = (style & WS_POPUP) != 0 && (style & WS_CHILD) == 0 && (exstyle & WS_EX_TOOLWINDOW) == 0; + if (isFullscreen) { + HMONITOR hMonitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST); + MONITORINFO mi = { sizeof(mi) }; + if (GetMonitorInfo(hMonitor, &mi)) { + RECT rcWindow; + GetWindowRect(hWnd, &rcWindow); + + // Check if the window covers the entire screen + isFullscreen = rcWindow.left == mi.rcMonitor.left && rcWindow.top == mi.rcMonitor.top + && rcWindow.right == mi.rcMonitor.right && rcWindow.bottom == mi.rcMonitor.bottom; + } + + if (isFullscreen) { + //qInfo() << "isFullscreen true:" << strTitle; + *(bool*)lParam = true; + m_currentFullScreenWindow =hWnd; + return FALSE; // Stop enumerating + } + } + } + } else { + + //qInfo() << "Skip ScreenPlayWallpaper"; + } } - return true; // keep enumerating + return TRUE; // Continue enumerating } -BOOL CALLBACK GetMonitorByHandle(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) -{ - Q_UNUSED(hdcMonitor) - Q_UNUSED(lprcMonitor) - - auto info = (sEnumInfo*)dwData; - if (info->hMonitor == hMonitor) - return FALSE; - ++info->iIndex; - return TRUE; -} - -int GetMonitorIndex(HMONITOR hMonitor) -{ - sEnumInfo info; - info.hMonitor = hMonitor; - - if (EnumDisplayMonitors(NULL, NULL, GetMonitorByHandle, (LPARAM)&info)) - return -1; - - return info.iIndex; -} /*! \brief This method is called via a fixed interval to detect if a window completely @@ -452,30 +503,12 @@ int GetMonitorIndex(HMONITOR hMonitor) */ void WinWindow::checkForFullScreenWindow() { + bool isFullscreenOrMaximized = false; + EnumWindows(IsFullscreenOrMaximizedEnumProc, (LPARAM)&isFullscreenOrMaximized); + if(isFullscreenOrMaximized != visualsPaused()) + qDebug() << "isFullscreenOrMaximized" << isFullscreenOrMaximized; - HWND hFoundWnd = nullptr; - EnumWindows(&FindTheDesiredWnd, reinterpret_cast(&hFoundWnd)); - - // True if one window has WS_MAXIMIZE - if (hFoundWnd != nullptr) { - DWORD dwFlags = 0; - HMONITOR monitor = MonitorFromWindow(hFoundWnd, dwFlags); - HMONITOR wallpaper = MonitorFromWindow(m_windowHandle, dwFlags); - int monitorIndex = GetMonitorIndex(monitor); - int wallpaperIndex = GetMonitorIndex(wallpaper); - // qDebug() << monitorIndex << wallpaperIndex; - - // If the window that has WS_MAXIMIZE is at the same monitor as this wallpaper - if (monitorIndex == wallpaperIndex) { - - setVisualsPaused(true); - } else { - setVisualsPaused(false); - } - - } else { - setVisualsPaused(false); - } + setVisualsPaused(isFullscreenOrMaximized); } /*! \brief Custom exit method to force a redraw of the window so that diff --git a/ScreenPlayWallpaper/src/winwindow.h b/ScreenPlayWallpaper/src/winwindow.h index 522ffcb0..8c4c3044 100644 --- a/ScreenPlayWallpaper/src/winwindow.h +++ b/ScreenPlayWallpaper/src/winwindow.h @@ -67,6 +67,8 @@ private: HWND m_windowHandle {}; HWND m_windowHandleWorker {}; QTimer m_checkForFullScreenWindowTimer; + HWINEVENTHOOK hEventHook; + QTimer m_reconfigureTimer; std::unique_ptr m_windowsDesktopProperties; };