Skip to content

Commit

Permalink
added padAtMonitorEdges setting
Browse files Browse the repository at this point in the history
  • Loading branch information
imthenachoman committed Oct 4, 2023
1 parent 97fedaa commit 28bbfe4
Show file tree
Hide file tree
Showing 3 changed files with 194 additions and 144 deletions.
276 changes: 151 additions & 125 deletions ExquisiteW.ahk
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#SingleInstance Force

; GLOBAL CONSTANTS
VERSION := "v1.0.0"
VERSION := "v1.1.0"
GITHUB_REPO := "imthenachoman/ExquisiteW"
HELP_URL := "https://github.com/" GITHUB_REPO

Expand Down Expand Up @@ -129,8 +129,9 @@ CreateGUI()
; read the layouts
layoutsData := JSON.parse(FileRead(A_ScriptDir "\layouts.json"))

; read global windowPaddingInPixels
; read global settings
windowPaddingInPixels_global := layoutsData.has("windowPaddingInPixels") ? layoutsData["windowPaddingInPixels"] : 0
padAtMonitorEdges_global := layoutsData.has("padAtMonitorEdges" ) ? layoutsData["padAtMonitorEdges" ] : false

; how many columns of layouts will we have
numberOfActualColumnsInGUI := layoutsData["layouts"].Length < setting_NumberOfLayoutsInARow ? layoutsData["layouts"].Length : setting_NumberOfLayoutsInARow
Expand Down Expand Up @@ -164,6 +165,7 @@ CreateGUI()
{
; get global zone
windowPaddingInPixels_layout := layoutSpecification.Has("windowPaddingInPixels") ? layoutSpecification["windowPaddingInPixels"] : windowPaddingInPixels_global
padAtMonitorEdges_layout := layoutSpecification.Has("padAtMonitorEdges" ) ? layoutSpecification["padAtMonitorEdges" ] : padAtMonitorEdges_global

; add a group box
layoutSelectorGUI.Add("GroupBox", "Section" groupBoxLeftPosition groupBoxTopPosition " w" setting_LayoutBoxWidthInPixels " h" setting_LayoutBoxHeightInPixels, " " layoutSpecification["name"] " ")
Expand All @@ -179,7 +181,8 @@ CreateGUI()
layoutZoneSpecification_activator := layoutZoneSpecification.Has("activator") ? "&" SubStr(layoutZoneSpecification["activator"], 1, 1) : ""
layoutZoneSpecification_hotkey := layoutZoneSpecification.Has("hotkey") ? layoutZoneSpecification["hotkey"] : ""

windowPaddingInPixels_zone := layoutZoneSpecification.Has("windowPaddingInPixels") ? layoutZoneSpecification["windowPaddingInPixels"] : windowPaddingInPixels_layout
windowPaddingInPixels_zone := layoutZoneSpecification.Has("windowPaddingInPixels") ? layoutZoneSpecification["windowPaddingInPixels"] : windowPaddingInPixels_layout
padAtMonitorEdges_zone := layoutZoneSpecification.Has("padAtMonitorEdges" ) ? layoutZoneSpecification["padAtMonitorEdges" ] : padAtMonitorEdges_layout

; figure out where the button will go
buttonLeft := "xs+" groupBoxInsidePadding + (layoutButtonsAvailableAreaWidthInPixels / 12) * layoutZoneSpecification_topLeftColumnNumber
Expand All @@ -194,11 +197,11 @@ CreateGUI()
layoutSelectorButtons.Push(zoneButton)

; add a click event for the button
zoneButton.OnEvent("Click", ZoneButtonClick.Bind("Normal", layoutZoneSpecification_topLeftRowNumber, layoutZoneSpecification_topLeftColumnNumber, layoutZoneSpecification_numberOfRows, layoutZoneSpecification_numberOfColumns, windowPaddingInPixels_zone))
zoneButton.OnEvent("Click", ZoneButtonClick.Bind("Normal", layoutZoneSpecification_topLeftRowNumber, layoutZoneSpecification_topLeftColumnNumber, layoutZoneSpecification_numberOfRows, layoutZoneSpecification_numberOfColumns, windowPaddingInPixels_zone, padAtMonitorEdges_zone))

if (layoutZoneSpecification_hotkey)
{
Hotkey layoutZoneSpecification_hotkey, ZoneShortcutResponse.Bind(layoutZoneSpecification_topLeftRowNumber, layoutZoneSpecification_topLeftColumnNumber, layoutZoneSpecification_numberOfRows, layoutZoneSpecification_numberOfColumns, windowPaddingInPixels_zone)
Hotkey layoutZoneSpecification_hotkey, ZoneGlobalShortcutResponse.Bind(layoutZoneSpecification_topLeftRowNumber, layoutZoneSpecification_topLeftColumnNumber, layoutZoneSpecification_numberOfRows, layoutZoneSpecification_numberOfColumns, windowPaddingInPixels_zone, padAtMonitorEdges_zone)
}
}

Expand Down Expand Up @@ -294,117 +297,6 @@ CreateGUI()
layoutSelectorGUI.GetPos(&junk, &junk, &layoutSelectorGUIWidth, &layoutSelectorGUIHeight)
}

; removes blue border from button remaining after clicking
WM_REMOVESTATE(wParam, lParam, msg, hwnd)
{
ControlSetStyle(-0x1, lParam, "ahk_id " hwnd)
return
}

ProcessUserInput(*)
{
global layoutSelectorGUI

layoutSelectorGUI.hide()
return
}

ReloadExquisiteW(*)
{
if A_IsCompiled
Run Format('"{1}" /force /restart', A_ScriptFullPath)
else
Run Format('"{1}" /force /restart "{2}" reloaded', A_AhkPath, A_ScriptFullPath)
ExitApp

return
}

; run when a buttin in the GUI is clicked
ZoneButtonClick(A_GuiEvent, Info*)
{
; get the zone spec details
layoutZoneSpecification_topLeftRowNumber := Info[1]
layoutZoneSpecification_topLeftColumnNumber := Info[2]
layoutZoneSpecification_numberOfRows := Info[3]
layoutZoneSpecification_numberOfColumns := Info[4]
paddingInPixels := Info[5]

; get the monitor index to send the window to
submitInfo := layoutSelectorGUI.Submit(false)
monitorIndex := submitInfo.HasOwnProp("monitorSelection") ? submitInfo.monitorSelection : 1

MoveAndResizeWindow(targetWindowToMoveAndResizeWindowHandleID, layoutZoneSpecification_topLeftRowNumber, layoutZoneSpecification_topLeftColumnNumber, layoutZoneSpecification_numberOfRows, layoutZoneSpecification_numberOfColumns, paddingInPixels, monitorIndex)

return
}

; gets info about the target window that needs to be moved
GetTargetWindowToMoveAndResizeInfo(&mousePositionLeft, &mousePositionTop, &windowUnderMouseHandleID, &monitorDetails)
{
; https://www.autohotkey.com/boards/viewtopic.php?p=540587#p540587
; Progman = Desktop
; WorkerW = Explorer Thread. WorkerW comes to the foreground when you press Win + D (minimize all windows)
; Shell_TrayWnd = TaskBar
; Shell_SecondaryTrayWnd = 2nd TaskBar
static windowsToAvoid := 'WorkerW Shell_TrayWnd Shell_SecondaryTrayWnd Progman'

; we want mouse position based on screen, so temporarily set the current coordinate mode
Local CMM := A_CoordModeMouse
A_CoordModeMouse := "Screen"
; get the mouse position and the window handle ID of the active window
MouseGetPos(&mousePositionLeft, &mousePositionTop, &windowUnderMouseHandleID)
; change coordinate mode back
A_CoordModeMouse := CMM

; if the trigger was run when the mouse is over the GUI, then don't do anything
if (windowUnderMouseHandleID = layoutSelectorGUIWindowHandleID)
{
TrayTip "ExquisiteW is already open.", "ExquisiteW Warning", "Mute Icon!"
return false
}

if (windowUnderMouseHandleID = "")
{
TrayTip "Cannot get the window under the mouse.", "ExquisiteW Error", "Mute Iconx"
return false
}

; get the PID of the window and see if it is running elevated
if isAdminCheckForMovingWindowsNeeded and (IsProcessElevated(WinGetPID("ahk_id " windowUnderMouseHandleID)) = 1)
{
TrayTip "Cannot interact with applications running as administrator.", "ExquisiteW Error", "Mute Iconx"
return false
}

if InStr(windowsToAvoid, WinGetClass('ahk_id ' windowUnderMouseHandleID))
{
TrayTip "Not over a window.", "ExquisiteW Error", "Mute Icon!"
return false
}

; set the target window to move
global targetWindowToMoveAndResizeWindowHandleID := windowUnderMouseHandleID

; get the details of the monitor the mouse is on
monitorDetails := getDetailsOfMonitorMouseIsIn(&mousePositionLeft, &mousePositionTop)

return true
}

; runs when a global zone shortcut is run
ZoneShortcutResponse(topLeftRowNumber, topLeftColumnNumber, numberOfRows, numberOfColumns, paddingInPixels, *)
{
; get necessary details
if !GetTargetWindowToMoveAndResizeInfo(&mousePositionLeft, &mousePositionTop, &windowUnderMouseHandleID, &monitorDetails)
{
return
}

; move the window
MoveAndResizeWindow(windowUnderMouseHandleID, topLeftRowNumber, topLeftColumnNumber, numberOfRows, numberOfColumns, paddingInPixels, monitorDetails.index)
}

; show the GUI
ShowGUI(ThisHotKey)
{
Expand All @@ -418,13 +310,13 @@ ShowGUI(ThisHotKey)

; set the active application text the window the mouse was over
layoutSelectorGUI["activeApplicationName"].Text := WinGetProcessName(windowUnderMouseHandleID) " > " WinGetTitle(windowUnderMouseHandleID)

; if there are multiple monitors
; update the selected radio
if (allMonitorDetails.Length > 1)
{
; select the current monitor radio button
firstMonitorRadioButtonNN := ControlGetClassNN(layoutSelectorGUI["monitorSelection"])
firstMonitorRadioButtonNN := ControlGetClassNN(layoutSelectorGUI["monitorSelection"])
firstMonitorRadioButtonNumber := SubStr(firstMonitorRadioButtonNN, 7)
layoutSelectorGUI['Button' . (firstMonitorRadioButtonNumber + monitorDetails.index - 1)].Value := 1
}
Expand All @@ -433,7 +325,7 @@ ShowGUI(ThisHotKey)
; for that we need to know the top/left of the GUI based on the mouse
layoutSelectorGUILeft := mousePositionLeft - round(layoutSelectorGUIWidth / 2)
; but we need to account for situations where the mouse is near the edge and the GUI will be offscreen
if(layoutSelectorGUILeft < monitorDetails.workArea.Left)
if (layoutSelectorGUILeft < monitorDetails.workArea.Left)
{
layoutSelectorGUILeft := monitorDetails.workArea.Left
}
Expand All @@ -443,7 +335,7 @@ ShowGUI(ThisHotKey)
}

layoutSelectorGUITop := mousePositionTop - round(layoutSelectorGUIHeight / 2)
if(layoutSelectorGUITop < monitorDetails.workArea.Top)
if (layoutSelectorGUITop < monitorDetails.workArea.Top)
{
layoutSelectorGUITop := monitorDetails.workArea.Top
}
Expand All @@ -461,8 +353,55 @@ ShowGUI(ThisHotKey)
return
}

ReloadExquisiteW(*)
{
if A_IsCompiled
Run Format('"{1}" /force /restart', A_ScriptFullPath)
else
Run Format('"{1}" /force /restart "{2}" reloaded', A_AhkPath, A_ScriptFullPath)
ExitApp

return
}

; run when a buttin in the GUI is clicked
ZoneButtonClick(A_GuiEvent, Info*)
{
; get the zone spec details
layoutZoneSpecification_topLeftRowNumber := Info[1]
layoutZoneSpecification_topLeftColumnNumber := Info[2]
layoutZoneSpecification_numberOfRows := Info[3]
layoutZoneSpecification_numberOfColumns := Info[4]
windowPaddingInPixels := Info[5]
padAtMonitorEdges := Info[6]


; get the monitor index to send the window to
submitInfo := layoutSelectorGUI.Submit(false)
monitorIndex := submitInfo.HasOwnProp("monitorSelection") ? submitInfo.monitorSelection : 1

MoveAndResizeWindow(targetWindowToMoveAndResizeWindowHandleID, layoutZoneSpecification_topLeftRowNumber, layoutZoneSpecification_topLeftColumnNumber, layoutZoneSpecification_numberOfRows, layoutZoneSpecification_numberOfColumns, windowPaddingInPixels, padAtMonitorEdges, monitorIndex)

return
}

; runs when a global zone shortcut is run
ZoneGlobalShortcutResponse(topLeftRowNumber, topLeftColumnNumber, numberOfRows, numberOfColumns, windowPaddingInPixels, padAtMonitorEdges, *)
{
; get necessary details
if !GetTargetWindowToMoveAndResizeInfo(&mousePositionLeft, &mousePositionTop, &windowUnderMouseHandleID, &monitorDetails)
{
return
}

; move the window
MoveAndResizeWindow(windowUnderMouseHandleID, topLeftRowNumber, topLeftColumnNumber, numberOfRows, numberOfColumns, windowPaddingInPixels, padAtMonitorEdges, monitorDetails.index)

return
}

; move the window
MoveAndResizeWindow(windowHandleID, topLeftRowNumber, topLeftColumnNumber, numberOfRows, numberOfColumns, paddingInPixels, monitorIndex)
MoveAndResizeWindow(windowHandleID, topLeftRowNumber, topLeftColumnNumber, numberOfRows, numberOfColumns, windowPaddingInPixels, padAtMonitorEdges, monitorIndex)
{
; we want modal msgbox (https://www.autohotkey.com/docs/v2/lib/Gui.htm#OwnDialogs)
layoutSelectorGUI.Opt("+OwnDialogs")
Expand All @@ -485,10 +424,29 @@ MoveAndResizeWindow(windowHandleID, topLeftRowNumber, topLeftColumnNumber, numbe
clientWindowBottomPadding := NumGet(targetWindowToMoveAndResizeWindowInfo, 16, "int") - NumGet(targetWindowToMoveAndResizeWindowInfo, 32, "int")

; calculate the window's new dimensions
newLeft := monitorDetails.workArea.left + (monitorDetails.workArea.width * topLeftColumnNumber / 12) - clientWindowLeftPadding + paddingInPixels
newTop := monitorDetails.workArea.top + (monitorDetails.workArea.height * topLeftRowNumber / 12) + paddingInPixels
newWidth := (monitorDetails.workArea.width * numberOfColumns / 12) + clientWindowLeftPadding + clientWindowRightPadding - paddingInPixels - paddingInPixels
newHeight := (monitorDetails.workArea.height * numberOfRows / 12) + clientWindowBottomPadding - paddingInPixels - paddingInPixels
newLeft := monitorDetails.workArea.left + (monitorDetails.workArea.width * topLeftColumnNumber / 12) - clientWindowLeftPadding ; + windowPaddingInPixels
newTop := monitorDetails.workArea.top + (monitorDetails.workArea.height * topLeftRowNumber / 12) ; + windowPaddingInPixels
newWidth := (monitorDetails.workArea.width * numberOfColumns / 12) + clientWindowLeftPadding + clientWindowRightPadding ; - windowPaddingInPixels - windowPaddingInPixels
newHeight := (monitorDetails.workArea.height * numberOfRows / 12) + clientWindowBottomPadding ; - windowPaddingInPixels - windowPaddingInPixels

if ((topLeftColumnNumber = 0) and padAtMonitorEdges) or topLeftColumnNumber != 0
{
newLeft += windowPaddingInPixels
newWidth -= windowPaddingInPixels
}
if ((topLeftRowNumber = 0) and padAtMonitorEdges) or topLeftRowNumber != 0
{
newTop += windowPaddingInPixels
newHeight -= windowPaddingInPixels
}
if (((topLeftColumnNumber + numberOfColumns) = 12) and padAtMonitorEdges) or ((topLeftColumnNumber + numberOfColumns) != 12)
{
newWidth -= windowPaddingInPixels
}
if (((topLeftRowNumber + numberOfRows) = 12) and padAtMonitorEdges) or ((topLeftRowNumber + numberOfRows) != 12)
{
newHeight -= windowPaddingInPixels
}

; get the status of the current window
WinStatus := WinGetMinMax("ahk_id " targetWindowToMoveAndResizeWindowHandleID)
Expand All @@ -514,6 +472,59 @@ MoveAndResizeWindow(windowHandleID, topLeftRowNumber, topLeftColumnNumber, numbe
return
}

; gets info about the target window that needs to be moved
GetTargetWindowToMoveAndResizeInfo(&mousePositionLeft, &mousePositionTop, &windowUnderMouseHandleID, &monitorDetails)
{
; https://www.autohotkey.com/boards/viewtopic.php?p=540587#p540587
; Progman = Desktop
; WorkerW = Explorer Thread. WorkerW comes to the foreground when you press Win + D (minimize all windows)
; Shell_TrayWnd = TaskBar
; Shell_SecondaryTrayWnd = 2nd TaskBar
static windowsToAvoid := 'WorkerW Shell_TrayWnd Shell_SecondaryTrayWnd Progman'

; we want mouse position based on screen, so temporarily set the current coordinate mode
Local CMM := A_CoordModeMouse
A_CoordModeMouse := "Screen"
; get the mouse position and the window handle ID of the active window
MouseGetPos(&mousePositionLeft, &mousePositionTop, &windowUnderMouseHandleID)
; change coordinate mode back
A_CoordModeMouse := CMM

; if the trigger was run when the mouse is over the GUI, then don't do anything
if (windowUnderMouseHandleID = layoutSelectorGUIWindowHandleID)
{
TrayTip "ExquisiteW is already open.", "ExquisiteW Warning", "Mute Icon!"
return false
}

if (windowUnderMouseHandleID = "")
{
TrayTip "Cannot get the window under the mouse.", "ExquisiteW Error", "Mute Iconx"
return false
}

; get the PID of the window and see if it is running elevated
if isAdminCheckForMovingWindowsNeeded and (IsProcessElevated(WinGetPID("ahk_id " windowUnderMouseHandleID)) = 1)
{
TrayTip "Cannot interact with applications running as administrator.", "ExquisiteW Error", "Mute Iconx"
return false
}

if InStr(windowsToAvoid, WinGetClass('ahk_id ' windowUnderMouseHandleID))
{
TrayTip "Not over a window.", "ExquisiteW Error", "Mute Icon!"
return false
}

; set the target window to move
global targetWindowToMoveAndResizeWindowHandleID := windowUnderMouseHandleID

; get the details of the monitor the mouse is on
monitorDetails := getDetailsOfMonitorMouseIsIn(&mousePositionLeft, &mousePositionTop)

return true
}

; get details about all the connected monitors
getAllMonitorDetails()
{
Expand Down Expand Up @@ -613,4 +624,19 @@ CheckFoUpdates_Ready(req)

MsgBox("Latest AutoHotkey version: " req.responseText, "ExquisiteW Update Error", "Iconx 0x1000")
}
}

; removes blue border from button remaining after clicking
WM_REMOVESTATE(wParam, lParam, msg, hwnd)
{
ControlSetStyle(-0x1, lParam, "ahk_id " hwnd)
return
}

ProcessUserInput(*)
{
global layoutSelectorGUI

layoutSelectorGUI.hide()
return
}
Loading

0 comments on commit 28bbfe4

Please sign in to comment.