Skip to content

Implement WM_APPCOMMAND hooks as a backup to keyboard hooks#482

Merged
unchihugo merged 2 commits intomasterfrom
feat/wm_appcommands
Mar 16, 2026
Merged

Implement WM_APPCOMMAND hooks as a backup to keyboard hooks#482
unchihugo merged 2 commits intomasterfrom
feat/wm_appcommands

Conversation

@unchihugo
Copy link
Copy Markdown
Owner

@unchihugo unchihugo commented Mar 15, 2026

A quick, simple implementation of WM_APPCOMMAND hooks as an alternative to existing keyboard hooks (discussed in #466). Hooks to WM_SHELLHOOK to retrieve global WM_APPCOMMAND messages. No additional permissions required. Likely fixes #437

@github-actions github-actions bot added the MainWindow / Media Flyout Changes to MainWindow including the Media Flyout label Mar 15, 2026
@unchihugo unchihugo requested a review from Copilot March 15, 2026 15:03
@unchihugo unchihugo changed the title Implement WM_APPCOMMAND hooks as an alternative to keyboard hooks Implement WM_APPCOMMAND hooks as a backup to keyboard hooks Mar 15, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a WM_SHELLHOOK/HSHELL_APPCOMMAND-based path to trigger media flyouts from global WM_APPCOMMAND events, providing an alternative to the existing low-level keyboard hook approach discussed in #466 and intended to address regressions like #437.

Changes:

  • Register and handle the SHELLHOOK window message to detect WM_APPCOMMAND media/volume commands and show the media flyout.
  • Add Win32 constants and P/Invoke declarations for shell hook window registration/unregistration.
  • Update cleanup logic to deregister the shell hook window.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
FluentFlyoutWPF/MainWindow.xaml.cs Registers shell hook window and handles WM_SHELLHOOK/HSHELL_APPCOMMAND to show media flyouts.
FluentFlyoutWPF/Classes/NativeMethods.cs Adds HSHELL/APPCOMMAND constants and P/Invokes for RegisterShellHookWindow/DeregisterShellHookWindow.
Comments suppressed due to low confidence (1)

FluentFlyoutWPF/MainWindow.xaml.cs:1415

  • On Explorer restart (WM_TASKBARCREATED), shell hook registrations are typically lost along with other shell integrations. The recovery path currently recreates the tray icon but never re-registers the shell hook window, so WM_APPCOMMAND-based flyouts can stop working after an Explorer restart. Re-register RegisterShellHookWindow (and re-acquire WM_SHELLHOOK if needed) once WaitForExplorerReadyAsync() succeeds.
        else if (msg == WM_TASKBARCREATED)
        {
            Logger.Warn("Explorer restart detected (TaskbarCreated)");

            ExplorerRestarting = true;

            // Defer recovery, do NOT touch tray/taskbar immediately
            Dispatcher.BeginInvoke(async () =>
            {
                try
                {
                    // Wait for Explorer to actually stabilize
                    if (await WaitForExplorerReadyAsync())
                    {
                        ExplorerRestarting = false;
                        Logger.Info("Explorer stabilized, resuming taskbar integration");

                        // Now it is safe to recreate tray icon
                        RecreateTrayIconSafely();
                    }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +290 to +294
[LibraryImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool RegisterShellHookWindow(IntPtr hWnd);

[LibraryImport("user32.dll")]
Comment on lines 172 to +174
WM_TASKBARCREATED = RegisterWindowMessage("TaskbarCreated");
WM_SHELLHOOK = RegisterWindowMessage("SHELLHOOK");
RegisterShellHookWindow(new WindowInteropHelper(this).Handle);
@unchihugo unchihugo merged commit 5f5397a into master Mar 16, 2026
4 checks passed
@unchihugo unchihugo deleted the feat/wm_appcommands branch March 16, 2026 21:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

MainWindow / Media Flyout Changes to MainWindow including the Media Flyout

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Media Flyout no longer pops up when media is playing

2 participants