Skip to content

Conversation

@Hashah2311
Copy link
Contributor

A sleek, pill-shaped music ticker for your Windows 11 taskbar. It sits unobtrusively in the corner, scrolling your current track and providing quick media controls.

A sleek, pill-shaped music ticker for your Windows 11 taskbar. It sits unobtrusively in the corner, scrolling your current track and providing quick media controls.
@m417z
Copy link
Member

m417z commented Nov 26, 2025

Thank you for the submission.

It doesn't look so well on a light theme:

image

Also, this mod has no good reason to run as part of explorer.exe, except that it's convenient. We discussed it here: #1916 (comment)

This mod is injected into explorer and runs as part of it. This is suboptimal for the following reasons:

  • There can be more than one explorer.exe process in case the "launch folder windows in separate process" option is enabled, and for other reasons.
  • This mod doesn't have a good reason to be injected into explorer.exe, it's just convenient. But by doing so, a mistake or instability in the mod affects the whole shell.

This is not the first mod to take this approach. Here are other recent mods:

And maybe also:

All three mods could be separate tools, they don't use and don't need Windhawk's injection and hooking capabilities. On the other hand, I can understand that the ease of mod installation is appealing. I wonder if Windhawk needs to come up with a new type of mods which run as part of a dedicated process.

Currently, Windhawk doesn't have a built-in functionality for something like that, but for now, I implemented some code that can be added to a mod to make it run as part of a separate windhawk.exe process:

Details

////////////////////////////////////////////////////////////////////////////////
// Windhawk tool mod implementation for mods which don't need to inject to other
// processes or hook other functions. Context:
// https://github.com/ramensoftware/windhawk-mods/pull/1916
//
// The mod will load and run in a dedicated windhawk.exe process.
//
// Paste the code below as part of the mod code, and use these callbacks:
// * WhTool_ModInit
// * WhTool_ModSettingsChanged
// * WhTool_ModUninit
//
// Currently, other callbacks are not supported.

bool g_isToolModProcessLauncher;
HANDLE g_toolModProcessMutex;

void WINAPI EntryPoint_Hook() {
    Wh_Log(L">");
    ExitThread(0);
}

BOOL Wh_ModInit() {
    bool isService = false;
    bool isToolModProcess = false;
    bool isCurrentToolModProcess = false;
    int argc;
    LPWSTR* argv = CommandLineToArgvW(GetCommandLine(), &argc);
    if (!argv) {
        Wh_Log(L"CommandLineToArgvW failed");
        return FALSE;
    }

    for (int i = 1; i < argc; i++) {
        if (wcscmp(argv[i], L"-service") == 0) {
            isService = true;
            break;
        }
    }

    for (int i = 1; i < argc - 1; i++) {
        if (wcscmp(argv[i], L"-tool-mod") == 0) {
            isToolModProcess = true;
            if (wcscmp(argv[i + 1], WH_MOD_ID) == 0) {
                isCurrentToolModProcess = true;
            }
            break;
        }
    }

    LocalFree(argv);

    if (isService) {
        return FALSE;
    }

    if (isCurrentToolModProcess) {
        g_toolModProcessMutex =
            CreateMutex(nullptr, TRUE, L"windhawk-tool-mod_" WH_MOD_ID);
        if (!g_toolModProcessMutex) {
            Wh_Log(L"CreateMutex failed");
            ExitProcess(1);
        }

        if (GetLastError() == ERROR_ALREADY_EXISTS) {
            Wh_Log(L"Tool mod already running (%s)", WH_MOD_ID);
            ExitProcess(1);
        }

        if (!WhTool_ModInit()) {
            ExitProcess(1);
        }

        IMAGE_DOS_HEADER* dosHeader =
            (IMAGE_DOS_HEADER*)GetModuleHandle(nullptr);
        IMAGE_NT_HEADERS* ntHeaders =
            (IMAGE_NT_HEADERS*)((BYTE*)dosHeader + dosHeader->e_lfanew);

        DWORD entryPointRVA = ntHeaders->OptionalHeader.AddressOfEntryPoint;
        void* entryPoint = (BYTE*)dosHeader + entryPointRVA;

        Wh_SetFunctionHook(entryPoint, (void*)EntryPoint_Hook, nullptr);
        return TRUE;
    }

    if (isToolModProcess) {
        return FALSE;
    }

    g_isToolModProcessLauncher = true;
    return TRUE;
}

void Wh_ModAfterInit() {
    if (!g_isToolModProcessLauncher) {
        return;
    }

    WCHAR currentProcessPath[MAX_PATH];
    switch (GetModuleFileName(nullptr, currentProcessPath,
                              ARRAYSIZE(currentProcessPath))) {
        case 0:
        case ARRAYSIZE(currentProcessPath):
            Wh_Log(L"GetModuleFileName failed");
            return;
    }

    WCHAR
    commandLine[MAX_PATH + 2 +
                (sizeof(L" -tool-mod \"" WH_MOD_ID "\"") / sizeof(WCHAR)) - 1];
    swprintf_s(commandLine, L"\"%s\" -tool-mod \"%s\"", currentProcessPath,
               WH_MOD_ID);

    HMODULE kernelModule = GetModuleHandle(L"kernelbase.dll");
    if (!kernelModule) {
        kernelModule = GetModuleHandle(L"kernel32.dll");
        if (!kernelModule) {
            Wh_Log(L"No kernelbase.dll/kernel32.dll");
            return;
        }
    }

    using CreateProcessInternalW_t = BOOL(WINAPI*)(
        HANDLE hUserToken, LPCWSTR lpApplicationName, LPWSTR lpCommandLine,
        LPSECURITY_ATTRIBUTES lpProcessAttributes,
        LPSECURITY_ATTRIBUTES lpThreadAttributes, WINBOOL bInheritHandles,
        DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory,
        LPSTARTUPINFOW lpStartupInfo,
        LPPROCESS_INFORMATION lpProcessInformation,
        PHANDLE hRestrictedUserToken);
    CreateProcessInternalW_t pCreateProcessInternalW =
        (CreateProcessInternalW_t)GetProcAddress(kernelModule,
                                                 "CreateProcessInternalW");
    if (!pCreateProcessInternalW) {
        Wh_Log(L"No CreateProcessInternalW");
        return;
    }

    STARTUPINFO si{
        .cb = sizeof(STARTUPINFO),
        .dwFlags = STARTF_FORCEOFFFEEDBACK,
    };
    PROCESS_INFORMATION pi;
    if (!pCreateProcessInternalW(nullptr, currentProcessPath, commandLine,
                                 nullptr, nullptr, FALSE, NORMAL_PRIORITY_CLASS,
                                 nullptr, nullptr, &si, &pi, nullptr)) {
        Wh_Log(L"CreateProcess failed");
        return;
    }

    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
}

void Wh_ModSettingsChanged() {
    if (g_isToolModProcessLauncher) {
        return;
    }

    WhTool_ModSettingsChanged();
}

void Wh_ModUninit() {
    if (g_isToolModProcessLauncher) {
        return;
    }

    WhTool_ModUninit();
    ExitProcess(0);
}

Please do the following:

  • Add the code above at the end of your mod code
  • Replace Wh_ModInit, Wh_ModSettingsChanged, Wh_ModUninit in your code to WhTool_*, e.g. WhTool_ModInit
  • Change the target process from explorer.exe to windhawk.exe

Please try it and let me know if it behaves as expected in all cases. If it is, let's adapt it. In the future, such functionality might become part of Windhawk.

@m417z m417z closed this Nov 26, 2025
@m417z m417z reopened this Nov 26, 2025
Code Refactor: 
- Relies on windhawk process instead of direct injection
- Added theme support
@Hashah2311
Copy link
Contributor Author

Hello! Thanks for your reply. I have implemented your suggested changes. Please check

@m417z
Copy link
Member

m417z commented Nov 27, 2025

Thanks. Why did you make changes in the code, such as replacing CreateProcessInternal with CreateProcess? It was written as is for a reason.

@Hashah2311
Copy link
Contributor Author

Sorry, my bad, I did that for my personal code understanding. I fixed it now.

*pResult = title;
return FALSE;
}
if (title.find(L"Spotify") != wstring::npos && title.find(L" - ") != wstring::npos) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly, the mod only supports YouTube Music and Spotify, it makes sense to mention it in the readme.

By the way, you might prefer using GlobalSystemMediaTransportControlsSessionManager for a universal solution. You can take a look at this pull request for a reference:
m417z/my-windhawk-mods#34

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly, the mod only supports YouTube Music and Spotify, it makes sense to mention it in the readme.

Noted, I will make the changes accordingly.

you might prefer using GlobalSystemMediaTransportControlsSessionManager for a universal solution.

I needed some advice regarding that, Implementing GSMTC in C++ requires using WinRT interfaces, wont this add significant complexity, new libraries, and potential stability issues??

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wont this add significant complexity

Depends on the implementation, generally it shouldn't.

new libraries

Sure, but that shouldn't be an issue.

and potential stability issues

That, too, depends on the implementation, but the WinRT APIs themselves aren't unstable or something, they are used by Windows.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Also, I have another question, I want to use DWM native rounding which available only on Win11, should I use that or stay windows version neutral?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's up to you. Windows 11 has rounded design and Windows 10 doesn't so I think it'd be a good fit, but if you want to leave it up to the user to you can add an option for that.

g_Settings.offsetY = Wh_GetIntSetting(L"OffsetY");
g_Settings.autoTheme = Wh_GetIntSetting(L"AutoTheme") != 0;

PCWSTR textHex = Wh_GetStringSetting(L"TextColor");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A call to Wh_FreeStringSetting to free the string is missing, here and below.

@Anixx
Copy link
Contributor

Anixx commented Nov 27, 2025

Sorry, but I really wonder, if the mod affects only the taskbar and would be useless without Explorer running, is not it natural to run it inside Explorer.exe?...

@m417z
Copy link
Member

m417z commented Nov 27, 2025

The mod doesn't affect the taskbar in the technical sense. It acts like a separate app which creates a window and positions it on the screen. It so happens that it chooses to position it on top of the taskbar. It also means that there are quirks such as when too many taskbar items are opened, they appear beneath the music lounge window. Also, due to that technical design, it can run without Explorer and without the taskbar, it will just keep appearing at the corner of the screen.

@Anixx
Copy link
Contributor

Anixx commented Nov 27, 2025

Thanks, this clears it up.

@AlwaysBorderRadius
Copy link

Is this mod intended to be something similar to AudioBand and modern like FluentFlyout?
Because I would love to see it as part of Windhawk.

Added DWM and GSMTC Implementation for Win11
@Hashah2311
Copy link
Contributor Author

@m417z Hello! sorry for this delay and silence, I got busy with some work. I have made some changes as discussed; hope you like them!

It's up to you. Windows 11 has rounded design and Windows 10 doesn't so I think it'd be a good fit, but if you want to leave it up to the user to you can add an option for that.

I havent really implemented this part yet, I will think about it and maybe develop that too but maybe not right now.

Is this mod intended to be something similar to AudioBand and modern like FluentFlyout? Because I would love to see it as part of Windhawk.

@AlwaysBorderRadius I initially didnt plan for this, but now you got me interested🤔

@m417z
Copy link
Member

m417z commented Dec 10, 2025

I'll take a look later. Looks promising at a first glance over the code.

Just one thing I noticed for now: please restore the "Windhawk tool mod launcher code" area to the original code I posted. There are several mods using this code, and unless there's a good reason to change it, keeping it unified making it easier to manage.

@AlwaysBorderRadius
Copy link

@Hashah2311 Damn, you got me hyped now haha. I would love to see that become a reality!!!

* Replaced the topmost timer with notification Z-Band usage. Made the mod target explorer.exe and not windhawk.exe for it to work.
* Fixed the process failing to exit by clearing g_SessionManager in the right thread.
* Reverted to the original Windhawk tool mod code (mostly formatting and logs).
@m417z
Copy link
Member

m417z commented Dec 15, 2025

I played with the new version and it's really nice, well done! I made some small improvements:

  • Replaced the topmost timer with notification Z-Band usage. Made the mod target explorer.exe and not windhawk.exe for it to work.
  • Fixed the process failing to exit by clearing g_SessionManager in the right thread.
  • Reverted to the original Windhawk tool mod code (mostly formatting and logs).

I also made it so that the window can no longer be closed with Alt+F4.

I meant to post the changes as suggestions, but it ended up as a commit:
1547bdf

@Hashah2311 please take a look, let me know if the changes look good to you, and if there's anything else you'd like to change. If it looks good, I'll go ahead and merge it.

@Hashah2311
Copy link
Contributor Author

This looks perfect! lets merge it.

@m417z m417z merged commit 2eddf69 into ramensoftware:main Dec 17, 2025
4 checks passed
@SpacEagle17
Copy link

SpacEagle17 commented Dec 17, 2025

If it acts as a separate app, is it possible to exclude it in the Taskbar auto-hide when maximized mod? So far only excluding explorer.exe seems to do the trick.
image
The reason why I ask is because of this issue:

2025-12-17.18-28-14.1080p.mp4

----------------------

Also, since I use the Taskbar auto-hide speed mod, the hiding speed of the music player no longer matches the taskbar, so a setting to alter that would be appreciated, if at all possible :)

@m417z
Copy link
Member

m417z commented Dec 17, 2025

@SpacEagle17 probably the easiest way is to set an AppID to the mod's process, and then use it in "Taskbar auto-hide when maximized".

To set an AppID as "taskbar-music-lounge", add these two lines:

 #include <windows.h>
+#include <shobjidl.h>
 #include <shellapi.h>
 #include <dwmapi.h>
 #include <gdiplus.h>
 // --- CALLBACKS ---
 BOOL WhTool_ModInit() {
+    SetCurrentProcessExplicitAppUserModelID(L"taskbar-music-lounge");
     LoadSettings();
     g_Running = true;
     g_pMediaThread = new std::thread(MediaThread);

@Hashah2311 you might want to add it to the mod in the next update.

@SpacEagle17
Copy link

SpacEagle17 commented Dec 17, 2025

Works flawlessly! ty

And idk if this could be looked into, I kinda hid it below my issue report haha
image

@AlwaysBorderRadius
Copy link

I have been trying it for a while and I'm loving it, works great. Thanks guys for making it :)

There are a few suggestions I'd like to make to make it perfect (for me lol):

  • Rounded corners for the song portrait
  • An option to change the size of the media buttons. On a 4k display, they look super tiny, like 1/3 of the cursor.
imagen
  • An option to hide it (or to not to be always on top) when running apps at full screen like games
imagen

@m417z
Copy link
Member

m417z commented Dec 17, 2025

Also, since I use the Taskbar auto-hide speed mod, the hiding speed of the music player no longer matches the taskbar, so a setting to alter that would be appreciated, if at all possible :)

It was discussed here, you might want to try the proposed solution: 2eddf69#commitcomment-173045991

@SpacEagle17
Copy link

SpacEagle17 commented Dec 17, 2025

It was discussed here, you might want to try the proposed solution: 2eddf69#commitcomment-173045991

And once again, all changes mentioned there made this perfect! Yep those changes linked above and the AppUserModelID should for sure be in the next update of this mod! Works all as expected and perfectly!

Also, with the taskbar styler mod and a modified taskbar to make it narrower, for example the glass theme one does not even have to disable widgets (visible in my video shared earlier in this thread). Just wanted to mention that, as it was stated in the readme to be incompatible.

Just another report:
After restarting file explorer, the window no longer appears. One has to disable and enable the mod manually for it to appear again, which is unfortunate

@jed84
Copy link

jed84 commented Dec 18, 2025

That's a quite nice tool!

A few observations:

  • does not support AIMP and MPC-BE;
  • on 4k screen the icons are too small;
  • will be nice to have an option to hide when full-scree app is running

@Cinabutts
Copy link

Prerequisite: This is a continuation of my "Issue" here: #2828
I used Gemini 3 Pro Preview(so be cautious, but it seems fairly capable, I also have it cross reference multiple other mods just fyi)

Hey @Hashah2311, 1: I want to say if you haven't read the "issue" I created before, I am incredibly grateful for this mod man, I have been looking for something exactly like this as a Rainmeter skin and just wanted to say thank you and sorry if any of this sounds assertive or anything like im taking over your amazing work you likely spent a LOT more time into than me just doing this.
2: I am posting this here as I felt it might reach you sooner. Also in case the other users above see this that have posted about issues I may have fixed in my version.

Anyway, I've spent some time extensively reworking the mod, This version fixes a fair amount of issues others have experienced (like auto-hide lag and it remaining visible in fullscreen apps) and improves general stability.

Could you please review the code below and consider pushing it as an official update?

========================================================
Tested on: Windows 11 Pro Insider Preview Build 26100.ge_release.240331-1435

image Screenshot 2025-12-24 023003

Summary of changes:

To fix the Auto-Hide, Fullscreen, and High-DPI issues, the logic was overhauled from a "guessing" system to a "listening" system. Here is the breakdown:

  • Reworked Window Positioning & Smart Docking:

    • Core Sync: Replaced the timer-based positioning with a centralized SyncPositionWithTaskbar function driven by a WinEventHook. The widget now "listens" for the taskbar's exact movement coordinates, staying glued pixel-perfectly even during custom animations.
    • Smart Docking (Startup/Shutdown): Implemented a "Parked" state. On startup, shutdown, or if explorer.exe crashes, the widget unobtrusively "docks" to the bottom screen edge (2px visible) instead of floating at (0,0) or vanishing. It slides up automatically when the Taskbar is ready.
  • Integrated Multi-State Handling:

    • Smart "Game Mode" Detection: Implemented a passive hybrid system (OS Signal + Geometry Check) to detect D3D Fullscreen and Borderless games. This allows the widget to hide during games without triggering Anti-Cheat software.
    • Master Toggle: Added EnableGameDetection to completely disable the hiding logic if desired.
    • Bidirectional Transitions: Added a toggleable Slide Animation. The widget smoothly slides down off-screen when entering a game and slides back up when returning to the desktop.
    • App Whitelist: Added an IgnoredApps setting. This allows specific apps (like firefox.exe) to run in Fullscreen (F11) while keeping the widget visible.
  • Stability & Cleanup:

    • True High-DPI Support: Added dynamic ScaleTransform logic combined with SetProcessDpiAwarenessContext. The UI now automatically scales its size and text to look crisp and correctly proportioned on 4K/1440p monitors.
    • Settings Layout: Reorganized the settings menu to flow logically (Visuals -> Transitions -> Detection -> Exceptions).
    • Optimization: Modified the internal loops to reduce CPU overhead when idle.
    • Dependencies: Added -lshell32 and -lpsapi to the compiler options to support the new detection and whitelist features.

mod.wh.cpp.zip


Personal TODOs:
Here you'll find ideas I'll eventually work on with the same ai, whether the dev gets to em first is up to him, This is what I'll likely be working on next(obviously probably not all at once), Going in order of priority.

  • Replace the hex input "Manual Text Color" to allow RGB or possibly RGBA, For simplicity sake.(Also is this thing even working right? I can't find a hex online that comes out the same color lol)
  • Add rounded corners for Album cover. As requested by another user. I much agree.
  • Smarter game detection, ie if it knows I'm playing a game, keep that in memory for X seconds so that it doesn't hog up any resources(possibly unnecessary, idk how to judge the performance soo hard to tell)
  • The Smart docking feature via the Explorer crashing should possibly also be a toggle(Depending on user feedback). I realized this after the fact but to me it makes since as I mean it's in the name, Taskbar Music Lounge
  • Vertical taskbar support(requires possible full redesign, The current "Panel Width/Height" adds complexity to this.) Would like for this to be a simple toggle but in doing so it'd change the Panel Width/Height thus leading to a conundrum. Are these able to be overridden even?

@Hashah2311
Copy link
Contributor Author

Hey @Cinabutts and everyone,
Sorry for the lack of updates. I’ve been busy with academic work recently.
I’m carving out some time now to address the backlog. I really appreciate the modifications and comments you've all posted, it helps a ton. I'll do my best to get through them, but development might remain sporadic. Thanks for understanding!

@SpacEagle17
Copy link

If no media is playing it should also hide itself imho. I've implemented this change locally.

Hashah2311 added a commit to Hashah2311/windhawk-mods that referenced this pull request Dec 24, 2025
Major update: Comprehensive fixes for v4

This version addresses and incorporates multiple suggestions. A detailed diff table has been added to the README.

Addressed Issues & Fixes:
* [#3666395914](ramensoftware#2746 (comment))
* [#3666527577](ramensoftware#2746 (comment))
* [2eddf69](ramensoftware@2eddf69#commitcomment-173045991)
* [#3671818092](ramensoftware#2746 (comment))
* [ramensoftware#2828](ramensoftware#2828)
* [#3689038965](ramensoftware#2746 (comment))
* [#3690241518](ramensoftware#2746 (comment))

Credits:
Special thanks to @Cinabutts and @Deykii for code references and the community for testing.

Testing Note:
AIMP and MPC-BE integration is implemented but currently untested. Please report any issues with these players.
@Hashah2311
Copy link
Contributor Author

Check out the newest version v4.
I have tried to include all the fixes discussed here but if I missed anything, please let me know.
Thank you for trying out my mod!

@m417z

@m417z
Copy link
Member

m417z commented Dec 24, 2025

@Hashah2311 please create a new pull request.

@Cinabutts
Copy link

Cinabutts commented Dec 25, 2025

Hey @Hashah2311 thanks for pushing some of my code, here's my latest version if you're interested. It's main changes is regarding the background, in this version you are being able to set a custom background color when auto hide is off, or if you leave it default 0,0,0 it sticks with the original light/dark theme and i've added the option to invert the mods perceived mode.
NOTE: It is a bit clunky though. Could be better. And this version is still based on my own fork, not the updated version above fyi.

My next plan is to add a toggle-able slim progress bar at the top so when the mod auto hides it still shows this progress bar, thus in my mind helps negate the fact that when the taskbar is hidden via auto hide and the widget gets docked, when I hover over the widget it doesn't allow the taskbar to reappear.(maybe that'll be fixed in the later versions?)
This progress bar would always be visible whilst toggled on fyi so for instance I could see the progress in-game.

mod.wh.cpp.zip
EDIT/REUPLOAD: Fixed background RGB, was looking for BGR instead.

image image image

@SpacEagle17
Copy link

I personally don't think a progress bar for auto hiding is necessary at all. You can keep such changes for your local edit

@Cinabutts
Copy link

I personally don't think a progress bar for auto hiding is necessary at all. You can keep such changes for your local edit

probably right, in my mind it just makes since because when it's docked and the taskbar is hidden the widget as said is docked so it still shows a few pixels where it once was, hovering over this whilst auto-hide is on doesn't allow the taskbar to reappear, soo might as well make it useful i feel. but i get it. kinda visually distracting, thus why i said it'd be toggle-able.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants