From 2532a70aa2fb4065335a8a88086e54071bc792ba Mon Sep 17 00:00:00 2001 From: "tiago.coderia" Date: Sun, 21 Jun 2026 10:06:57 -0300 Subject: [PATCH 1/2] Prioritize Spotify session over browser media sessions --- mods/taskbar-music-lounge.wh.cpp | 98 ++++++++++++++++++++++++++------ 1 file changed, 80 insertions(+), 18 deletions(-) diff --git a/mods/taskbar-music-lounge.wh.cpp b/mods/taskbar-music-lounge.wh.cpp index 5a38b0c83d..5cfafa17bb 100644 --- a/mods/taskbar-music-lounge.wh.cpp +++ b/mods/taskbar-music-lounge.wh.cpp @@ -1,6 +1,6 @@ // ==WindhawkMod== -// @id taskbar-music-lounge -// @name Taskbar Music Lounge +// @id taskbar-music-lounge-fork +// @name Taskbar Music Lounge - Fork // @description A native-style music ticker with media controls. // @version 4.0.2 // @author Hashah2311 @@ -255,55 +255,117 @@ void UpdateMediaInfo() { if (!g_SessionManager) { g_SessionManager = GlobalSystemMediaTransportControlsSessionManager::RequestAsync().get(); } - if (!g_SessionManager) return; - // Iterate ALL sessions to find one that is actively PLAYING. - GlobalSystemMediaTransportControlsSession session = nullptr; - bool foundActive = false; + if (!g_SessionManager) + return; + GlobalSystemMediaTransportControlsSession session = nullptr; auto sessionsList = g_SessionManager.GetSessions(); + + // ====================================================== + // PRIORIDADE 1: SPOTIFY + // ====================================================== for (auto const& s : sessionsList) { + auto source = s.SourceAppUserModelId(); auto pb = s.GetPlaybackInfo(); - if (pb && pb.PlaybackStatus() == GlobalSystemMediaTransportControlsSessionPlaybackStatus::Playing) { - session = s; - foundActive = true; - break; + + if (pb && + pb.PlaybackStatus() == + GlobalSystemMediaTransportControlsSessionPlaybackStatus::Playing) + { + std::wstring sourceStr = source.c_str(); + + if (sourceStr.find(L"Spotify") != std::wstring::npos || + sourceStr.find(L"spotify") != std::wstring::npos) + { + session = s; + break; + } + } + } + + // ====================================================== + // PRIORIDADE 2: QUALQUER MÍDIA TOCANDO + // ====================================================== + if (!session) { + for (auto const& s : sessionsList) { + auto pb = s.GetPlaybackInfo(); + + if (pb && + pb.PlaybackStatus() == + GlobalSystemMediaTransportControlsSessionPlaybackStatus::Playing) + { + session = s; + break; + } } } - if (!foundActive) { + // ====================================================== + // PRIORIDADE 3: CURRENT SESSION + // ====================================================== + if (!session) { session = g_SessionManager.GetCurrentSession(); } + // ====================================================== + // ATUALIZA DADOS + // ====================================================== if (session) { auto props = session.TryGetMediaPropertiesAsync().get(); auto info = session.GetPlaybackInfo(); lock_guard guard(g_MediaState.lock); - + wstring newTitle = props.Title().c_str(); - if (newTitle != g_MediaState.title || g_MediaState.albumArt == nullptr) { - if (g_MediaState.albumArt) { delete g_MediaState.albumArt; g_MediaState.albumArt = nullptr; } + + if (newTitle != g_MediaState.title || g_MediaState.albumArt == nullptr) + { + if (g_MediaState.albumArt) { + delete g_MediaState.albumArt; + g_MediaState.albumArt = nullptr; + } + auto thumbRef = props.Thumbnail(); + if (thumbRef) { auto stream = thumbRef.OpenReadAsync().get(); g_MediaState.albumArt = StreamToBitmap(stream); } } + g_MediaState.title = newTitle; g_MediaState.artist = props.Artist().c_str(); - g_MediaState.isPlaying = (info.PlaybackStatus() == GlobalSystemMediaTransportControlsSessionPlaybackStatus::Playing); + g_MediaState.isPlaying = + (info.PlaybackStatus() == + GlobalSystemMediaTransportControlsSessionPlaybackStatus::Playing); + g_MediaState.hasMedia = true; - } else { + } + else { lock_guard guard(g_MediaState.lock); + g_MediaState.hasMedia = false; g_MediaState.title = L"No Media"; g_MediaState.artist = L""; - if (g_MediaState.albumArt) { delete g_MediaState.albumArt; g_MediaState.albumArt = nullptr; } + + if (g_MediaState.albumArt) { + delete g_MediaState.albumArt; + g_MediaState.albumArt = nullptr; + } } - } catch (...) { + } + catch (...) { lock_guard guard(g_MediaState.lock); + g_MediaState.hasMedia = false; + g_MediaState.title = L"No Media"; + g_MediaState.artist = L""; + + if (g_MediaState.albumArt) { + delete g_MediaState.albumArt; + g_MediaState.albumArt = nullptr; + } } } From c2c6cbeef28b6b09c3457ae074b34cdd6cb5cef0 Mon Sep 17 00:00:00 2001 From: "tiago.coderia" Date: Sun, 21 Jun 2026 10:29:58 -0300 Subject: [PATCH 2/2] fix: fixed player over youtube fullscreen videos, show only in desktop --- mods/taskbar-music-lounge.wh.cpp | 53 ++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/mods/taskbar-music-lounge.wh.cpp b/mods/taskbar-music-lounge.wh.cpp index 5cfafa17bb..77c557a038 100644 --- a/mods/taskbar-music-lounge.wh.cpp +++ b/mods/taskbar-music-lounge.wh.cpp @@ -539,6 +539,31 @@ void DrawMediaPanel(HDC hdc, int width, int height) { } } +bool IsFullscreenAppRunning() +{ + HWND fg = GetForegroundWindow(); + if (!fg) + return false; + + RECT rcWindow; + GetWindowRect(fg, &rcWindow); + + HMONITOR hMon = MonitorFromWindow(fg, MONITOR_DEFAULTTOPRIMARY); + + MONITORINFO mi{}; + mi.cbSize = sizeof(mi); + + if (!GetMonitorInfo(hMon, &mi)) + return false; + + RECT rcMonitor = mi.rcMonitor; + + return rcWindow.left <= rcMonitor.left && + rcWindow.top <= rcMonitor.top && + rcWindow.right >= rcMonitor.right && + rcWindow.bottom >= rcMonitor.bottom; +} + // --- Event Hook --- bool IsTaskbarWindow(HWND hwnd) { WCHAR cls[64]; @@ -623,15 +648,11 @@ LRESULT CALLBACK MediaWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) bool shouldHide = false; // 1. Check Fullscreen - if (g_Settings.hideFullscreen) { - QUERY_USER_NOTIFICATION_STATE state; - if (SUCCEEDED(SHQueryUserNotificationState(&state))) { - if (state == QUNS_BUSY || state == QUNS_RUNNING_D3D_FULL_SCREEN || state == QUNS_PRESENTATION_MODE) { - shouldHide = true; - } - } + if (g_Settings.hideFullscreen) + { + shouldHide = IsFullscreenAppRunning(); } - + // 2. Check Idle Timeout bool isPlaying = false; { @@ -701,11 +722,9 @@ LRESULT CALLBACK MediaWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) if (!g_IsHiddenByIdle && !IsWindowVisible(hwnd)) { // Double check fullscreen mode isn't forcing hide bool gameModeHide = false; - if (g_Settings.hideFullscreen) { - QUERY_USER_NOTIFICATION_STATE state; - if (SUCCEEDED(SHQueryUserNotificationState(&state))) { - if (state == QUNS_BUSY || state == QUNS_RUNNING_D3D_FULL_SCREEN || state == QUNS_PRESENTATION_MODE) gameModeHide = true; - } + if (g_Settings.hideFullscreen) + { + gameModeHide = IsFullscreenAppRunning(); } if (!gameModeHide) ShowWindow(hwnd, SW_SHOWNOACTIVATE); } @@ -724,7 +743,7 @@ LRESULT CALLBACK MediaWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) (myRc.bottom - myRc.top) != g_Settings.height) { SetWindowPos( hwnd, - HWND_TOPMOST, + HWND_NOTOPMOST, x, y, g_Settings.width, g_Settings.height, @@ -832,12 +851,12 @@ void MediaThread() { if (CreateWindowInBand) { g_hMediaWindow = CreateWindowInBand( - WS_EX_LAYERED | WS_EX_TOOLWINDOW | WS_EX_TOPMOST, + WS_EX_LAYERED | WS_EX_TOOLWINDOW, wc.lpszClassName, TEXT("MusicLounge"), WS_POPUP | WS_VISIBLE, 0, 0, g_Settings.width, g_Settings.height, NULL, NULL, wc.hInstance, NULL, - ZBID_IMMERSIVE_NOTIFICATION + ZBID_DESKTOP ); if (g_hMediaWindow) { Wh_Log(L"Created window in ZBID_IMMERSIVE_NOTIFICATION band"); @@ -847,7 +866,7 @@ void MediaThread() { if (!g_hMediaWindow) { Wh_Log(L"Falling back to CreateWindowEx"); g_hMediaWindow = CreateWindowEx( - WS_EX_LAYERED | WS_EX_TOOLWINDOW | WS_EX_TOPMOST, + WS_EX_LAYERED | WS_EX_TOOLWINDOW, wc.lpszClassName, TEXT("MusicLounge"), WS_POPUP | WS_VISIBLE, 0, 0, g_Settings.width, g_Settings.height,