flow-wm 0.1.1

A scrolling, infinite-horizontal-canvas tiling window manager for Windows
#Requires AutoHotkey v2.0.2
#SingleInstance Force

; ════════════════════════════════════════════════════════════════════════════
; FlowWM — flow.ahk
; Ready-to-use AutoHotkey v2 keybindings for FlowWM.
; ════════════════════════════════════════════════════════════════════════════
;
; Generated by:  `flow config init --ahk`
; Written to:    %USERPROFILE%\.config\flow\flow.ahk
;
; This file is yours. Edit it freely — FlowWM never overwrites it once it
; exists. Two things you may want to customise (both at the top of the file):
;
;   1. ModKey    — the modifier every binding is held with. Alt is the default
;                 (it's on every keyboard and matches other Windows tiling
;                 managers), but Alt+<letter> can collide with an app's menu
;                 shortcuts. To switch, change the one line below, e.g.
;                 ModKey := "ScrollLock", "CapsLock", "F13", or "LWin".
;                 Key list: https://www.autohotkey.com/docs/v2/KeyList.htm
;
;                 Want the Windows key? ModKey := "LWin" works, but Windows
;                 swallows some Win+<key> shortcuts (Start menu, Win+D, Win+L, …)
;                 before AutoHotkey sees them, so a few chords may misfire. The
;                 zero-compromise path: set ModKey to a sacrificial key (e.g.
;                 "ScrollLock") and hardware-remap LWin to it in your keyboard
;                 firmware — physically you press Win, the OS sees the sacrificial
;                 key. See the README's "Can I use the Win key?" section.
;
;   2. flowExe  — path to flow.exe. Defaults to "flow" (resolved from PATH).
;                 If FlowWM isn't on your PATH, set the full path, e.g.
;                 "C:\Users\you\flow.exe".
;
; Run at login:  `flow enable-autostart --ahk` (creates a single shell:startup
;                shortcut that runs `flow.exe start --ahk`; idempotent).
; Full dispatch: run `flow dispatch help` for every available command.
;
; Layout (hold ModKey + key):
;   h j k l  focus left/down/up/right          (+Shift = move window)
;                                             (+Ctrl  = merge into column)
;                                             (+Ctrl+Shift = promote to new column)
;   , .      shrink / expand focused column
;   c        center viewport on focused column
;   t        cycle window float <-> tile
;   q        close focused window
;   p        stop the daemon (then this script exits too)
;   1..9,0   switch to workspace 1..10        (+Shift = send window there)
;
; ════════════════════════════════════════════════════════════════════════════

; --- Config ------------------------------------------------------------------
ModKey   := "Alt"                 ; the modifier every binding is held with
flowExe := "flow"                ; path to flow.exe (PATH by default)

; --- Flow command helpers ----------------------------------------------------
Flow(cmd) {
    global flowExe
    Run(flowExe ' ' cmd, , 'Hide')
}

FlowDispatch(cmd) {
    global flowExe
    Run(flowExe ' dispatch ' cmd, , 'Hide')
}

; --- Action handlers ---------------------------------------------------------
; Each handler maps one ModKey+key chord to a `flow dispatch` call. The
; Ctrl/Shift variants are read at fire-time so a single key covers several
; related actions.
Act_Stop(*) {
    Flow("stop")
    ExitApp()
}

Act_Left(*) {     ; h
    if GetKeyState("Control") and GetKeyState("Shift")
        FlowDispatch("promote left")
    else if GetKeyState("Shift")
        FlowDispatch("move-window left")
    else if GetKeyState("Control")
        FlowDispatch("merge-column left")
    else
        FlowDispatch("focus left")
}

Act_Right(*) {    ; l
    if GetKeyState("Control") and GetKeyState("Shift")
        FlowDispatch("promote right")
    else if GetKeyState("Shift")
        FlowDispatch("move-window right")
    else if GetKeyState("Control")
        FlowDispatch("merge-column right")
    else
        FlowDispatch("focus right")
}

Act_Down(*) {     ; j
    if GetKeyState("Shift")
        FlowDispatch("move-window down")
    else
        FlowDispatch("focus down")
}

Act_Up(*) {       ; k
    if GetKeyState("Shift")
        FlowDispatch("move-window up")
    else
        FlowDispatch("focus up")
}

WorkspaceAction(n) {
    if GetKeyState("Shift")
        FlowDispatch("move-to-workspace " n)
    else
        FlowDispatch("switch-workspace " n)
}

; --- Register every binding --------------------------------------------------
; Done dynamically so ModKey is one changeable line: swap the modifier above and
; every chord below follows. Custom combos (e.g. "Alt & h") are passed
; to Hotkey() as a single string built from ModKey.
Hotkey(ModKey " & p", Act_Stop)
Hotkey(ModKey " & h", Act_Left)
Hotkey(ModKey " & l", Act_Right)
Hotkey(ModKey " & j", Act_Down)
Hotkey(ModKey " & k", Act_Up)
Hotkey(ModKey " & ,", (*) => FlowDispatch("shrink-column"))
Hotkey(ModKey " & .", (*) => FlowDispatch("expand-column"))
Hotkey(ModKey " & c", (*) => FlowDispatch("center"))
Hotkey(ModKey " & t", (*) => FlowDispatch("set-window cycle"))
Hotkey(ModKey " & q", (*) => FlowDispatch("close-window"))
Hotkey(ModKey " & 1", (*) => WorkspaceAction(1))
Hotkey(ModKey " & 2", (*) => WorkspaceAction(2))
Hotkey(ModKey " & 3", (*) => WorkspaceAction(3))
Hotkey(ModKey " & 4", (*) => WorkspaceAction(4))
Hotkey(ModKey " & 5", (*) => WorkspaceAction(5))
Hotkey(ModKey " & 6", (*) => WorkspaceAction(6))
Hotkey(ModKey " & 7", (*) => WorkspaceAction(7))
Hotkey(ModKey " & 8", (*) => WorkspaceAction(8))
Hotkey(ModKey " & 9", (*) => WorkspaceAction(9))
Hotkey(ModKey " & 0", (*) => WorkspaceAction(10))