Monday, August 1, 2011

AutoHotKey: script structure, tray menus

I like AutoHotKey.

But I find that AutoHotKey scripts often collide, with each other and with other applications. (A problem that GNU Emacs' key binding also has, although elisp's greater programmability provides ways of managing such collisions.)

Therefore, I have structured my AutoHotKey system as multiple scripts, which I only load as necessary. The top level script loads other scripts as desired. Normally I have minimal bindings enabled.

Actually, up until today I had only one binding enabled by default, Ctl-Win-G (G for Glew). As of today, I have removed even that - I now just use the tray menu.

My AHK main script, called "Startup Default Glew Minimal Main Entry Point AutoHotKey,ahk" (there's a story behind the long name) looks like:

AG_AutoHotKey_Folder = ...path...
SetWorkingDir,%AG_AutoHotKey_Folder%
...
#include Glew-Package-Menu.ahk
return


(Eliding details - I'll add some below.)

I use the level of indirection to get to the package menu to allow me to quickly switch stuff around.


The package menu currently looks like:



; This AutoHotkey package exists mainly to load other packages
; via a minimal, single key, keyboard binding.
; I do not want them always loaded, because AutoHotkey is suspect of interfering,
; causing Windows crashes and hangs.


Menu, Glew_AutoHotKey_Package_Menu, Add, Old AutoHotKey, Run_2
Menu, Glew_AutoHotKey_Package_Menu, Add, Glew-AutoHotKey-Bindings, Run_1
Menu, Glew_AutoHotKey_Package_Menu, Add, Display Window Warping, Run_3

Menu, GlewMenu, Add, Glew_AutoHotKey_Package_Menu, :Glew_AutoHotKey_Package_Menu

; Quick summary on Tray Menu
Menu, tray, add
Menu, tray, add, GlewMenu, :GlewMenu

return ; End of script's auto-execute section.

;===============================================================

; Load packages which I do not necessarily want always loaded
; because of key binding conflicts

Run_1:
Run "...Glew-AutoHotKey-Bindings.ahk"
return
Run_2:
Run ".../Old-AutoHotKey.ahk"
return
Run_3:
Run ".../Glew-Display-Window.ahk"
return


TBD: possibly display all packages in a directory.

The lines

; Quick summary on Tray Menu
Menu, tray, add
Menu, tray, add, GlewMenu, :GlewMenu

do what the comment says - they basically add the functionality as a submenu off the tree menu. Which means that the default AHK script requires no key bindings at all, greatly reducing the problems I have had - and also making it easy to recall how to use the AHK macros.

Finally, to the top level script, I have added:

First, stuff to visit my AHK folder and the scriupt called indirectly:


...
Menu,tray,add
Menu,tray,add,visit_AG_AutoHotKey_Folder
Menu,tray,add,edit_Default_Script
Menu,tray,add
...
visit_AG_AutoHotKey_Folder:
Run %AG_AutoHotKey_Folder%
return

edit_Default_Script:
Run Notepad Glew-Package-Menu.ahk
return



Second, stuff to make it easy to find all windows
- I have been plagued by windows getting opened up off any visible display, because I am frequently moving between multi-display configurations:

...
Menu,tray,add
Menu,tray,add,Locate_All_Windows
Menu,tray,add,Locate_and_Restore_All_Windows
Menu,tray,add,Locate_and_Maximize_All_Windows
Menu,tray,add
Menu,tray,add,Maximize_All_Windows
Menu,tray,add,Minimize_All_Windows
Menu,tray,add,Restore_All_Windows
Menu,tray,add
...
;=============================================================================

; "locate" - appears to place the windows at 0,0 of the primary display

Locate_All_Windows:
WinGet, id, list, , , Program Manager
Loop, %id%
{
StringTrimRight, this_id, id%a_index%, 0
WinGetTitle, this_title, ahk_id %this_id%
winMove,%this_title%,,0,0
}
Return

Locate_and_Restore_All_Windows:
WinGet, id, list, , , Program Manager
Loop, %id%
{
StringTrimRight, this_id, id%a_index%, 0
WinGetTitle, this_title, ahk_id %this_id%
WinRestore,%this_title%
winMove,%this_title%,,0,0
}
Return

Locate_and_Maximize_All_Windows:
WinGet, id, list, , , Program Manager
Loop, %id%
{
StringTrimRight, this_id, id%a_index%, 0
WinGetTitle, this_title, ahk_id %this_id%
WinRestore,%this_title%
winMove,%this_title%,,0,0
WinMaximize,%this_title%
winMove,%this_title%,,0,0
}
Return

; --------------------------------------------------------------
; Maximize/Minimize/restore all windows

Maximize_All_Windows:
WinGet, id, list, , , Program Manager
Loop, %id%
{
StringTrimRight, this_id, id%a_index%, 0
WinGetTitle, this_title, ahk_id %this_id%
winMaximize,%this_title%
}
Return

Minimize_All_Windows:
WinGet, id, list, , , Program Manager
Loop, %id%
{
StringTrimRight, this_id, id%a_index%, 0
WinGetTitle, this_title, ahk_id %this_id%
winMinimize,%this_title%
}
Return

Restore_All_Windows:
WinGet, id, list, , , Program Manager
Loop, %id%
{
StringTrimRight, this_id, id%a_index%, 0
WinGetTitle, this_title, ahk_id %this_id%
winRestore,%this_title%
}
Return

;-------------------------------------------------------------------
; TBD: close, kill, hide, unhide, show
; for all windows

No comments:

Post a Comment