Repository navigation
feat(grabandmove): snap windows to screen edges and corners while dragging - #50245
James Martin (jjamesmartiin) wants to merge 1 commit into
Conversation
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
|
@microsoft-github-policy-service agree |
699a952 to
d835ec5
Compare
|
Hi! I've put together a short (~30 second) screen recording that walks through the snapping behavior end-to-end: the new Settings toggle, snapping to a half at the left/right edge, snapping to a quarter at the corners, and maximizing at the top edge. Please let me know if there's anything else you'd like me to include or if you have any feedback on the behavior or the settings wording — happy to make changes. Thanks for taking a look! power-toys-grab-and-move-snapping-demo-10mb.mp4 |
d835ec5 to
309202e
Compare
|
Quick note: I ran clang-format against |
…gging Add release-to-edge-snap to GrabAndMove: - Arm edge-snap when dragging near the left/right/top work-area edge or a screen corner - Reuse the existing overlay to preview the target half/quarter/maximize region - On release: position the window directly into the half/quarter region (accounting for DWM frame bounds), or maximize at the top edge - Add snapToEdges setting (default on) with Settings UI toggle + localization
309202e to
822df24
Compare
|
Oh good point! I can try to get that added in. I also noticed that when you grab the window it doesn't bring the window to the front. Would this sort of behavior be OK to add as a toggle? (maybe some people are used to how it is now and would prefer to be able to keep it off?) |
This should be a closer related issue, not sure why it didn't appear in my first search. |
I also noticed it's not going to work on the snap assist, so I'll try to get it working too. |
|
Muyuan Li (@MuyuanMS) should I move this back to ready to merge and work on the FancyZones and Snap Assist in a separate PR? |
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
|
I've marked this PR as ready for review. I decided to scope out the remaining features—such as FancyZones integration, Snap Assistant support, and bringing windows to the front—which I'm still working on. I'll submit those in separate follow-up PRs once they are ready. |
This comment was marked as spam.
This comment was marked as spam.
Keep snap work off the low-level hook and preserve destination-monitor maximize/restore boundsSeverity: Affected code:
Problem: Release-time snap placement still runs in the Why it matters: A low-level hook is the wrong place for the final window move and maximize work because the callback is latency-sensitive and can be interrupted by the target app or a monitor transition. If the selected destination monitor is dropped, the final snap lands on the wrong monitor and restoring the maximized window can jump to the wrong workspace bounds. Suggested change:
Verification: Run the GrabAndMove Debug build and exercise a cross-monitor edge/corner drag followed by maximize and restore on a multi-monitor setup; confirm the final window stays on the chosen monitor and restore returns to the correct bounds without a stale jump. |
Recompute final snap bounds after the monitor/DPI transition and bound delayed focus restoreSeverity: Affected code:
Problem: The snap logic calculates the final side/corner bounds from the source monitor before the async monitor/DPI transition completes, and delayed focus restoration is not bounded to the active maximize target. That can leave a stale retry loop or restore the wrong foreground window after a drag that crosses monitors or changes DPI. Why it matters: A source-monitor margin calculation can be stale once the window moves to its destination monitor, and a non-bounded focus retry can keep a timer alive after the target has changed or hung. Both issues create visible drift or focus theft during edge/corner snap completion. Suggested change:
Verification: Run the GrabAndMove debug validation on a monitor/DPI-change scenario and confirm the final snap lands at the correct edge/corner and focus restoration stays bounded to the active target without a stale retry timer. |
|
Close PR due to long time inactivity - please reopen once ready |




Summary of the Pull Request
Adds release-to-edge window snapping to the GrabAndMove utility. When dragging windows using the modifier key (Alt/Win + Left Click), dragging near the left or right work-area edge previews and snaps the window to that screen half using direct window positioning. Dragging to a screen corner previews and snaps the window to that quarter, and dragging to the top work-area edge previews and maximizes the window.
PR Checklist
GrabAndMove_SnapToEdges.HeaderandGrabAndMove_SnapToEdges.DescriptiontoResources.resw.PowerToys.GrabAndMove.exe).Detailed Description of the Pull Request / Additional comments
Technical Implementation Details:
src/modules/GrabAndMove/GrabAndMove/main.cpp):ComputeSnapTarget()to calculate work-area boundaries (GetWorkAreaForPoint) and determine if the cursor is withinSNAP_EDGE_THRESHOLD(24px) of an edge or corner. Corners are checked first so quadrants take priority over the half-screen/maximize edge zones.RepositionOverlay) expands to preview the half-screen, quarter-screen, or full-screen target region with zeroed margins.SetWindowPos()so its visible frame (DWM extended frame bounds) matches the previewed half/quarter region, accounting for the invisible resize borders.ShowWindow(g_dragTarget, SW_MAXIMIZE).SnapToEdges(snapToEdgesbool property, defaulttrue) toGrabAndMoveProperties.cs.GrabAndMoveViewModel.csand UI toggle switch inGrabAndMovePage.xaml.Resources.resw(en-us).Validation Steps Performed
PowerToys.GrabAndMove.exewith explorer PID runner parameter.Alt+ left-click drag on target windows (e.g. Notepad, Edge, Command Prompt).Alt + Right-Clickwindow resize operations function normally without interference.Video Demonstration
power-toys-grab-and-move-snapping-demo-10mb.mp4