Skip to content

Instantly share code, notes, and snippets.

@velebak
Forked from tholden/AdvancedWindowSnap.ahk
Created March 13, 2019 23:06
Show Gist options
  • Select an option

  • Save velebak/3cccc1daa63b5e4caaf4d7e5b41fb9a1 to your computer and use it in GitHub Desktop.

Select an option

Save velebak/3cccc1daa63b5e4caaf4d7e5b41fb9a1 to your computer and use it in GitHub Desktop.

Advanced Window Snap

Advanced Window Snap is a script for AutoHotKey that expands upon Windows built-in window-snapping hotkeys (which are Win + LEFT to snap an active window to the left half of a monitor and Win + RIGHT to snap a window to the right half of a monitor) by adding many additional snap methods, using combinations of Win + Ctrl, Win + Alt, and Win + Ctrl + Alt, along with arrow keys, and the number pad (with NumLock On).

Installation Steps

  1. Install AutoHotKey
  2. Copy or Download the AdvancedWindowSnap.ahk file to your computer and double click it to run it.
  3. (Optional) To have the program run when you start up your computer, place the .ahk file into your computer's startup folder.
    • The Windows 7 Startup Folder can be accessed by mousing to Start > All Programs, then right-clicking on Startup and selecting "Open".
    • The Windows 8 Startup Folder can be accessed by tapping Win + R on your keyboard, then in the Open: field, type shell:startup then press Enter.

Advanced Window Snap Keybindings

Directional Arrow Hotkeys:

Please see the code.

Changelog

  • v2.00, 30 March 2015
    • Modified for widescreen monitors
  • v1.00, 08 January 2015
    • Initial Version

Recommendation For Editing AHK Files

If you plan on working with AutoHotKey files, consider using Sublime Text 3. Read my steps for setting up Sublime Text 3 to edit AutoHotKey files here: Working with AutoHotKey in Sublime Text.

/**
* Advanced Window Snap
* Snaps the Active Window to one of nine different window positions.
*
* @author Andrew Moore <andrew+github@awmoore.com>
* @version 1.0
*/
/**
* SnapActiveWindow resizes and moves (snaps) the active window to a given position.
* @param {string} winPlaceVertical The vertical placement of the active window.
* Expecting "top" or "bottom", otherwise assumes
* window should span the "full" height of the monitor.
* @param {string} winPlaceHorizontal The horizontal placement of the active window.
* Expecting "right" or "middle", otherwise assumes
* window should be placed at the "left".
* @param {string} winSizeWidth The width of the active window in relation to
* the active monitor's width. Expecting "full" or "half"
* size, otherwise will resize window to a "third".
*/
SnapActiveWindow(winPlaceVertical, winPlaceHorizontal, winSizeWidth) {
WinGet activeWin, ID, A
activeMon := GetMonitorIndexFromWindow(activeWin)
SysGet, MonitorWorkArea, MonitorWorkArea, %activeMon%
if (winSizeWidth == "full") {
width := (MonitorWorkAreaRight - MonitorWorkAreaLeft)
} else if (winSizeWidth == "half") {
width := (MonitorWorkAreaRight - MonitorWorkAreaLeft)/2
} else {
width := (MonitorWorkAreaRight - MonitorWorkAreaLeft)/3
}
if (winPlaceVertical == "top") {
posY := MonitorWorkAreaTop
height := (MonitorWorkAreaBottom - MonitorWorkAreaTop)/2
} else if (winPlaceVertical == "bottom") {
posY := MonitorWorkAreaTop + (MonitorWorkAreaBottom - MonitorWorkAreaTop)/2
height := (MonitorWorkAreaBottom - MonitorWorkAreaTop)/2
} else {
posY := MonitorWorkAreaTop
height := MonitorWorkAreaBottom - MonitorWorkAreaTop
}
if (winPlaceHorizontal == "right") {
posX := MonitorWorkAreaRight - width
} else if (winPlaceHorizontal == "middle") {
posX := MonitorWorkAreaLeft + (MonitorWorkAreaRight - MonitorWorkAreaLeft - width)/2
} else {
posX := MonitorWorkAreaLeft
}
WinMove,A,,%posX%,%posY%,%width%,%height%
}
/**
* GetMonitorIndexFromWindow retrieves the HWND (unique ID) of a given window.
* @param {Uint} windowHandle
* @author shinywong
* @link http://www.autohotkey.com/board/topic/69464-how-to-determine-a-window-is-in-which-monitor/?p=440355
*/
GetMonitorIndexFromWindow(windowHandle) {
; Starts with 1.
monitorIndex := 1
VarSetCapacity(monitorInfo, 40)
NumPut(40, monitorInfo)
if (monitorHandle := DllCall("MonitorFromWindow", "uint", windowHandle, "uint", 0x2))
&& DllCall("GetMonitorInfo", "uint", monitorHandle, "uint", &monitorInfo) {
monitorLeft := NumGet(monitorInfo, 4, "Int")
monitorTop := NumGet(monitorInfo, 8, "Int")
monitorRight := NumGet(monitorInfo, 12, "Int")
monitorBottom := NumGet(monitorInfo, 16, "Int")
workLeft := NumGet(monitorInfo, 20, "Int")
workTop := NumGet(monitorInfo, 24, "Int")
workRight := NumGet(monitorInfo, 28, "Int")
workBottom := NumGet(monitorInfo, 32, "Int")
isPrimary := NumGet(monitorInfo, 36, "Int") & 1
SysGet, monitorCount, MonitorCount
Loop, %monitorCount% {
SysGet, tempMon, Monitor, %A_Index%
; Compare location to determine the monitor index.
if ((monitorLeft = tempMonLeft) and (monitorTop = tempMonTop)
and (monitorRight = tempMonRight) and (monitorBottom = tempMonBottom)) {
monitorIndex := A_Index
break
}
}
}
return %monitorIndex%
}
; Directional Arrow Hotkeys
#!^Left::SnapActiveWindow("full","left","half")
#!^Right::SnapActiveWindow("full","right","half")
#^!Up::SnapActiveWindow("top","full","full")
#^!Down::SnapActiveWindow("bottom","full","full")
#!Left::SnapActiveWindow("full","left","third")
#!Right::SnapActiveWindow("full","right","third")
#!Up::SnapActiveWindow("full","middle","third")
#!Down::SnapActiveWindow("full","middle","third")
#^Left::SnapActiveWindow("full","left","half")
#^Right::SnapActiveWindow("full","right","half")
#^Up::SnapActiveWindow("full","middle","half")
#^Down::SnapActiveWindow("full","middle","half")
; Numberpad Hotkeys
#!Numpad7::SnapActiveWindow("top","left","third")
#!Numpad8::SnapActiveWindow("top","middle","third")
#!Numpad9::SnapActiveWindow("top","right","third")
#!Numpad4::SnapActiveWindow("full","left","third")
#!Numpad5::SnapActiveWindow("full","middle","third")
#!Numpad6::SnapActiveWindow("full","right","third")
#!Numpad1::SnapActiveWindow("bottom","left","third")
#!Numpad2::SnapActiveWindow("bottom","middle","third")
#!Numpad3::SnapActiveWindow("bottom","right","third")
#^Numpad7::SnapActiveWindow("top","left","half")
#^Numpad8::SnapActiveWindow("top","middle","half")
#^Numpad9::SnapActiveWindow("top","right","half")
#^Numpad4::SnapActiveWindow("full","left","half")
#^Numpad5::SnapActiveWindow("full","middle","half")
#^Numpad6::SnapActiveWindow("full","right","half")
#^Numpad1::SnapActiveWindow("bottom","left","half")
#^Numpad2::SnapActiveWindow("bottom","middle","half")
#^Numpad3::SnapActiveWindow("bottom","right","half")
#!^Numpad7::SnapActiveWindow("top","left","full")
#!^Numpad8::SnapActiveWindow("top","middle","full")
#!^Numpad9::SnapActiveWindow("top","right","full")
#!^Numpad4::SnapActiveWindow("full","left","full")
#!^Numpad5::SnapActiveWindow("full","middle","full")
#!^Numpad6::SnapActiveWindow("full","right","full")
#!^Numpad1::SnapActiveWindow("bottom","left","full")
#!^Numpad2::SnapActiveWindow("bottom","middle","full")
#!^Numpad3::SnapActiveWindow("bottom","right","full")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment