Converting v1 script to v2

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
afshindavoudy
Posts: 44
Joined: 10 Jan 2024, 13:25

Converting v1 script to v2

Post by afshindavoudy » 23 Feb 2024, 05:01

I'm trying to convert this script to v2:
https://github.com/Tome-Sulmont/SimpleWindowsDrag

But I get the following error when using Win + numpad or Win + MButton hotkeys:
Error: Invalid parameter(s).
▶ 227: NumPut('UPtr', 40, monitorInfo)


I'm new to AHK and can't fix the error by myself. So, appreciate any help!
Here is what I have done sofar:

Code: Select all

; REMOVED: #NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode("Input")  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir(A_ScriptDir)  ; Ensures a consistent starting directory.
#SingleInstance Force
TraySetIcon("imageres.dll", "262") ; makes the icon into two window


; Simple Window Drag 
; --------------------------------------------------
; version : 1.0.0
; -> Script by Tomé Sulmont (tome.sulmont@laposte.net)
;
; Includes modified versions of :
; 	- Easy Window Dragging KDE style - by Jonny
; 	- Middle Mouse Button Gestures (diagonal) - by Drozdman
;	- Hyper Window Snap - by Andrew Moore and Jeff Axelrod
;
; https://www.autohotkey.com
;
; The goal with this script is to easily snap, move and resize windows with a single
; key press and a mouse :
;   1) Hold down the LWin key and LEFT-click anywhere inside a window to drag it to
;   a new location.
; 	2) Hold down LWin and RIGHT-click-drag anywhere inside a window to easily resize it.
;   3) Hold down LWin and MIDDLE-click-drag to perform different actions : maximize,
;   always on top or snap a window.
; 	4) Hold down LWin and MIDDLE-click without moving to minimize the window under
;   the mouse cursor.
;
; Shortcuts :
;  LWin + Left Button   + Drag					    : Move a window.
;  LWin + Right Button  + Drag						: Resize a window.
;  LWin + Middle Button + Drag Up					: Maximize/Restore a window.
;  LWin + Middle Button + Drag Down 					: Always On Top a window.
;  LWin + Middle Button + Drag Right 				: Snap to the Right half.
;  LWin + Middle Button + Drag Left 					: Snap to the Left half.
;  LWin + Middle Button + Drag Top Right Corner 		: Snap to the Top-Right quarter.
;  LWin + Middle Button + Drag Top Left Corner 		: Snap to the Top-Left quarter.
;  LWin + Middle Button + Drag Bottom Right Corner 	: Snap to Bottom-Right quarter.
;  LWin + Middle Button + Drag Bottom Left Corner 	: Snap to the Bottom-Left quarter.
;  LWin + Middle Button + Motionless 				: Minimize a window.
;  LWin + Numpad                                     : Snap the active window.

; Note
; --------------------------------------------------
; In my case, LWin is remapped to Caps Lock with PowerToy (because "Capslock::LWin" doesn't work)
If (VerCompare(A_AhkVersion, "1.0.39.00") < 0) {
    msgResult := MsgBox("This script may not work properly with your version of AutoHotkey. Continue?", "", 20)
    if (msgResult = "No")
        ExitApp()
}


; Easy Window Dragging
; --------------------------------------------------
; This is the setting that runs smoothest on my system. Depending on your video card and cpu power, you may want to raise or lower this value.
SetWinDelay(2)
CoordMode("Mouse")
return


; Mouse Gesture
; --------------------------------------------------
LWin & LButton:: {
    MouseGetPos(, , &KDE_id) ; Get the window id
    ; Abort if it's the desktop.
    ClassWin := WinGetClass("ahk_id " KDE_id)
    if (ClassWin = "WorkerW")
        return
    ; If the window is maximized, restore the initial position
    ; and size of the window and center the mouse.
    KDE_Win := WinGetMinMax("ahk_id " KDE_id)
    If KDE_Win {
        WinRestore("ahk_id " KDE_id)
        WinGetPos(&KDE_WinX1, &KDE_WinY1, &KDE_WinW, &KDE_WinH, "ahk_id " KDE_id)
        MouseMove((KDE_WinX1 + (KDE_WinW / 2)), (KDE_WinY1 + (KDE_WinH / 2)), 0)
    }

    ; Move the window.
    MouseGetPos(&KDE_X1, &KDE_Y1)
    WinGetPos(&KDE_WinX1, &KDE_WinY1, , , "ahk_id " KDE_id)
    Loop {
        KDE_Button := GetKeyState("LButton", "P") ? "D" : "U" ; Break if button has been released.
        if (KDE_Button = "U")
            break
        MouseGetPos(&KDE_X2, &KDE_Y2) ; Get the current mouse position.
        KDE_X2 -= KDE_X1 ; Obtain an offset from the initial mouse position.
        KDE_Y2 -= KDE_Y1
        KDE_WinX2 := (KDE_WinX1 + KDE_X2) ; Apply this offset to the window position.
        KDE_WinY2 := (KDE_WinY1 + KDE_Y2)
        WinMove(KDE_WinX2, KDE_WinY2, , , "ahk_id " KDE_id) ; Move the window to the new position.
    }
    return
}
LWin & RButton:: {
    ; Get the mouse position and window id,
    MouseGetPos(&KDE_X1, &KDE_Y1, &KDE_id)
    ; Abort if it's the desktop.
    ClassWin := WinGetClass("ahk_id " KDE_id)
    if (ClassWin = "WorkerW")
        return
    ; Abort if the window is maximized.
    KDE_Win := WinGetMinMax("ahk_id " KDE_id)
    If KDE_Win
        return
    ; Get the initial window position and size.
    WinGetPos(&KDE_WinX1, &KDE_WinY1, &KDE_WinW, &KDE_WinH, "ahk_id " KDE_id)
    ; Define the window region the mouse is currently in.
    ; The four regions are Up and Left, Up and Right, Down and Left, Down and Right.
    If (KDE_X1 < KDE_WinX1 + KDE_WinW / 2)
        KDE_WinLeft := 1
    Else
        KDE_WinLeft := -1
    If (KDE_Y1 < KDE_WinY1 + KDE_WinH / 2)
        KDE_WinUp := 1
    Else
        KDE_WinUp := -1
    Loop {
        KDE_Button := GetKeyState("RButton", "P") ? "D" : "U" ; Break if button has been released.
        if (KDE_Button = "U")
            break
        MouseGetPos(&KDE_X2, &KDE_Y2) ; Get the current mouse position.
        ; Get the current window position and size.
        WinGetPos(&KDE_WinX1, &KDE_WinY1, &KDE_WinW, &KDE_WinH, "ahk_id " KDE_id)
        KDE_X2 -= KDE_X1 ; Obtain an offset from the initial mouse position.
        KDE_Y2 -= KDE_Y1
        ; Then, act according to the defined region.
        WinMove(KDE_WinX1 + (KDE_WinLeft + 1) / 2 * KDE_X2, KDE_WinY1 + (KDE_WinUp + 1) / 2 * KDE_Y2, KDE_WinW - KDE_WinLeft * KDE_X2, KDE_WinH - KDE_WinUp * KDE_Y2, "ahk_id " KDE_id)  ; X of resized window
        KDE_X1 := (KDE_X2 + KDE_X1) ; Reset the initial position for the next iteration.
        KDE_Y1 := (KDE_Y2 + KDE_Y1)
    }
    return
}
LWin & MButton:: {
    MouseGetPos(&X1, &Y1, &KDE_id) ; Get the window id
    ; Abort if it's the desktop.
    ClassWin := WinGetClass("ahk_id " KDE_id)
    if (ClassWin = "WorkerW")
        return
    KeyWait("MButton")
    MouseGetPos(&X2, &Y2)
    MinTime := 50 ; Set A_TimeSinceThisHotkey
    LongTime := 200 ; Set A_TimeSinceThisHotkey to avoid hiting Gesture down by accident
    Tolerance := 60 ; Tolerance of the gesture
    if (A_TimeSinceThisHotkey > MinTime AND X2 - X1 > 0 AND Y2 - Y1 < 0 AND Abs(X2 - X1) >= Tolerance AND Abs(Y2 - Y1) >= Tolerance) {
        Goto(GestureTR(KDE_id))	; gesture top/right
    }
    else if (A_TimeSinceThisHotkey > MinTime AND X2 - X1 > 0 AND Y2 - Y1 > 0 AND Abs(X2 - X1) >= Tolerance AND Abs(Y2 - Y1) >= Tolerance) {
        Goto(GestureDR)	; gesture down/right
    }
    else if (A_TimeSinceThisHotkey > MinTime AND X2 - X1 < 0 AND Y2 - Y1 < 0 AND Abs(X2 - X1) >= Tolerance AND Abs(Y2 - Y1) >= Tolerance) {
        Goto(GestureTL(KDE_id))	; gesture top/left
    }
    else if (A_TimeSinceThisHotkey > MinTime AND X2 - X1 < 0 AND Y2 - Y1 > 0 AND Abs(X2 - X1) >= Tolerance AND Abs(Y2 - Y1) >= Tolerance) {
        Goto(GestureDL(KDE_id))	; gesture down/left
    }
    else if (A_TimeSinceThisHotkey > MinTime AND Y2 - Y1 < 0 AND Abs(Y2 - Y1) >= Tolerance AND Abs(X2 - X1) < Tolerance) {
        Goto(GestureU(KDE_id))	; gesture up
    }
    else if (A_TimeSinceThisHotkey > LongTime AND Y2 - Y1 > 0 AND Abs(Y2 - Y1) >= Tolerance AND Abs(X2 - X1) < Tolerance) {
        Goto(GestureD(KDE_id))	; Gesture down
    }
    else if (A_TimeSinceThisHotkey > MinTime AND X2 - X1 < 0 AND Abs(X2 - X1) >= Tolerance AND Abs(Y2 - Y1) < Tolerance) {
        Goto(GestureL(KDE_id))	; gesture left
    }
    else if (A_TimeSinceThisHotkey > MinTime AND X2 - X1 > 0 AND Abs(X2 - X1) >= Tolerance AND Abs(Y2 - Y1) < Tolerance) {
        Goto(GestureR(KDE_id))	; gesture right
    }
    else if ((X1 = X2) and (Y1 = Y2)) {
        Goto(NoMove(KDE_id))		; gesture no move
    }
    return
}


; Hyper Window Snap
; --------------------------------------------------
SnapActiveWindow(winPlaceVertical, winPlaceHorizontal, winSizeHeight) {
    heightOffset := 7
    widthOffset := 15
    xOffset := 7

    activeWin := WinExist("A")
    activeMon := GetMonitorIndexFromWindow(activeWin)
    MinMaxState := WinGetMinMax("A")
    If (MinMaxState) {
        WinRestore("A")
    }

    MonitorGetWorkArea(activeMon, &MonitorWorkAreaLeft, &MonitorWorkAreaTop, &MonitorWorkAreaRight, &MonitorWorkAreaBottom)

    if (winSizeHeight == "half") {
        height := (MonitorWorkAreaBottom - MonitorWorkAreaTop) / 2 + heightOffset
    } else if (winSizeHeight == "full") {
        height := (MonitorWorkAreaBottom - MonitorWorkAreaTop) + heightOffset
    } else if (winSizeHeight == "third") {
        height := (MonitorWorkAreaBottom - MonitorWorkAreaTop) / 3
    }

    if (winPlaceHorizontal == "left") {
        posX := MonitorWorkAreaLeft - xOffset
        width := (MonitorWorkAreaRight - MonitorWorkAreaLeft) / 2 + widthOffset
    } else if (winPlaceHorizontal == "right") {
        posX := MonitorWorkAreaLeft + (MonitorWorkAreaRight - MonitorWorkAreaLeft) / 2 - xOffset
        width := (MonitorWorkAreaRight - MonitorWorkAreaLeft) / 2 + widthOffset
    } else {
        posX := MonitorWorkAreaLeft - xOffset
        width := MonitorWorkAreaRight - MonitorWorkAreaLeft + widthOffset
    }

    if (winPlaceVertical == "bottom") {
        posY := MonitorWorkAreaBottom - height + heightOffset
    } else if (winPlaceVertical == "middle") {
        posY := MonitorWorkAreaTop + height
    } else {
        posY := MonitorWorkAreaTop
    }

    WinMove(posX, posY, width, height, "A")
}
GetMonitorIndexFromWindow(windowHandle) {
    ; Starts with 1.
    monitorIndex := 1

    VarSetStrCapacity(&monitorInfo, 40) ; V1toV2: if 'monitorInfo' is NOT a UTF-16 string, use 'monitorInfo := Buffer(40)'
    NumPut('UPtr', 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

            monitorCount := MonitorGetCount()

            Loop monitorCount {
                MonitorGet(A_Index, &tempMonLeft, &tempMonTop, &tempMonRight, &tempMonBottom)

                ; 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
}


; Set actions
; --------------------------------------------------
; Add Title Id to diferanciate diferent multiple instances (explorer or chrome for exemple) ?
GestureTR(KDE_id) {	; gesture top/right
    WinActivate("ahk_id " KDE_id) ; Activate the window
    SnapActiveWindow("top", "right", "half")
    return
}
GestureDR(KDE_id) {	; gesture down/right
    WinActivate("ahk_id " KDE_id) ; Activate the window
    SnapActiveWindow("bottom", "right", "half")
    return
}
GestureTL(KDE_id) {	; gesture top/left
    WinActivate("ahk_id " KDE_id) ; Activate the window
    SnapActiveWindow("top", "left", "half")
    return
}
GestureDL(KDE_id) {	; gesture down/left
    WinActivate("ahk_id " KDE_id) ; Activate the window
    SnapActiveWindow("bottom", "left", "half")
    return
}
GestureU(KDE_id) {	; gesture up
    ; Toggle between maximized and restored state.
    KDE_Win := WinGetMinMax("ahk_id " KDE_id)
    If KDE_Win
        WinRestore("ahk_id " KDE_id)
    Else
        WinMaximize("ahk_id " KDE_id)
    return
}
GestureD(KDE_id) {	; Gesture down
    WinActivate("KDE_id") ; Activate the window
    WinSetAlwaysOnTop(-1, "ahk_id " KDE_id)
    return
}
GestureL(KDE_id) {	; gesture left
    WinActivate("ahk_id " KDE_id) ; Activate the window
    SnapActiveWindow("top", "left", "full")
    return
}
GestureR(KDE_id) { ; gesture right
    WinActivate("ahk_id " KDE_id) ; Activate the window
    SnapActiveWindow("top", "right", "full")
    return
}
NoMove(KDE_id) { ; gesture no move
    WinMinimize("ahk_id " KDE_id) ; Minimize the window
    return
}


; Win + Numpad = Snap to conrners for diagonals, or top, bottom, left, right of screen (Landscape)
; --------------------------------------------------
LWin & Numpad1:: {
    ClassWin := WinGetClass("A") ; Abort if it's the desktop.
    if (ClassWin = "WorkerW")
        return
    SnapActiveWindow("bottom", "left", "half")
    return
}
LWin & Numpad2:: {
    ClassWin := WinGetClass("A") ; Abort if it's the desktop.
    if (ClassWin = "WorkerW")
        return
    SnapActiveWindow("bottom", "full", "half")
    return
}
LWin & Numpad3:: {
    ClassWin := WinGetClass("A") ; Abort if it's the desktop.
    if (ClassWin = "WorkerW")
        return
    SnapActiveWindow("bottom", "right", "half")
    return
}
LWin & Numpad4:: {
    ClassWin := WinGetClass("A") ; Abort if it's the desktop.
    if (ClassWin = "WorkerW")
        return
    SnapActiveWindow("top", "left", "full")
    return
}
LWin & Numpad5:: {
    ClassWin := WinGetClass("A") ; Abort if it's the desktop.
    if (ClassWin = "WorkerW")
        return
    KDE_Win := WinGetMinMax("A")
    If KDE_Win
        WinRestore("A")
    Else
        WinMaximize("A")
    return
}
LWin & Numpad6:: {
    ClassWin := WinGetClass("A") ; Abort if it's the desktop.
    if (ClassWin = "WorkerW")
        return
    SnapActiveWindow("top", "right", "full")
    return
}
LWin & Numpad7:: {
    ClassWin := WinGetClass("A") ; Abort if it's the desktop.
    if (ClassWin = "WorkerW")
        return
    SnapActiveWindow("top", "left", "half")
    return
}
LWin & Numpad8:: {
    ClassWin := WinGetClass("A") ; Abort if it's the desktop.
    if (ClassWin = "WorkerW")
        return
    SnapActiveWindow("top", "full", "half")
    return
}
LWin & Numpad9:: {
    ClassWin := WinGetClass("A") ; Abort if it's the desktop.
    if (ClassWin = "WorkerW")
        return
    SnapActiveWindow("top", "right", "half")
    return
}

User avatar
kunkel321
Posts: 1194
Joined: 30 Nov 2015, 21:19

Re: Converting v1 script to v2

Post by kunkel321 » 23 Feb 2024, 12:38

Here's a minimalist one that I made. It only does the drag/moving, not the other stuff.

Code: Select all

#SingleInstance
#Requires AutoHotkey v2+

^!Lbutton:: ; Ctrl+Alt+Left Mouse Click
{
	SetWinDelay(-1) ; Sets time between moves. -1 = no time
	CoordMode("Mouse", "Screen")
	WinGetPos(&BwX, &BwY, , , "A") ; Begin window X Y coord.
	WinRestore("A") ; Unmaximizes window.
	MouseGetPos(&BmX, &BmY) ; Begin mouse X Y coord
	while GetKeyState("Lbutton", "P") ; While left mouse button is held down.
	{	MouseGetPos(&CmX, &CmY) ; Keep getting current mouse X Y
		WinMove((BwX+CmX-BmX), (BwY+CmY-BmY), , , "A")
	} 
	SetWinDelay 100
	CoordMode("Mouse", "Window") ; Put back, because window is mostly the default.
Return
}
ste(phen|ve) kunkel

afshindavoudy
Posts: 44
Joined: 10 Jan 2024, 13:25

Re: Converting v1 script to v2

Post by afshindavoudy » 27 Feb 2024, 04:41

Here is the answer thanks to iPhilip:

Code: Select all

; REMOVED: #NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode("Input")  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir(A_ScriptDir)  ; Ensures a consistent starting directory.
#SingleInstance Force
; TraySetIcon("imageres.dll", "262") ; makes the icon into two window


; Simple Window Drag 
; --------------------------------------------------
; version : 1.0.0
; -> Script by Tomé Sulmont (tome.sulmont@laposte.net)
;
; Includes modified versions of :
; 	- Easy Window Dragging KDE style - by Jonny
; 	- Middle Mouse Button Gestures (diagonal) - by Drozdman
;	- Hyper Window Snap - by Andrew Moore and Jeff Axelrod
;
; https://www.autohotkey.com
;
; The goal with this script is to easily snap, move and resize windows with a single
; key press and a mouse :
;   1) Hold down the LWin key and LEFT-click anywhere inside a window to drag it to
;   a new location.
; 	2) Hold down LWin and RIGHT-click-drag anywhere inside a window to easily resize it.
;   3) Hold down LWin and MIDDLE-click-drag to perform different actions : maximize,
;   always on top or snap a window.
; 	4) Hold down LWin and MIDDLE-click without moving to minimize the window under
;   the mouse cursor.
;
; Shortcuts :
;  LWin + Left Button   + Drag					    : Move a window.
;  LWin + Right Button  + Drag						: Resize a window.
;  LWin + Middle Button + Drag Up					: Maximize/Restore a window.
;  LWin + Middle Button + Drag Down 					: Always On Top a window.
;  LWin + Middle Button + Drag Right 				: Snap to the Right half.
;  LWin + Middle Button + Drag Left 					: Snap to the Left half.
;  LWin + Middle Button + Drag Top Right Corner 		: Snap to the Top-Right quarter.
;  LWin + Middle Button + Drag Top Left Corner 		: Snap to the Top-Left quarter.
;  LWin + Middle Button + Drag Bottom Right Corner 	: Snap to Bottom-Right quarter.
;  LWin + Middle Button + Drag Bottom Left Corner 	: Snap to the Bottom-Left quarter.
;  LWin + Middle Button + Motionless 				: Minimize a window.
;  LWin + Numpad                                     : Snap the active window.

; Note
; --------------------------------------------------
; In my case, LWin is remapped to Caps Lock with PowerToy (because "Capslock::LWin" doesn't work)
If (VerCompare(A_AhkVersion, "1.0.39.00") < 0) {
    msgResult := MsgBox("This script may not work properly with your version of AutoHotkey. Continue?", "", 20)
    if (msgResult = "No")
        ExitApp()
}


; Easy Window Dragging
; --------------------------------------------------
; This is the setting that runs smoothest on my system. Depending on your video card and cpu power, you may want to raise or lower this value.
SetWinDelay(2)
CoordMode("Mouse")
return


; Mouse Gesture
; --------------------------------------------------
LWin & LButton:: {
    MouseGetPos(, , &KDE_id) ; Get the window id
    ; Abort if it's the desktop.
    ClassWin := WinGetClass("ahk_id " KDE_id)
    if (ClassWin = "WorkerW")
        return
    ; If the window is maximized, restore the initial position
    ; and size of the window and center the mouse.
    KDE_Win := WinGetMinMax("ahk_id " KDE_id)
    If KDE_Win {
        WinRestore("ahk_id " KDE_id)
        WinGetPos(&KDE_WinX1, &KDE_WinY1, &KDE_WinW, &KDE_WinH, "ahk_id " KDE_id)
        MouseMove((KDE_WinX1 + (KDE_WinW / 2)), (KDE_WinY1 + (KDE_WinH / 2)), 0)
    }

    ; Move the window.
    MouseGetPos(&KDE_X1, &KDE_Y1)
    WinGetPos(&KDE_WinX1, &KDE_WinY1, , , "ahk_id " KDE_id)
    Loop {
        KDE_Button := GetKeyState("LButton", "P") ? "D" : "U" ; Break if button has been released.
        if (KDE_Button = "U")
            break
        MouseGetPos(&KDE_X2, &KDE_Y2) ; Get the current mouse position.
        KDE_X2 -= KDE_X1 ; Obtain an offset from the initial mouse position.
        KDE_Y2 -= KDE_Y1
        KDE_WinX2 := (KDE_WinX1 + KDE_X2) ; Apply this offset to the window position.
        KDE_WinY2 := (KDE_WinY1 + KDE_Y2)
        WinMove(KDE_WinX2, KDE_WinY2, , , "ahk_id " KDE_id) ; Move the window to the new position.
    }
    return
}
LWin & RButton:: {
    ; Get the mouse position and window id,
    MouseGetPos(&KDE_X1, &KDE_Y1, &KDE_id)
    ; Abort if it's the desktop.
    ClassWin := WinGetClass("ahk_id " KDE_id)
    if (ClassWin = "WorkerW")
        return
    ; Abort if the window is maximized.
    KDE_Win := WinGetMinMax("ahk_id " KDE_id)
    If KDE_Win
        return
    ; Get the initial window position and size.
    WinGetPos(&KDE_WinX1, &KDE_WinY1, &KDE_WinW, &KDE_WinH, "ahk_id " KDE_id)
    ; Define the window region the mouse is currently in.
    ; The four regions are Up and Left, Up and Right, Down and Left, Down and Right.
    If (KDE_X1 < KDE_WinX1 + KDE_WinW / 2)
        KDE_WinLeft := 1
    Else
        KDE_WinLeft := -1
    If (KDE_Y1 < KDE_WinY1 + KDE_WinH / 2)
        KDE_WinUp := 1
    Else
        KDE_WinUp := -1
    Loop {
        KDE_Button := GetKeyState("RButton", "P") ? "D" : "U" ; Break if button has been released.
        if (KDE_Button = "U")
            break
        MouseGetPos(&KDE_X2, &KDE_Y2) ; Get the current mouse position.
        ; Get the current window position and size.
        WinGetPos(&KDE_WinX1, &KDE_WinY1, &KDE_WinW, &KDE_WinH, "ahk_id " KDE_id)
        KDE_X2 -= KDE_X1 ; Obtain an offset from the initial mouse position.
        KDE_Y2 -= KDE_Y1
        ; Then, act according to the defined region.
        WinMove(KDE_WinX1 + (KDE_WinLeft + 1) / 2 * KDE_X2, KDE_WinY1 + (KDE_WinUp + 1) / 2 * KDE_Y2, KDE_WinW - KDE_WinLeft * KDE_X2, KDE_WinH - KDE_WinUp * KDE_Y2, "ahk_id " KDE_id)  ; X of resized window
        KDE_X1 := (KDE_X2 + KDE_X1) ; Reset the initial position for the next iteration.
        KDE_Y1 := (KDE_Y2 + KDE_Y1)
    }
    return
}
LWin & MButton:: {
    MouseGetPos(&X1, &Y1, &KDE_id) ; Get the window id
    ; Abort if it's the desktop.
    ClassWin := WinGetClass("ahk_id " KDE_id)
    if (ClassWin = "WorkerW")
        return
    KeyWait("MButton")
    MouseGetPos(&X2, &Y2)
    MinTime := 50 ; Set` A_TimeSinceThisHotkey
    LongTime := 200 ; Set A_TimeSinceThisHotkey to avoid hiting Gesture down by accident
    Tolerance := 60 ; Tolerance of the gesture
    if (A_TimeSinceThisHotkey > MinTime AND X2 - X1 > 0 AND Y2 - Y1 < 0 AND Abs(X2 - X1) >= Tolerance AND Abs(Y2 - Y1) >= Tolerance) {
        GestureTR(KDE_id)	; gesture top/right
    }
    else if (A_TimeSinceThisHotkey > MinTime AND X2 - X1 > 0 AND Y2 - Y1 > 0 AND Abs(X2 - X1) >= Tolerance AND Abs(Y2 - Y1) >= Tolerance) {
        GestureDR(KDE_id)	; gesture down/right
    }
    else if (A_TimeSinceThisHotkey > MinTime AND X2 - X1 < 0 AND Y2 - Y1 < 0 AND Abs(X2 - X1) >= Tolerance AND Abs(Y2 - Y1) >= Tolerance) {
        GestureTL(KDE_id)	; gesture top/left
    }
    else if (A_TimeSinceThisHotkey > MinTime AND X2 - X1 < 0 AND Y2 - Y1 > 0 AND Abs(X2 - X1) >= Tolerance AND Abs(Y2 - Y1) >= Tolerance) {
        GestureDL(KDE_id)	; gesture down/left
    }
    else if (A_TimeSinceThisHotkey > MinTime AND Y2 - Y1 < 0 AND Abs(Y2 - Y1) >= Tolerance AND Abs(X2 - X1) < Tolerance) {
        GestureU(KDE_id)	; gesture up
    }
    else if (A_TimeSinceThisHotkey > LongTime AND Y2 - Y1 > 0 AND Abs(Y2 - Y1) >= Tolerance AND Abs(X2 - X1) < Tolerance) {
        GestureD(KDE_id)	; Gesture down
    }
    else if (A_TimeSinceThisHotkey > MinTime AND X2 - X1 < 0 AND Abs(X2 - X1) >= Tolerance AND Abs(Y2 - Y1) < Tolerance) {
        GestureL(KDE_id)	; gesture left
    }
    else if (A_TimeSinceThisHotkey > MinTime AND X2 - X1 > 0 AND Abs(X2 - X1) >= Tolerance AND Abs(Y2 - Y1) < Tolerance) {
        GestureR(KDE_id)	; gesture right
    }
    else if ((X1 = X2) and (Y1 = Y2)) {
        NoMove(KDE_id)		; gesture no move
    }
    return
}


; Hyper Window Snap
; --------------------------------------------------
SnapActiveWindow(winPlaceVertical, winPlaceHorizontal, winSizeHeight) {
    heightOffset := 7
    widthOffset := 15
    xOffset := 7

    activeWin := WinExist("A")
    activeMon := GetMonitorIndexFromWindow(activeWin)
    MinMaxState := WinGetMinMax("A")
    If (MinMaxState) {
        WinRestore("A")
    }

    MonitorGetWorkArea(activeMon, &MonitorWorkAreaLeft, &MonitorWorkAreaTop, &MonitorWorkAreaRight, &MonitorWorkAreaBottom)

    if (winSizeHeight == "half") {
        height := (MonitorWorkAreaBottom - MonitorWorkAreaTop) / 2 + heightOffset
    } else if (winSizeHeight == "full") {
        height := (MonitorWorkAreaBottom - MonitorWorkAreaTop) + heightOffset
    } else if (winSizeHeight == "third") {
        height := (MonitorWorkAreaBottom - MonitorWorkAreaTop) / 3
    }

    if (winPlaceHorizontal == "left") {
        posX := MonitorWorkAreaLeft - xOffset
        width := (MonitorWorkAreaRight - MonitorWorkAreaLeft) / 2 + widthOffset
    } else if (winPlaceHorizontal == "right") {
        posX := MonitorWorkAreaLeft + (MonitorWorkAreaRight - MonitorWorkAreaLeft) / 2 - xOffset
        width := (MonitorWorkAreaRight - MonitorWorkAreaLeft) / 2 + widthOffset
    } else {
        posX := MonitorWorkAreaLeft - xOffset
        width := MonitorWorkAreaRight - MonitorWorkAreaLeft + widthOffset
    }

    if (winPlaceVertical == "bottom") {
        posY := MonitorWorkAreaBottom - height + heightOffset
    } else if (winPlaceVertical == "middle") {
        posY := MonitorWorkAreaTop + height
    } else {
        posY := MonitorWorkAreaTop
    }

    WinMove(posX, posY, width, height, "A")
}

GetMonitorIndexFromWindow(windowHandle) {
    ; Starts with 1.
    monitorIndex := 1

    monitorInfo := Buffer(40)
    NumPut('UInt', 40, monitorInfo)
    

    if (monitorHandle := DllCall("MonitorFromWindow", "Ptr", windowHandle, "UInt", 0x2))
        && DllCall("GetMonitorInfo", "Ptr", monitorHandle, "Ptr", 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, "UInt") & 1

            monitorCount := MonitorGetCount()

            Loop monitorCount {
                MonitorGet(A_Index, &tempMonLeft, &tempMonTop, &tempMonRight, &tempMonBottom)

                ; 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
}


; Set actions
; --------------------------------------------------
; Add Title Id to diferanciate diferent multiple instances (explorer or chrome for exemple) ?
GestureTR(KDE_id) {	; gesture top/right
    WinActivate("ahk_id " KDE_id) ; Activate the window
    SnapActiveWindow("top", "right", "half")
    return
}
GestureDR(KDE_id) {	; gesture down/right
    WinActivate("ahk_id " KDE_id) ; Activate the window
    SnapActiveWindow("bottom", "right", "half")
    return
}
GestureTL(KDE_id) {	; gesture top/left
    WinActivate("ahk_id " KDE_id) ; Activate the window
    SnapActiveWindow("top", "left", "half")
    return
}
GestureDL(KDE_id) {	; gesture down/left
    WinActivate("ahk_id " KDE_id) ; Activate the window
    SnapActiveWindow("bottom", "left", "half")
    return
}
GestureU(KDE_id) {	; gesture up
    ; Toggle between maximized and restored state.
    KDE_Win := WinGetMinMax("ahk_id " KDE_id)
    If KDE_Win
        WinRestore("ahk_id " KDE_id)
    Else
        WinMaximize("ahk_id " KDE_id)
    return
}
GestureD(KDE_id) {	; Gesture down
    WinActivate("KDE_id") ; Activate the window
    WinSetAlwaysOnTop(-1, "ahk_id " KDE_id)
    return
}
GestureL(KDE_id) {	; gesture left
    WinActivate("ahk_id " KDE_id) ; Activate the window
    SnapActiveWindow("top", "left", "full")
    return
}
GestureR(KDE_id) { ; gesture right
    WinActivate("ahk_id " KDE_id) ; Activate the window
    SnapActiveWindow("top", "right", "full")
    return
}
NoMove(KDE_id) { ; gesture no move
    WinMinimize("ahk_id " KDE_id) ; Minimize the window
    return
}


; Win + Numpad = Snap to conrners for diagonals, or top, bottom, left, right of screen (Landscape)
; --------------------------------------------------
LWin & Numpad1:: {
    ClassWin := WinGetClass("A") ; Abort if it's the desktop.
    if (ClassWin = "WorkerW")
        return
    SnapActiveWindow("bottom", "left", "half")
    return
}
LWin & Numpad2:: {
    ClassWin := WinGetClass("A") ; Abort if it's the desktop.
    if (ClassWin = "WorkerW")
        return
    SnapActiveWindow("bottom", "full", "half")
    return
}
LWin & Numpad3:: {
    ClassWin := WinGetClass("A") ; Abort if it's the desktop.
    if (ClassWin = "WorkerW")
        return
    SnapActiveWindow("bottom", "right", "half")
    return
}
LWin & Numpad4:: {
    ClassWin := WinGetClass("A") ; Abort if it's the desktop.
    if (ClassWin = "WorkerW")
        return
    SnapActiveWindow("top", "left", "full")
    return
}
LWin & Numpad5:: {
    ClassWin := WinGetClass("A") ; Abort if it's the desktop.
    if (ClassWin = "WorkerW")
        return
    KDE_Win := WinGetMinMax("A")
    If KDE_Win
        WinRestore("A")
    Else
        WinMaximize("A")
    return
}
LWin & Numpad6:: {
    ClassWin := WinGetClass("A") ; Abort if it's the desktop.
    if (ClassWin = "WorkerW")
        return
    SnapActiveWindow("top", "right", "full")
    return
}
LWin & Numpad7:: {
    ClassWin := WinGetClass("A") ; Abort if it's the desktop.
    if (ClassWin = "WorkerW")
        return
    SnapActiveWindow("top", "left", "half")
    return
}
LWin & Numpad8:: {
    ClassWin := WinGetClass("A") ; Abort if it's the desktop.
    if (ClassWin = "WorkerW")
        return
    SnapActiveWindow("top", "full", "half")
    return
}
LWin & Numpad9:: {
    ClassWin := WinGetClass("A") ; Abort if it's the desktop.
    if (ClassWin = "WorkerW")
        return
    SnapActiveWindow("top", "right", "half")
    return
}

Post Reply

Return to “Ask for Help (v2)”