A window manager written in AutoHotkey v2.
Harken allows a keyboard-centered workflow on Windows: a single super modifier, mnemonic app keys, and fast window actions. Alt+Tab and Win+Tab still work, but you will hardly use them.
- Overview
- Quick Start
- Configuration
- Default Config Keys
- Window Matching
- Path Expansion
- Window Manager Exceptions
- Helper Utility
- Command Overlay
- Known Limitations
- Layout
- Third-Party
Note
CapsLock is the default super key, because who needs it?
- Launch-or-focus your most common programs with the hotkeys you assign in your config file.
- Focused tile includes border highlight that can be customized, including per app, window class, or window title.
- Snap tiles to grid and cycle through various positions with subsequent key presses.
- Freely move tiles with your keyboard.
- Resize tiles and their edges with your keyboard.
- Directional focus changes with vim-like motions.
- Cycle stacked tiles with
super + [andsuper + ]. - Cycle focus between tiles of the same program with
super + c. - Show a hotkey menu with
super + /. - Screen search hints with
super + .. - Virtual desktops (native)
- Navigate between desktops with better hotkeys
- Assign custom hotkeys for the index-based virtual desktops.
Launch-or-focus a program with super + [letter], or directionally change window focus with alt + h/l/j/k (left, right, down, up) and alt + [ / alt + ] for back/forward in a stack.

Cycle centered window widths with super + spacebar.

Maximizes/restores with super + m.

Move a window with super + h/j/k/l.

Freely move a window with double tap super + h/j/k/l

Resize edges with super + shift + h/j/k/l.

Show the Command Overlay when the super key is held. Disable through command mode.

Use the "window switcher" (like powertoys window walker) with super + w.

Other
super + altsendsctrl + tab(configurable viaglobal_hotkeys)super + ccycle through windows of the same appsuper + shift + ccycle through windows of the same app on the current desktopsuper + .screen search (click hints)super + alt + h/lswitch to previous/next virtual desktopsuper + alt + shift + h/lmove the active window to previous/next desktop (follow)super + wopen Window Selector (fuzzy find open windows)alt + h/lmove window focus left/rightalt + j/kmove window focus down/up (non-stacked)alt + [/alt + ]move window focus forward/back through stacked windowssuper + alt + h/lto move between desktopssuper + shift + alt + h/lsend current tile to adjacent desktop
Enter Command Mode with super + ;.
rto reload program/configeto open config filewopens a new window for the active program, if the program supports itgreapply app desktop assignmentsntoggles the command overlay on or offiopens the Helper Utility
- Clarify and work on areas of state
- saving layouts
- per app configs determining where things go (virtual desktop destination is supported now)
- Possibly rework the config schema. It's hectic.
- If not using the binary, make sure to install AutoHotKey 2.1-alpha18 or newer.
- Start the program and enter command mode with
super + ;. The binary is not currently signed and you will be warned by Windows. Clone and useharken.ahkdirectly as an alternative. - The program might fail on first run? Probably something to do with the config. For now you can create the config first to maybe avoid the initial-crash scenario.
- Press
eto open the config file. You can also find it manually in~/.config/harken/harken.tomlas it will be created on first run. - After making changes to your config you can reload (the entire program) with
rwhile in command mode.
App entries under apps can match windows via win_title or a match map. The match map accepts
exe, class, and title, plus *_regex = true to treat the value as a regex. You can also match
by process tree with match.process_tree, which checks for ancestor/descendant executables.
Use exclude_titles to ignore specific window titles for a given app. Each entry is a regex pattern
and the match is case-insensitive unless you include your own (?i) prefix.
[apps.editor]
hotkey = "v"
match = { exe = "Code.exe", title = " - Visual Studio Code$", title_regex = true }
exclude_titles = ["^Settings$", "^Welcome$"]Process tree matching can split apps that share the same window executable:
[[apps]]
id = "terminal"
hotkey = "s"
match = { exe = "alacritty.exe", process_tree = { mode = "descendant", exe = ["yazi.exe"], negate = true } }
[[apps]]
id = "yazi"
hotkey = "y"
match = { exe = "alacritty.exe", process_tree = { mode = "descendant", exe = ["yazi.exe"] } }Add debug = true under match.process_tree to log process tree details to
%APPDATA%\harken\process_tree.debug.log.
| Shortcut | Action |
|---|---|
super + / |
Show command overlay (temporary) |
super + w |
Window selector (window walker) |
super + . |
Screen search (click hints) |
super + c |
Cycle app windows across desktops |
super + shift + c |
Cycle app windows on current desktop |
super + space |
Center width cycle |
super + m |
Maximize/un-maximize |
alt + q |
Close window |
super + Left/Right/Up/Down |
Resize window and snap to grids |
super + shift + h/j/k/l |
Resize centered |
super + ctrl + h/j/k/l |
Move window |
super (double tap) |
Toggle move mode |
| Shortcut | Action |
|---|---|
h/j/k/l |
Move window |
Esc or super |
Exit move mode |
| Shortcut | Action |
|---|---|
alt + h/l |
Focus left/right |
alt + j/k |
Focus down/up |
alt + [ / alt + ] |
Cycle stacked (prev/next) |
| Shortcut | Action |
|---|---|
super + alt + h/l |
Previous/next desktop |
super + WheelUp/WheelDown |
Previous/next desktop (when virtual_desktop.scroll_switch = true) |
super + alt + shift + h/l |
Move window to previous/next desktop (follow) |
super + alt + shift + WheelUp/WheelDown |
Move window to previous/next desktop (when virtual_desktop.scroll_switch = true) |
super + alt + <key> |
Go to mapped desktop ([[virtual_desktop.<N>]]) |
super + alt + shift + <key> |
Move window to mapped desktop (follow) |
virtual_desktop.auto_assign |
Move newly created windows that match apps[] with desktop set |
virtual_desktop.debug_focus |
Log cross-desktop focus attempts to %APPDATA%\harken\vd.focus.debug.log |
virtual_desktop.switch_curtain |
Dim overlay during desktop switches to reduce flicker |
These are examples for the launch-or-focus keybindings.
| Shortcut | Action |
|---|---|
super + e |
Files (explorer.exe) |
super + v |
Editor (Code.exe) |
super + s |
Terminal (WindowsTerminal.exe) |
super + n |
Notes (notepad++.exe) |
| Shortcut | Action |
|---|---|
super + ; |
Enter command mode |
r |
Reload program/config |
e |
Open config file |
w |
Open a new window for the active app |
n |
Toggle command overlay |
i |
Open window inspector |
m |
Enter move mode |
Esc |
Exit command mode |
tools/window_inspector.ahklists active window titles, exe names, classes, and PIDs.- Use it to identify values for
apps[].win_titlein your config. - In Command Mode, press
ito launch the window inspector. - Use Refresh to update the list; Copy Selected/All or Export to save results.
Optional config file watcher that reloads the program when your config changes.
[config_watch]
enabled = false
interval_ms = 2500[screen_search]
enabled = true
hotkey = "."
hint_chars = "asdfghjklqwertyuiopzxcvbnm"
max_results = 200
min_size_px = 12
min_distance_px = 40
hint_opacity = 235
debug_log = false- This has not been tested with multi-monitor setups or much outside of ultra-wide monitors.
- Virtual desktop integration requires AutoHotkey v2.1-alpha-18 or later.
- Some apps (e.g., Discord) launch via
Update.exeand keep versioned subfolders, which makes auto-resolution unreliable for launching or focusing more challenging. - For some apps that minimize or close to the system tray, it's recommended you disable that in the program. Otherwise you can try to set
apps[].runto a stable full path (or userun_paths) in your config. - Windows with elevated permissions may ignore Harken hotkeys unless Harken is run as Administrator.
- JXON (AHK v2 JSON serializer) from https://github.com/TheArkive/JXON_ahk2
- License:
LICENSES/JXON_ahk2-LICENSE.md
- License:
- VD.ahk from https://github.com/FuPeiJiang/VD.ahk
- License:
LICENSES/VD.ahk-LICENSE.md
- License:
- UIA.ahk v1.1.2 from https://github.com/Descolada/UIA-v2
- License:
LICENSES/UIA.ahk-LICENSE.md
- License:
For this project I was primarily inspired by what I was able to accomplish with Raycast on macOS. Between Karabiner, Raycast, and HammerSpoon one could achieve all of Harken and more on macOS. I needed to move back to windows for work, and I wanted a way to use the same flow on Windows that I had become accustomed to on macOS.
Other macOS tools that I tried for more than five minutes were AeroSpace and Loop.
The foundation of Harken was built upon this reddit post, shared by u/CrashKZ -- Thanks to /u/plankoe for their initial contributions, too.
FancyZones is okay, but it doesn't remove the need to know where things are in order to focus on them, and its features are insufficient for a truly keyboard-centered workflow.
I really like komorebi--though I didn't use it for long and I have never been able to stick with tiling in the long run--but for those who prefer the tiling approach this might be the best option on Windows.
GlazeWM is another popular tiling window manager for Windows operating systems.
| Feature | Harken | FancyZones | komorebi | GlazeWM |
|---|---|---|---|---|
| Primary interaction model | Keyboard-first hotkeys and commands | Zone-based snapping (mouse + keyboard) | Dynamic tiling WM | Dynamic tiling WM |
| Launch-or-focus app hotkeys | Yes (configurable per app) | No (outside scope) | Possible via external tooling/scripts | Possible via external tooling/scripts |
| Directional focus movement | Yes (alt + h/j/k/l) |
No | Yes | Yes |
| Stack/window cycling | Yes (super + [ / super + ], app cycling) |
Mostly | Yes (tiling containers/workspaces) | Yes (tiling containers/workspaces) |
| Virtual desktop hotkeys | Yes (native desktop integration) | Indirect (PowerToys + Windows shortcuts) | Yes | Yes |
| Freeform floating adjustments | Yes (move mode + resize controls) | Primarily zone snapping | Primarily tiling; floating is secondary | Primarily tiling; floating is secondary |
| Built-in command/help overlay | Yes (super + /, command mode) |
No | No built-in overlay | No built-in overlay |
| Config format | TOML | GUI + JSON settings | JSON/YAML-style config | YAML |
| Best fit | Users who want keyboard speed without fully committing to tiling | Users who want quick snap layouts | Users who want full tiling workflows | Users who want full tiling workflows |