From 90ac7a7805751568073b7ef7bb6876b12e5a5b4a Mon Sep 17 00:00:00 2001 From: Klesh Wong Date: Fri, 23 Jul 2021 12:59:49 +0800 Subject: [PATCH] [feature] support multi-monitor --- win/ahk/WindowManager.ahk | 141 +++++++++++++++++++++++++++++--------- win/win.ahk | 35 ++++++++-- 2 files changed, 138 insertions(+), 38 deletions(-) diff --git a/win/ahk/WindowManager.ahk b/win/ahk/WindowManager.ahk index 863aec7..f3c1141 100644 --- a/win/ahk/WindowManager.ahk +++ b/win/ahk/WindowManager.ahk @@ -73,25 +73,23 @@ GetActiveWindowMonGeometry(ByRef x, ByRef y, ByRef w, ByRef h) { } GetMonGeometryByPos(px, py, ByRef x, ByRef y, ByRef w, ByRef h) { - ; find monitor by position SysGet, mc, MonitorCount - mi := 0 + mi := 1 loop { - if (mi > mc) { - break - } - SysGet, mon, MonitorWorkArea, %mi% - if (monLeft < px and monRight > px and monTop < py and monBottom > py) { - x := monLeft - y := monTop - w := monRight - monLeft - h := monBottom - monTop - return - } - mi := mi + 1 + if (mi > mc) { + break + } + SysGet, mon, MonitorWorkArea, %mi% + if (monLeft < px and monRight > px and monTop < py and monBottom > py) { + x := monLeft + y := monTop + w := monRight - monLeft + h := monBottom - monTop + return + } + mi := mi + 1 } - msg := Format("unable to find monitor for pos {1}, {2}", px, py) - MsgBox, %msg% + LogDebug("unable to find monitor for pos {1}, {2}", px, py) } FocusWinByDirection(direction) { @@ -168,6 +166,27 @@ GetActiveWindowMargins(hwnd, monX, monY, monW, monH, ByRef l, ByRef t, ByRef r, LogDebug("active window margins: {1} {2} {3} {4}", l, t, r, b) } +ToggleActiveWinMaximum() { + WinGet, isMax, MinMax, A + if (isMax) { + WinRestore, A + } else { + WinMaximize, A + } +} + +ArrangeActiveWindow(method) { + if (method = "monocle") { + WinGet, isMax, MinMax, A + if (not isMax) { + WinMaximize, A + } + } else { + MoveActiveWinByDirection(method) + } + SaveActiveWindowDirection(method) +} + MoveActiveWinByDirection(direction) { WinGet, isMax, MinMax, A if (isMax) { @@ -204,7 +223,69 @@ MoveActiveWinByDirection(direction) { wh := wh - PADDING * 2 WinMove, A,, wx, wy, ww, wh LogDebug("move win to x: {1}, y: {2}, w: {3}, h: {4}", wx, wy, ww, wh) - SaveActiveWindowDirection(direction) +} + +GetCursorNearestMonitor(direction, ByRef ml, ByRef mt, ByRef mr, ByRef mb) { + MouseGetPos x, y + if (direction = "right") { ; start at right most, and search for nearest monitor + ml := 10000 + mt := 10000 + mr := 10000 + mb := 10000 + } else { + ml := -10000 + mt := -10000 + mr := -10000 + mb := -10000 + } + SysGet, mc, MonitorCount + mi := 1 + loop { + if (mi > mc) { + break + } + SysGet, mon, MonitorWorkArea, %mi% + if (direction = "right") { + if (monLeft > x and monLeft < ml) { + ml := monLeft + mt := monTop + mr := monRight + mb := monBottom + } + } else { + if (monRight < x and monRight > mr) { + ml := monLeft + mt := monTop + mr := monRight + mb := monBottom + } + } + mi := mi + 1 + } + return Abs(ml) != 10000 +} + +MoveCursorToMonitor(direction) { + if (GetCursorNearestMonitor(direction, ml, mt, mr, mb)) { + SetCursorPos((ml+mr)/2, (mt + mb)/2) + FocusWinUnderCursor() + } +} + +MoveWindowToMonitor(direction) { + if (GetCursorNearestMonitor(direction, ml, mt, mr, mb)) { + WinGetPos wx, wy, ww, wh, A + mw := mr - ml + mh := mb - mt + ww := mw * 0.8 + wh := mh * 0.8 + wx := ml + ww / 2 + wy := mt + wh / 2 + LogDebug("move win to mon: {1}, {2}, {3}, {4}", wx, wy, ww, wh) + WinMove, A,, wx, wy, ww, wh + ArrangeActiveWindowFromStorage() + SetCursorToCenterOfActiveWin() + } } SaveArrangement() { @@ -245,7 +326,8 @@ LoadArrangement() { GetActiveWindowPath() { WinGet processPath, ProcessPath, A WinGetClass windowClass, A - return processPath . ":" . windowClass + GetActiveWindowMonGeometry(x, y, w, h) + return Format("{1}_{2}\{3}\{4}", w, h, processPath, windowClass) } IsActiveWindowSeen() { @@ -321,8 +403,15 @@ ActiveWinInfo() { return Format("{1}:{2}[{3}]{4}", processPath, klass, id, title) } -AdjustNewWindow() { +ArrangeActiveWindowFromStorage() { global ARRANGEMENT + windowPath := GetActiveWindowPath() + if ARRANGEMENT["windows"].HasKey(windowPath) { + ArrangeActiveWindow(ARRANGEMENT["windows"][windowPath]) + } +} + +AdjustNewWindow() { seen := IsActiveWindowSeen() arrangable := IsActiveWindowArrangable() wininfo := ActiveWinInfo() @@ -330,18 +419,6 @@ AdjustNewWindow() { LogDebug("win: {1}, seen: {2}, arrangable: {3}", wininfo, seen, arrangable) } if not seen and arrangable { - windowPath := GetActiveWindowPath() - if ARRANGEMENT["windows"].HasKey(windowPath) { - MoveActiveWinByDirection(ARRANGEMENT["windows"][windowPath]) - } - } -} - -ToggleActiveWinMaximum() { - WinGet, isMax, MinMax, A - if (isMax) { - WinRestore, A - } else { - WinMaximize, A + ArrangeActiveWindowFromStorage() } } diff --git a/win/win.ahk b/win/win.ahk index 5f43fda..4d545b6 100644 --- a/win/win.ahk +++ b/win/win.ahk @@ -7,7 +7,7 @@ CoordMode, Mouse, Screen ; mouse coordinates relative to the screen ; ========================= ; DEBUGGING ; ========================= -global DEBUGGING := false +global DEBUGGING := true ToggleDebugging() { global DEBUGGING @@ -25,12 +25,25 @@ LogDebug(params*) { log.Close() } +SetDisableLockWorkstationRegKeyValue(value) { + RegWrite, REG_DWORD, HKEY_CURRENT_USER, Software\Microsoft\Windows\CurrentVersion\Policies\System, DisableLockWorkstation, %value% +} + + +LockWorkStation() { + SetDisableLockWorkstationRegKeyValue( 0 ) + ; Lock + DllCall( "User32\LockWorkStation" ) + ; Disable locking again + SetDisableLockWorkstationRegKeyValue( 1 ) +} ; ========================= ; LIBS ; ========================= InitWindowManager() InitClipboardManager() +SetDisableLockWorkstationRegKeyValue(1) ; in order to remap win+l #Include, ahk\JSON.ahk #Include, ahk\WindowManager.ahk #Include, ahk\ClipboardManager.ahk @@ -57,20 +70,20 @@ InitClipboardManager() ; Win + \ => Toggle mute #\::Send {Volume_Mute} ; Win + backspace => Lock -#BS::#l +#BS::LockWorkStation() ; WINDOW MANAGER -; Win + f => Toggle window maximum -#f:: ToggleActiveWinMaximum() ; Win + j => Focus right window #j:: FocusWinByDirection("right") ; Win + k => Focus left window #k:: FocusWinByDirection("left") +; Win + f => Move active window as monocle +#f::ArrangeActiveWindow("monocle") ; Win + Shift + j => Move active window to right side -#+j::MoveActiveWinByDirection("right") +#+j::ArrangeActiveWindow("right") ; Win + Shift + k => Move active window to left side -#+k::MoveActiveWinByDirection("left") +#+k::ArrangeActiveWindow("left") ; Win + Shift + b => Blacklist active window so it won't be arranged when launched #+b::BlacklistArrangementForActiveWindow() ; Win + Shift + b => Whitelist active window so it always be arranged when launched @@ -79,6 +92,10 @@ InitClipboardManager() #+i::IgnoreArrangementForActiveWindow() ; Win + Shift + d => Toggle debug logging #+d::ToggleDebugging() +#h::MoveCursorToMonitor("left") +#l::MoveCursorToMonitor("right") +#+h::MoveWindowToMonitor("left") +#+l::MoveWindowToMonitor("right") ; CLIPBOARD MANAGER @@ -110,3 +127,9 @@ InitClipboardManager() ; SetCapsLockState % !GetKeyState("CapsLock", "T") ; Return ; Capslock::return + + +#t:: + MouseGetPos, MouseX, MouseY + MsgBox, s: %MouseX%, sh: %MouseY% + return \ No newline at end of file