Release notes
Changelog
Why this starts at 1.0.0. The Mac build has its own longer history and is further along in its
numbering. Windows starts its own version line at 1.0.0 rather than pretending to a past it doesn't have.
The two builds share a design and a license key, not a version number, and this Windows build has the
same 55 commands the Mac build had at the time of this port, not necessarily every command the Mac build
has gained since.
Mac changelog →
1.0.0
Beta
August 11, 2026
First Windows release: the Mac build's 55 commands and layout system, rebuilt on Win32 APIs rather than macOS ones, plus the engineering Windows itself demands that macOS never asked for.
Snapping
- Snap the focused window to a half, quarter, third, two-thirds, fourth, three-fourths or sixth with a keystroke (55 commands across 10 categories, every one of them rebindable).
- Cycle on repeat. Press
Ctrl+Alt+Left Arrowagain and again and the window steps ½ → ⅔ → ⅓ instead of sitting at a fixed half. The cycle is per-window and expires after 1.5 s, so snapping one window left and then pressing Left on another starts that one from a half rather than dropping it straight to two-thirds. - Maximize, Maximize Height, Maximize Width, Almost Maximize and Center (which keeps the window's size), plus Larger / Smaller and a nudge in any direction, by a step you set.
- Toggle Maximized replaces the Mac build's Toggle Full Screen. Windows has no per-window
full-screen API (an app's own
F11is internal to that app), so the honest equivalent is the real maximize state. Snapr's own Maximize stays a different thing on purpose: it fills the work area as an ordinary window, respects your gaps, and is undoable. - Undo, Redo and Restore for window positions, 50 deep per window, so a snap you didn't want is one keystroke back. Whole-desk operations record undo points too, so a Tile All or a layout restore comes back with the same key.
Layouts
- Save an arrangement of every window and put it back with one command.
- Auto-restore on dock / undock. The layout captured on that desk comes back by itself, 2.5 s after the display change settles. Windows spends a second or two rearranging windows itself when a monitor arrives or leaves, and restoring into the middle of that is a fight the OS wins.
- Layouts are stored as proportions, not pixels, so an arrangement captured on a 4K monitor restores correctly onto a laptop panel.
- Each layout remembers its desk by monitor hardware identity
(
EnumDisplayDevicesWwithEDD_GET_DEVICE_INTERFACE_NAME) as well as geometry.\\.\DISPLAY1is a slot, not a monitor: an identical 1920×1080 panel at home and at the office would otherwise hash the same and restore each other's layout. - If two saved layouts match the same desk, Snapr restores neither and says so in Settings. Guessing would rearrange twenty windows the wrong way every time you dock; doing nothing is recoverable.
- Windows that would land on the identical rectangle (what happens when a two-monitor layout is recalled on one screen) are cascaded down-and-right so every title bar stays reachable.
- Tile All arranges the windows on the monitor under your pointer into a grid that stays close to square. Scoped to one display on purpose: a command that rearranges a second monitor you weren't even looking at is the kind of surprise that gets an app uninstalled.
Drag-to-snap
- Drag a window toward an edge and a translucent preview shows exactly where it will land, gaps included, with the tile's name written across it, because a colored rectangle alone is genuinely ambiguous between "Left Two-Thirds" and "Center Third" on an ultrawide.
- The bottom edge is a thirds ruler: left third, left two-thirds, centre third, right two-thirds, right third as you move across. Windows' own edge snapping has no equivalent.
- The preview arms only once a window is actually being moved
(
EVENT_SYSTEM_MOVESIZESTART), so clicks and text selections never trigger it, and it polls the cursor at 60 Hz for the length of one drag rather than installing a low-level mouse hook that would stall every drag on the machine if Snapr ever paused.
Windows-specific engineering
- Windows are placed by their visible frame, read from
DWMWA_EXTENDED_FRAME_BOUNDS, notGetWindowRect, which includes the invisible resize border every top-level window has carried since Vista. Measured on a 200%-scale display, that border is (left 10, top 0, right 10, bottom 10) px: a left-half snap lands the visible frame at exactly (0, 0, 1710, 2050), identical torcWork's left half, where trustingGetWindowRectwould have been off by (-10, 0, +10, +10).SetWindowPospositions the outer rectangle, so every write is grown by the measured border, verified, and corrected once with fresh margins if it missed, which is what happens moving between monitors of different scale. - Per-monitor DPI awareness (
PROCESS_PER_MONITOR_DPI_AWARE_V2) is taken before any window exists, because Windows refuses a later call. Without it every coordinate on a mixed-DPI desk is virtualised and a perfectly correct tile calculation places the window wrong by exactly the scale ratio.--selfcheckreports the level actually granted; on the development machine,per-monitor-v2. - Tiles are computed against
MONITORINFO.rcWork, so a taskbar on any edge (and auto-hide) needs no special case anywhere in the codebase. A taskbar that moves, resizes or switches to auto-hide arrives asWM_SETTINGCHANGEand is treated as a desk change. Win+arrow belongs to Windows Snap, and Snapr will not take it. The shortcut editor refuses it with a reason, along withWin+Shift+arrow (move to next monitor),Ctrl+Win+arrow (virtual desktops),Win+Tab,Ctrl+Alt+Del,Ctrl+Shift+Esc,Alt+TabandAlt+F4.RegisterHotKeyfails for these, and an editor that accepts a binding the OS will never deliver is worse than one that refuses it.- AltGr is flagged, not ignored. On most non-US layouts
AltGrisCtrl+Alt, so aCtrl+Altshortcut on a letter or symbol takes over the character it would otherwise type: the€on a German or Polish keyboard. Snapr probes the active layout withVkKeyScanExWand flags the affected bindings in Settings. The arrow-key bindings are unaffected on every layout. - A binding another app already owns is reported, not silently dead: "In use by another
app." Verified by having a rival process take
Ctrl+Alt+Left: Snapr registered the other 28 bindings and named the one it could not take. - Windows on another virtual desktop are skipped. They present themselves as cloaked
(
DWMWA_CLOAKED) while still passingIsWindowVisible, so without that check a Tile All rearranges windows you cannot see on a desktop you are not looking at. - Apps running as administrator are named, not fumbled. Windows will not let a normal-integrity process reposition an elevated app's window; Snapr detects it up front by trying to open the process token (the same refusal that blocks the move) and says so. Snapr deliberately does not run elevated: an elevated window manager driven from the desktop is a far worse trade, and the per-user installer keeps it that way.
- A maximized window is restored before it is moved, because a maximized window ignores geometry writes and springs straight back to the full work area, the most confusing no-op a Windows tiler can have.
- Hotkeys, display-change notifications and the drag hook share one thread, one hidden window, one
message loop, because
RegisterHotKeybinds to the registering thread andSetWinEventHookto the pumping one.
Made yours
- Default keymap is
Ctrl+Alt(Rectangle's and the macOS build's), withCtrl+Alt+Shiftas the second tier: 29 factory bindings out of 55 commands. Sixths, fourths, three-fourths, Next/Previous Third, Maximize Width, the directional and absolute display moves and the whole-desk commands ship unbound, exactly as the Mac build does. - Display moves are on
Ctrl+Alt+Page Up/Page Downrather than the Mac build's third modifier tier, because on Windows every three-modifier chord includingWinis shell-reserved and every one that doesn't collides with the nudges. - Cheat sheet on
Ctrl+Alt+/: every command and its binding, over whatever you were doing. - Rebinding a combination another command owns takes it and unbinds the other. Unbinding a default survives a relaunch: cleared defaults are remembered, or the factory binding would simply reappear every launch.
- App ignore list for VMs, games and remote-desktop sessions, with an "Ignore the Frontmost App" tray item that resolves the app at click time.
- Configurable gaps with a live preview, adjustable nudge and resize steps, edge
sensitivity, settings import/export, launch at login (
HKCURunkey, per-user, no admin), and shortcut hints in the tray menu. - Prefs at
%APPDATA%\Snapr\prefs.json, layouts at%APPDATA%\Snapr\layouts.json, both written atomically, and a layouts file that has been corrupted is moved aside rather than silently overwritten.
It tells you when it can't
- No eligible window, an ignored app, a minimized window, a window that refuses to resize, an elevated app, "there's only one display", "nothing to undo": each is a short sentence rather than a shortcut that looks broken. A snap that worked says nothing at all: the window visibly moved, and a toast per keystroke in a keyboard app would be unbearable.
Accessibility, languages, packaging
- WCAG 2.1 AA in both light and dark, with Windows High Contrast honoured, checked statically against the real markup in the test suite.
- The shortcut recorder is a real
<button>: Enter or Space arms it, Escape cancels, Delete clears, and Tab always leaves, so it is not a keyboard trap. - Every binding is shown as words ("Ctrl+Alt+Left Arrow"), never a bare arrow glyph; Narrator gets "Control Alt Left Arrow", because it reads "+" as "plus". The snap-zone diagram is duplicated as a written list, and the picture is hidden from screen readers precisely because the list is not.
- 13 languages: English, Español, Français, Deutsch, Italiano, Português (Brasil), Nederlands, Polski, Русский, Türkçe, 日本語, 简体中文, 한국어. They follow the Windows UI-language list on Auto, with counted strings using real plural arrays (Russian and Polish need three forms; Japanese needs one).
- Settings window is pywebview/WebView2 over an embedded UI, booting on
pywebviewreadyrather thanload: WebView2 finishes the document before the API bridge is injected, so booting onloadis a race the app loses about as often as it wins. - Snapr lives in the notification area with no window at all until you open Settings, and the settings window is created hidden so it can appear instantly after days of running.
- Silent weekly update check with Authenticode-anchored self-update, business licensing (personal use free forever, one-time $5 per computer), and a per-user Inno Setup installer with no UAC prompt.
Known in this beta
- Development so far has run on a single physical display. The multi-monitor, dock/undock and mixed-DPI code paths are exercised through unit tests against simulated monitors (different scales, offsets and orientations, including restoring a two-monitor layout onto one screen), but not yet against real multi-monitor hardware. The geometry is tested; the hardware path is the thing this beta most needs checked. See the beta section.
- SmartScreen may still warn on first download despite the signature; reputation builds per file. See the install notes.
- No screen-reader pass with Narrator or NVDA has been done by a human yet. The accessibility work is tested structurally against the markup, but assistive technology has not driven the app end to end. If you use one, that feedback is the most valuable thing you could send.