Implement WM_APPCOMMAND hooks as a backup to keyboard hooks#482
Merged
Implement WM_APPCOMMAND hooks as a backup to keyboard hooks#482
Conversation
Contributor
There was a problem hiding this comment.
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
SHELLHOOKwindow 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-registerRegisterShellHookWindow(and re-acquireWM_SHELLHOOKif needed) onceWaitForExplorerReadyAsync()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); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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