log in

AutoHotkey: command-backtick windows switcher for Windows

Luke Breuer
2018-01-04 18:08 UTC

I wanted OSX's Command-` shortcut ability on Windows, although apparently I've implemented the "most recently used" ability requested at su.SE OS x command backtick historic order, instead of what OSX actually does.

  • Alt-[Shift-]`: cycle through other windows of the same process as the active window
  • Win-`: like Alt-`, but hides the active window first
  • Win-Shift-`: undo Win-`

Note that I'm by no means an AutoHotkey expert; I consider the language gross and just came across AutoHotkey_H, which looks a lot cleaner.
; emulate OSX command-backtick functionality
OutputDebug, AHK backtick_initialized = %backtick_initialized%
if (!backtick_initialized)
    backtick_initialized := 1
    SetTimer, CheckDisable, 10

    WinGet, pn, ProcessPath, A
    WinGet, pns, List, ahk_exe %pn%
    pn_count := pns
    pn_cur := 0

    ; cannot use GroupAdd because there is no GroupDelete
    ;Loop, %pns%
    ;    this_id := pns%A_Index%
    ;    GroupAdd, Backtick_Windows, ahk_id %this_id%
    ;    WinActivate, ahk_id %this_id%
    ;    WinGetClass, this_class, ahk_id %this_id%
    ;    WinGetTitle, this_title, ahk_id %this_id%
    ;    OutputDebug, AHK %A_Index% %this_title%
    ;    MsgBox, 4, , Visiting All Windowsn%a_index% of %id%nahk_id %this_id%nahk_class %this_class%n%this_title%nnContinue?
    ;    IfMsgBox, NO, break
;GroupActivate, Backtick_Windows

if (GetKeyState("Shift"))
    add_value := pn_count - 1
    add_value := 1

pn_cur := Mod(pn_cur + add_value, pn_count)
idx := pn_cur + 1
;OutputDebug, AHK: %shift_depressed% : +%add_value% -> %idx%
this_id := pns%idx%
WinActivate, ahk_id %this_id%

; I found no better way to detect the alt-keyup
KeyWait, Alt, T0.001
if (!ErrorLevel)
    backtick_initialized := 0
    SetTimer, CheckDisable, off

; emulate OSX command-backtick functionality except the active window is sent
; to the bottom of the Z-index
WinGetClass, ActiveClass, A
WinGet, WinClassCount, Count, ahk_class %ActiveClass%
if WinClassCount = 1
WinSet, Bottom,, A
WinActivate, ahk_class %ActiveClass%

; I didn't feel like making the hide-last-window functionality from #`:: work,
; so this progressively pulls more windows to the top; in a sense that's
; actually the exact inverse of #`::
WinGet, pn, ProcessPath, A
WinGet, pns, List, ahk_exe %pn%
OutputDebug, AHK pns%pns%, %pns5%
if pns = 1
;WinSet, Bottom,, A
this_id := pns%pns%
WinActivate, ahk_id %this_id%