Skip to content

fix(fancyzones): Prevent stuck drag state and key swallowing (#410)#7

Closed
crutkas wants to merge 3 commits into
mainfrom
fix-stuck-keys/a-fancyzones
Closed

fix(fancyzones): Prevent stuck drag state and key swallowing (#410)#7
crutkas wants to merge 3 commits into
mainfrom
fix-stuck-keys/a-fancyzones

Conversation

@crutkas

@crutkas crutkas commented Apr 13, 2026

Copy link
Copy Markdown
Owner

Summary

Fix FancyZones stuck drag state that permanently steals keyboard input (Shift+key combos and number keys).

Root Cause

When a window is destroyed mid-drag (Alt+F4, task kill, app crash), EVENT_SYSTEM_MOVESIZEEND never fires. The drag state machine stays in m_dragging = true permanently, causing:

  • All Shift+key combos swallowed — the LL hook returns 1 for any keystroke when Shift is held during IsDragging()
  • Number keys eatenquickLayoutSwitch fires on bare digit presses during (stuck) drag with no modifier requirement
  • Extra LL hooks stay installedGenericKeyHook and MouseButtonsHook remain active system-wide

Changes

A1: Subscribe to EVENT_OBJECT_DESTROY and clean up drag state

  • Add EVENT_OBJECT_DESTROY to the WinEvent subscription array
  • Route to WM_PRIV_WINDOWDESTROYED message handler
  • If destroyed window matches the dragged window (via GetDraggedWindow()), force MoveSizeEnd()
  • Make MoveSizeEnd() always disable dragging state even if m_windowMouseSnapper is null

A2: Narrow Shift+key swallowing to bare VK_SHIFT only

  • Change IsDragging() && shift to only suppress VK_LSHIFT / VK_RSHIFT themselves
  • Other Shift+key combos (Shift+A, Shift+1, etc.) now pass through during drag

A3: Require Win+Ctrl+Alt for quickLayoutSwitch during drag

  • Prevents bare number keys from triggering layout switches during stuck drag

A4: Tag SwallowKey SendInput with dwExtraInfo

How to Reproduce (before fix)

  1. Enable FancyZones with Shift-drag mode (default)
  2. Start dragging a Notepad window while holding Shift (zone overlay appears)
  3. Kill the Notepad process from Task Manager while still dragging
  4. Open a new Notepad and try typing Hello 123
  5. Bug: Number keys and Shift+key combos are eaten. Zone overlay stuck on screen.

How to Verify (after fix)

  1. Same steps — after kill, zone overlay disappears, typing works normally
  2. Normal Shift+drag still works end-to-end

Related Issues

PR Checklist

  • Builds clean on x64 Release
  • Manual verification per repro steps above

Comment thread src/modules/fancyzones/FancyZonesLib/FancyZones.cpp Fixed
Comment thread src/modules/fancyzones/FancyZonesLib/FancyZones.cpp Fixed
Comment thread src/modules/fancyzones/FancyZonesLib/FancyZonesWinHookEventIDs.cpp Fixed
Comment thread src/modules/fancyzones/FancyZonesLib/FancyZonesWinHookEventIDs.cpp Fixed
Comment thread src/modules/fancyzones/FancyZonesLib/FancyZonesWinHookEventIDs.h Fixed
@github-actions

This comment has been minimized.

@yeelam-gordon

Copy link
Copy Markdown

The EVENT_OBJECT_DESTROY path is the right primary fix for microsoft#410 cleanly handles Alt+F4 / app-crash mid-drag. Solid.

One coverage question: are there code paths where the dragged window survives but the user-physical-drag context is lost? A few that I think still leave m_dragging = true:

  • WTS_SESSION_LOCK / WM_WTSSESSION_CHANGE (user hits Win+L mid-drag)
  • Display configuration change (DPI / resolution / monitor add-remove while dragging across the seam)
  • Foreground steal via Win+Tab / UAC consent / focus-thief

If the destroy event doesn't fire in those, the LL hook will keep swallowing Shift-combos until the next drag completes. Probably out of scope here, but worth a follow-up issue.

crutkas and others added 2 commits June 12, 2026 15:31
- Subscribe to EVENT_OBJECT_DESTROY to clean up when dragged window
  dies mid-drag (root cause of microsoft#410)
- Only suppress bare Shift key during drag, not all Shift+key combos
- Require Win+Ctrl+Alt for quickLayoutSwitch during drag
- Tag SwallowKey SendInput with dwExtraInfo

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@crutkas crutkas force-pushed the fix-stuck-keys/a-fancyzones branch from b65f53a to 3393637 Compare June 12, 2026 22:51
@crutkas

crutkas commented Jun 12, 2026

Copy link
Copy Markdown
Owner Author

Rebased onto main and dropped the unrelated commits that had crept in, so this PR is now scoped to just the stuck-drag / key-swallowing fix.

Agreed that EVENT_OBJECT_DESTROY is the right hook for the core issue. The remaining gaps you called out — session lock (WTS_SESSION_LOCK), display/topology change, and a foreground steal mid-drag — are real but out of scope here; I'll track them in a follow-up issue rather than widen this PR.

(Also swapped the placeholder window-message identifier for a real GUID to match the rest of FancyZonesWinHookEventIDs.cpp.)

The EVENT_OBJECT_DESTROY win-event was subscribed and mapped to
WM_PRIV_WINDOWDESTROYED by the consumer, but FancyZonesApp's dispatch
switch had no case for it, so the event was dropped at default: break
and the stuck-drag fix never ran. Forward EVENT_OBJECT_DESTROY to the
callback alongside the other window-lifecycle events.

When the dragged window is destroyed mid-drag, the WM_PRIV_WINDOWDESTROYED
handler called MoveSizeEnd(), which snaps the now-dead HWND into a zone
and corrupts layout state. Abort the drag instead via a new
WindowMouseSnap::Abort() that tears down overlays/highlights/transparency
without snapping, then resets the snapper and disables dragging state.

Drop the redundant 'shift &&' term from the bare-Shift swallow: in a
WH_KEYBOARD_LL hook GetAsyncKeyState(VK_SHIFT) is not yet set on the
initial Shift-down, so the first press leaked through to the app. The
explicit VK_LSHIFT/VK_RSHIFT vkCode check already scopes this to the
bare Shift key.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@crutkas

crutkas commented Jun 13, 2026

Copy link
Copy Markdown
Owner Author

Superseded by the upstream PR against microsoft/PowerToys: microsoft#48569 (rebased onto current main, builds/tests verified). Closing this intra-fork review PR.

@crutkas crutkas closed this Jun 13, 2026
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.

FancyZones stuck active if window closes while dragging PowerToys steals my number keys!

3 participants