You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
While dragging a window by holding left click, right click in the grid section you want to resize from, continue dragging left click to the grid section you want to resize to and press right click again or let go of left click.
Double click the quickbar icon to launch settings.
Settings are saved in %appdata%\TheGriddler\settings.json.
If you select the option to run at startup, it will make an entry in shell:startup.
For Developers
Prerequisites
Visual Studio 2022 or VS Code.
.NET 10.0 SDK.
Windows OS. Win32 API and WPF support are required.
Building the Project
Clone the repository.
Open a terminal in the project root.
Run the following commands:
dotnet build
dotnet run
To build a production executable to the publish folder:
Installs a low-level mouse hook (WH_MOUSE_LL) to capture mouse events globally across all windows. Exposes events for left/right button and mouse movement.
Singleton that manages user preferences. Persists to %appdata%\TheGriddler\settings.json, clamps grid dimensions, normalizes invalid settings, and implements INotifyPropertyChanged for reactive WPF bindings.
A transparent WPF window that covers the active monitor, renders the snap grid, tracks the selection rectangle, calculates physical pixel coordinates, and applies DPI compensation for cross-monitor snapping.
Settings UI for per-monitor grid dimensions, colors, dark mode, and run-on-startup.
Windows APIs Used
The Griddler relies heavily on Win32 APIs via P/Invoke to achieve system-wide window management. All API declarations are centralized in Core/NativeMethods.cs.
Gets the current module handle for hook installation.
Architecture & Design
Core Flow
Startup: App.xaml.cs initializes MainController and creates a system tray icon.
Hooking: GlobalHook installs a WH_MOUSE_LL hook to monitor all mouse events.
Drag Detection: When a right-click occurs while the left button is held, MainController checks if the foreground window is in a move/size loop using GetGUIThreadInfo.
Break Drag: If confirmed, WindowManager.BreakDragLoop sends WM_CANCELMODE and WM_LBUTTONUP to interrupt the native drag.
Overlay Display: A GridOverlay window covers the current monitor and shows a configurable grid.
Selection: Mouse movement updates the selection rectangle. On completion, Snap calculates target bounds in physical pixels.
Snapping: SetWindowPos moves and resizes the window to the selected grid cells. DPI compensation is applied for Per-Monitor DPI aware apps.
Design Principles
Separation of Concerns: UI logic in Views, native interop in Core, state in Models.
Reactive Settings: Settings implements INotifyPropertyChanged for automatic UI updates.
Validated Settings: Grid dimensions are clamped and invalid color values fall back to defaults.
Per-Monitor Support: Grid dimensions and DPI handling work across multi-monitor setups.
Minimal Footprint: Runs as a system tray app with no main window.
Credits
Created by derac.
Inspired by WindowGrid by Joshua Wilding.
About
The Griddler is a lightweight window management tool for Windows that allows you to snap windows to a configurable grid using your mouse. Inspired by WindowGrid.