-
Notifications
You must be signed in to change notification settings - Fork 1
/
resize.ahk
305 lines (240 loc) · 9.41 KB
/
resize.ahk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
#Requires AutoHotkey v2.0
#SingleInstance force
; Options
modKey := "lwin"
CoordMode "mouse", "screen"
SetWinDelay 0
monitorWidth := sysget(16)
monitorHeight := sysget(17)
hotif "not filters()"
hotkey modKey " & WheelUp", increaseOpacity
hotkey modKey " & WheelDown", decreaseOpacity
hotkey modKey " & LButton", move
hotkey modkey " & RButton", resize
hotkey modkey " & MButton", minimize
hotif
#hotif not filters()
filters() {
MouseGetPos , , &pid
; disable hotkey if desktop is active
if (WinGetTitle(pid) = "Program Manager" or WinGetTitle(pid) = "") {
return true
}
return false
}
move(_) {
static lastClickTime := 0
doubleClickThreshold := 300 ; Adjust as needed
MouseGetPos &mX, &mY, &pid
currentTime := A_TickCount
timeSinceLastClick := currentTime - lastClickTime
lastClickTime := currentTime
if (timeSinceLastClick <= doubleClickThreshold) {
lastClickTime := 0
; Double click detected, toggle maximize/restore
if (WinGetMinMax(pid) = 1) {
WinRestore pid
} else {
WinMaximize pid
}
}
windowState := WinGetMinMax(pid)
SetSystemCursor('SIZEALL')
; Check if the window is maximized or in fullscreen
if (windowState = 1 || isFullScreen()) {
initialMonitor := SysGetMonitorContainingPoint(mX, mY)
while (IsModPlusKeyHeld("LButton")) {
MouseGetPos ¤tMX, ¤tMY
currentMonitor := SysGetMonitorContainingPoint(currentMX, currentMY)
if (initialMonitor != currentMonitor) {
; Snap the window to the new monitor
SnapWindowToMonitor(pid, currentMonitor)
initialMonitor := currentMonitor ; Update the initial monitor to the new one
}
}
} else {
WinGetPos &x, &y, &w, &h, pid
xOffset := x - mX
yOffset := y - mY
WinSetAlwaysOnTop 1, pid
while (IsModPlusKeyHeld("LButton")) {
MouseGetPos &mX, &mY
winmove mX + xOffset, mY + yOffset, , , pid
}
WinSetAlwaysOnTop 0, pid
}
RestoreCursor()
}
resize(_) {
; Get the initial window position and size
MouseGetPos &mX, &mY, &pid
WinGetPos &x, &y, &w, &h, pid
if (WinGetMinMax(pid) = 1) {
WinRestore pid
}
; Initialize the cumulative delta
cumulativeDeltaX := 0
cumulativeDeltaY := 0
; Determine which corners are nearest
isLeft := mX - x < w // 2
isTop := mY - y < h // 2
if (isLeft && isTop) || (!isLeft && !isTop) {
SetSystemCursor("SIZENWSE") ; Top-left or bottom-right corner
} else {
SetSystemCursor("SIZENESW") ; Top-right or bottom-left corner
}
while IsModPlusKeyHeld("RButton") {
MouseGetPos ¤tMX, ¤tMY
deltaX := currentMX - mX
deltaY := currentMY - mY
cumulativeDeltaX += deltaX
cumulativeDeltaY += deltaY
; Set new dimensions based on the nearest corner
newW := isLeft ? w - cumulativeDeltaX : w + cumulativeDeltaX
newH := isTop ? h - cumulativeDeltaY : h + cumulativeDeltaY
; Adjust the window position if dragging from the left or top
newX := isLeft ? x + cumulativeDeltaX : x
newY := isTop ? y + cumulativeDeltaY : y
WinMove newX, newY, newW, newH, pid
mX := currentMX
mY := currentMY
}
RestoreCursor()
}
minimize(_) {
MouseGetPos , , &pid
WinGetPos , , , , pid
WinMinimize(pid)
}
; This function checks which monitor contains the specified point
SysGetMonitorContainingPoint(x, y) {
monitors := []
monitorCount := MonitorGetCount()
Loop monitorCount {
MonitorGet(A_Index, &left, &top, &right, &bottom,)
if (x >= left && x <= right && y >= top && y <= bottom) {
return A_Index
}
}
return 1 ; Default to primary monitor if not found
}
; This function snaps the window to the specified monitor
SnapWindowToMonitor(windowPID, monitorIndex) {
; Get monitor dimensions
MonitorGet(monitorIndex, &MonitorLeft, &MonitorTop, &MonitorRight, &MonitorBottom)
; Restore the window if it is maximized, to be able to move it
WinRestore("ahk_id " . windowPID)
WinGetPos(&windowX, &windowY, &windowWidth, &windowHeight, "ahk_id " . windowPID)
; Move the window to the center of the new monitor
WinMove(MonitorLeft + (MonitorRight - MonitorLeft - windowWidth) // 2, MonitorTop + (MonitorBottom - MonitorTop - windowHeight) // 2, windowWidth, windowHeight, "ahk_id " . windowPID)
; Maximize the window again
WinMaximize("ahk_id " . windowPID)
}
increaseOpacity(_) {
adjustWindowOpacity(10) ; Increase opacity by 10%
}
decreaseOpacity(_) {
adjustWindowOpacity(-10) ; Decrease opacity by 10%
}
adjustWindowOpacity(change) {
MouseGetPos , , &pid
currentOpacity := WinGetTransparent(pid)
currentOpacity := currentOpacity ? currentOpacity : 255 ; If window is not transparent, set to 100%
newOpacity := Ceil(max(64, min(255, currentOpacity + (change * 2.55)))) ; Convert to 255-scale
WinSetTransparent (newOpacity = 255 ? "Off" : newOpacity), pid
}
IsModPlusKeyHeld(key) {
return (getKeyState(modKey) and getKeyState(key, "P"))
}
/*!
Checks if a window is in fullscreen mode.
______________________________________________________________________________________________________________
Usage: isFullScreen()
Return: True/False
GitHub Repo: https://github.com/Nigh/isFullScreen
*/
class isFullScreen
{
static monitors := this.init()
static init()
{
a := []
loop MonitorGetCount()
{
MonitorGet(A_Index, &Left, &Top, &Right, &Bottom)
a.Push({ l: Left, t: Top, r: Right, b: Bottom })
}
Return a
}
static Call()
{
uid := WinExist("A")
if (!uid) {
Return False
}
wid := "ahk_id " uid
c := WinGetClass(wid)
If (uid = DllCall("GetDesktopWindow") Or (c = "Progman") Or (c = "WorkerW")) {
Return False
}
WinGetClientPos(&cx, &cy, &cw, &ch, wid)
cl := cx
ct := cy
cr := cx + cw
cb := cy + ch
For , v in this.monitors
{
if (cl == v.l and ct == v.t and cr == v.r and cb == v.b) {
Return True
}
}
Return False
}
}
; Source: Serenity - https://autohotkey.com/board/topic/32608-changing-the-system-cursor/
; Modified: iseahound - https://www.autohotkey.com/boards/viewtopic.php?t=75867
SetSystemCursor(Cursor := "", cx := 0, cy := 0) {
static SystemCursors := Map("APPSTARTING", 32650, "ARROW", 32512, "CROSS", 32515, "HAND", 32649, "HELP", 32651, "IBEAM", 32513, "NO", 32648,
"SIZEALL", 32646, "SIZENESW", 32643, "SIZENS", 32645, "SIZENWSE", 32642, "SIZEWE", 32644, "UPARROW", 32516, "WAIT", 32514)
if (Cursor = "") {
AndMask := Buffer(128, 0xFF), XorMask := Buffer(128, 0)
for CursorName, CursorID in SystemCursors {
CursorHandle := DllCall("CreateCursor", "ptr", 0, "int", 0, "int", 0, "int", 32, "int", 32, "ptr", AndMask, "ptr", XorMask, "ptr")
DllCall("SetSystemCursor", "ptr", CursorHandle, "int", CursorID) ; calls DestroyCursor
}
return
}
if (Cursor ~= "^(IDC_)?(?i:AppStarting|Arrow|Cross|Hand|Help|IBeam|No|SizeAll|SizeNESW|SizeNS|SizeNWSE|SizeWE|UpArrow|Wait)$") {
Cursor := RegExReplace(Cursor, "^IDC_")
if !(CursorShared := DllCall("LoadCursor", "ptr", 0, "ptr", SystemCursors[StrUpper(Cursor)], "ptr"))
throw Error("Error: Invalid cursor name")
for CursorName, CursorID in SystemCursors {
CursorHandle := DllCall("CopyImage", "ptr", CursorShared, "uint", 2, "int", cx, "int", cy, "uint", 0, "ptr")
DllCall("SetSystemCursor", "ptr", CursorHandle, "int", CursorID) ; calls DestroyCursor
}
return
}
if FileExist(Cursor) {
SplitPath Cursor, , , &Ext := "" ; auto-detect type
if !(uType := (Ext = "ani" || Ext = "cur") ? 2 : (Ext = "ico") ? 1 : 0)
throw Error("Error: Invalid file type")
if (Ext = "ani") {
for CursorName, CursorID in SystemCursors {
CursorHandle := DllCall("LoadImage", "ptr", 0, "str", Cursor, "uint", uType, "int", cx, "int", cy, "uint", 0x10, "ptr")
DllCall("SetSystemCursor", "ptr", CursorHandle, "int", CursorID) ; calls DestroyCursor
}
} else {
if !(CursorShared := DllCall("LoadImage", "ptr", 0, "str", Cursor, "uint", uType, "int", cx, "int", cy, "uint", 0x8010, "ptr"))
throw Error("Error: Corrupted file")
for CursorName, CursorID in SystemCursors {
CursorHandle := DllCall("CopyImage", "ptr", CursorShared, "uint", 2, "int", 0, "int", 0, "uint", 0, "ptr")
DllCall("SetSystemCursor", "ptr", CursorHandle, "int", CursorID) ; calls DestroyCursor
}
}
return
}
throw Error("Error: Invalid file path or cursor name")
}
RestoreCursor() {
return DllCall("SystemParametersInfo", "uint", SPI_SETCURSORS := 0x57, "uint", 0, "ptr", 0, "uint", 0)
}