diff --git a/mods/taskbar-music-lounge.wh.cpp b/mods/taskbar-music-lounge.wh.cpp index 637f49457..b5c0c7535 100644 --- a/mods/taskbar-music-lounge.wh.cpp +++ b/mods/taskbar-music-lounge.wh.cpp @@ -1,12 +1,12 @@ // ==WindhawkMod== -// @id taskbar-music-lounge -// @name Taskbar Music Lounge +// @id taskbar-music-lounge +// @name Taskbar Music Lounge // @description A native-style music ticker with media controls. // @version 3.0 // @author Hashah2311 // @github https://github.com/Hashah2311 // @include explorer.exe -// @compilerOptions -lole32 -ldwmapi -lgdi32 -luser32 -lwindowsapp -lshcore -lgdiplus +// @compilerOptions -lole32 -ldwmapi -lgdi32 -luser32 -lwindowsapp -lshcore -lgdiplus -lshell32 // ==/WindhawkMod== // ==WindhawkModReadme== @@ -44,9 +44,12 @@ A media controller that uses Windows 11 native DWM styling for a seamless look. $name: Auto Theme - TextColor: 0xFFFFFF $name: Manual Text Color (Hex) -- BgOpacity: 0 - $name: Acrylic Tint Opacity (0-255). Keep 0 for pure glass. -*/ +- BgOpacity: 0 + $name: Acrylic Tint Opacity (0-255). Keep 0 for pure glass. +- HideOnFullscreen: true + $name: Hide on Fullscreen + $description: Hide the widget when a fullscreen application is active. +*/ // ==/WindhawkModSettings== #include @@ -140,16 +143,17 @@ typedef BOOL(WINAPI* pSetWindowBand)(HWND hWnd, HWND hwndInsertAfter, DWORD dwBa typedef BOOL(WINAPI* pGetWindowBand)(HWND hWnd, PDWORD pdwBand); // --- Configurable State --- -struct ModSettings { - int width = 300; - int height = 48; - int fontSize = 11; - int offsetX = 12; - int offsetY = 0; - bool autoTheme = true; - DWORD manualTextColor = 0xFFFFFFFF; - int bgOpacity = 0; -} g_Settings; +struct ModSettings { + int width = 300; + int height = 48; + int fontSize = 11; + int offsetX = 12; + int offsetY = 0; + bool autoTheme = true; + DWORD manualTextColor = 0xFFFFFFFF; + int bgOpacity = 0; + bool hideOnFullscreen = true; +} g_Settings; // --- Global State --- HWND g_hMediaWindow = NULL; @@ -189,15 +193,60 @@ void LoadSettings() { } g_Settings.manualTextColor = 0xFF000000 | textRGB; - g_Settings.bgOpacity = Wh_GetIntSetting(L"BgOpacity"); - if (g_Settings.bgOpacity < 0) g_Settings.bgOpacity = 0; - if (g_Settings.bgOpacity > 255) g_Settings.bgOpacity = 255; - - if (g_Settings.width < 100) g_Settings.width = 300; - if (g_Settings.height < 24) g_Settings.height = 48; -} - -// --- WinRT / GSMTC --- + g_Settings.bgOpacity = Wh_GetIntSetting(L"BgOpacity"); + if (g_Settings.bgOpacity < 0) g_Settings.bgOpacity = 0; + if (g_Settings.bgOpacity > 255) g_Settings.bgOpacity = 255; + + g_Settings.hideOnFullscreen = Wh_GetIntSetting(L"HideOnFullscreen") != 0; + + if (g_Settings.width < 100) g_Settings.width = 300; + if (g_Settings.height < 24) g_Settings.height = 48; +} + +// --- Fullscreen Detection --- +bool IsFullscreenAppRunning() { + // Method 1: Shell notification state (D3D games, presentations) + QUERY_USER_NOTIFICATION_STATE state; + if (SUCCEEDED(SHQueryUserNotificationState(&state))) { + if (state == QUNS_RUNNING_D3D_FULL_SCREEN || + state == QUNS_PRESENTATION_MODE) { + return true; + } + } + + // Method 2: Check if foreground window covers entire monitor + HWND hwndFg = GetForegroundWindow(); + if (!hwndFg || hwndFg == GetDesktopWindow() || hwndFg == g_hMediaWindow) { + return false; + } + + // Skip shell windows + WCHAR className[256]; + if (GetClassNameW(hwndFg, className, 256)) { + if (wcscmp(className, L"Shell_TrayWnd") == 0 || + wcscmp(className, L"WorkerW") == 0 || + wcscmp(className, L"Progman") == 0) { + return false; + } + } + + // Get monitor info + HMONITOR hMon = MonitorFromWindow(hwndFg, MONITOR_DEFAULTTONEAREST); + MONITORINFO mi = { sizeof(mi) }; + if (!GetMonitorInfo(hMon, &mi)) return false; + + // Get window rect + RECT rcWnd; + if (!GetWindowRect(hwndFg, &rcWnd)) return false; + + // Check if window covers entire monitor + return (rcWnd.left <= mi.rcMonitor.left && + rcWnd.top <= mi.rcMonitor.top && + rcWnd.right >= mi.rcMonitor.right && + rcWnd.bottom >= mi.rcMonitor.bottom); +} + +// --- WinRT / GSMTC --- GlobalSystemMediaTransportControlsSessionManager g_SessionManager = nullptr; Bitmap* StreamToBitmap(IRandomAccessStreamWithContentType const& stream) { @@ -410,16 +459,20 @@ void DrawMediaPanel(HDC hdc, int width, int height) { } // --- Window Procedure --- -#define IDT_POLL_MEDIA 1001 -#define IDT_ANIMATION 1002 -#define APP_WM_CLOSE WM_APP +#define IDT_POLL_MEDIA 1001 +#define IDT_ANIMATION 1002 +#define IDT_FULLSCREEN 1003 +#define APP_WM_CLOSE WM_APP LRESULT CALLBACK MediaWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { - case WM_CREATE: - UpdateAppearance(hwnd); // Apply DWM Rounding + Acrylic - SetTimer(hwnd, IDT_POLL_MEDIA, 1000, NULL); - return 0; + case WM_CREATE: + UpdateAppearance(hwnd); // Apply DWM Rounding + Acrylic + SetTimer(hwnd, IDT_POLL_MEDIA, 1000, NULL); + if (g_Settings.hideOnFullscreen) { + SetTimer(hwnd, IDT_FULLSCREEN, 100, NULL); // Fast polling for fullscreen + } + return 0; case WM_ERASEBKGND: return 1; @@ -453,15 +506,24 @@ LRESULT CALLBACK MediaWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) int taskbarHeight = rc.bottom - rc.top; int y = rc.top + (taskbarHeight / 2) - (g_Settings.height / 2) + g_Settings.offsetY; - RECT myRc; GetWindowRect(hwnd, &myRc); - if (myRc.left != x || myRc.top != y || - (myRc.right - myRc.left) != g_Settings.width || - (myRc.bottom - myRc.top) != g_Settings.height) { - SetWindowPos(hwnd, HWND_TOPMOST, x, y, g_Settings.width, g_Settings.height, SWP_NOACTIVATE); - } - } - } - else if (wParam == IDT_ANIMATION) { + RECT myRc; GetWindowRect(hwnd, &myRc); + if (myRc.left != x || myRc.top != y || + (myRc.right - myRc.left) != g_Settings.width || + (myRc.bottom - myRc.top) != g_Settings.height) { + SetWindowPos(hwnd, HWND_TOPMOST, x, y, g_Settings.width, g_Settings.height, SWP_NOACTIVATE); + } + } + + } + else if (wParam == IDT_FULLSCREEN) { + // Fast fullscreen detection (100ms) + if (g_Settings.hideOnFullscreen && IsFullscreenAppRunning()) { + if (IsWindowVisible(hwnd)) ShowWindow(hwnd, SW_HIDE); + } else { + if (!IsWindowVisible(hwnd)) ShowWindow(hwnd, SW_SHOWNOACTIVATE); + } + } + else if (wParam == IDT_ANIMATION) { if (g_IsScrolling) { if (g_ScrollWait > 0) { g_ScrollWait--;