Add support to move windows between monitors
This commit is contained in:
parent
2f584d17d0
commit
4804b2f827
1 changed files with 102 additions and 90 deletions
|
@ -1,12 +1,23 @@
|
||||||
log(text)
|
; Returns the rectangle (position & size) of a given monitor.
|
||||||
|
MonitorGetRect(N)
|
||||||
{
|
{
|
||||||
FileAppend(text . "`n", "log.txt")
|
MonitorGetWorkArea(N, &left, &top, &right, &bottom)
|
||||||
|
return {
|
||||||
|
pos: {
|
||||||
|
x: left,
|
||||||
|
y: top,
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
width: Abs(right - left),
|
||||||
|
height: Abs(bottom - top),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
; Return the number of the monitor that contains a window.
|
; Return the number of the monitor that contains a window.
|
||||||
getMonitor(winId:="A")
|
WinGetMonitor(WinTitle:="A")
|
||||||
{
|
{
|
||||||
WinGetPos(&x,, &width,, winId)
|
WinGetPos(&x,, &width,, WinTitle)
|
||||||
midx := x + width // 2
|
midx := x + width // 2
|
||||||
|
|
||||||
Loop MonitorGetCount() {
|
Loop MonitorGetCount() {
|
||||||
|
@ -18,122 +29,123 @@ getMonitor(winId:="A")
|
||||||
return MonitorGetPrimary() ; fallback to primary if none found
|
return MonitorGetPrimary() ; fallback to primary if none found
|
||||||
}
|
}
|
||||||
|
|
||||||
; Returns the bound of the monitor that contains a window.
|
; Center a window without changing its size.
|
||||||
getMonitorBounds(winId:="A")
|
WinCenter(WinTitle:="A")
|
||||||
{
|
{
|
||||||
monitor := getMonitor(winId)
|
WinGetPos(,, &width, &height, WinTitle)
|
||||||
MonitorGetWorkArea(monitor, &left, &top, &right, &bottom)
|
r := MonitorGetRect(WinGetMonitor(WinTitle))
|
||||||
|
x := Round(r.pos.x + r.size.width/2 - width/2)
|
||||||
|
y := Round(r.pos.y + r.size.height/2 - height/2)
|
||||||
|
WinMove(x, y, width, height, WinTitle)
|
||||||
|
}
|
||||||
|
|
||||||
|
; Return the rect (in percentages) of a window in its current monitor.
|
||||||
|
WinGetRelativeRect(WinTitle:="A")
|
||||||
|
{
|
||||||
|
WinGetPos(&x, &y, &width, &height, WinTitle)
|
||||||
|
monitor := WinGetMonitor(WinTitle)
|
||||||
|
rect := MonitorGetRect(monitor)
|
||||||
return {
|
return {
|
||||||
x : left,
|
pos: {
|
||||||
y : top,
|
x: Abs((x - rect.pos.x) / rect.size.width),
|
||||||
width : Abs(right - left),
|
y: Abs((y - rect.pos.y) / rect.size.height),
|
||||||
height : Abs(bottom - top),
|
},
|
||||||
|
size: {
|
||||||
|
width: width / rect.size.width,
|
||||||
|
height: height / rect.size.height,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clamp(n, limit:=1)
|
; Move and resize window to a rect (in percentage) in a given monitor.
|
||||||
|
WinSetRelativeRect(winRect, monitor?, WinTitle:="A")
|
||||||
{
|
{
|
||||||
n := Abs(n)
|
if not IsSet(monitor)
|
||||||
if (n > limit)
|
monitor := WinGetMonitor(WinTitle)
|
||||||
return Mod(n, limit)
|
|
||||||
return n
|
rect := MonitorGetRect(monitor)
|
||||||
|
|
||||||
|
x := Round(rect.pos.x + winRect.pos.x * rect.size.width)
|
||||||
|
y := Round(rect.pos.y + winRect.pos.y * rect.size.height)
|
||||||
|
width := Round( winRect.size.width * rect.size.width)
|
||||||
|
height := Round( winRect.size.height * rect.size.height)
|
||||||
|
|
||||||
|
WinMove(x, y, width, height, WinTitle)
|
||||||
}
|
}
|
||||||
|
|
||||||
; Move and resize window to match spec (x, y, width, height).
|
; Move a window wihtout changing its size.
|
||||||
positionWindow(spec, winId:="A")
|
WinTranslate(dx, dy, WinTitle:="A")
|
||||||
{
|
{
|
||||||
xScale := clamp(spec.x)
|
WinGetPos(&x, &y, &width, &height, WinTitle)
|
||||||
yScale := clamp(spec.y)
|
WinMove(x + dx, y + dy, width, height, WinTitle)
|
||||||
wScale := clamp(spec.w)
|
|
||||||
hScale := clamp(spec.h)
|
|
||||||
|
|
||||||
monitor := getMonitorBounds(winId)
|
|
||||||
|
|
||||||
x := Round(monitor.x + xScale * monitor.width)
|
|
||||||
y := Round(monitor.y + yScale * monitor.height)
|
|
||||||
width := Round( wScale * monitor.width)
|
|
||||||
height := Round( hScale * monitor.height)
|
|
||||||
|
|
||||||
WinMove(x, y, width, height, winId)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
; Center a window without changing its size.
|
; Move a window to a different monitor, ajusting the relative scaling.
|
||||||
centerWindow(winId:="A")
|
WinSetMonitor(target, WinTitle:="A")
|
||||||
{
|
{
|
||||||
WinGetPos(,, &width, &height, winId)
|
WinSetRelativeRect(WinGetRelativeRect(WinTitle), target, WinTitle)
|
||||||
|
|
||||||
monitor := getMonitorBounds(winId)
|
|
||||||
|
|
||||||
x := Round(monitor.x + monitor.width/2 - width/2)
|
|
||||||
y := Round(monitor.y + monitor.height/2 - height/2)
|
|
||||||
|
|
||||||
WinMove(x, y, width, height, winId)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
; Move a window wihtou changing its size.
|
POS := {
|
||||||
moveWindow(dx, dy, winId:="A")
|
|
||||||
{
|
|
||||||
WinGetPos(&x, &y, &width, &height, winId)
|
|
||||||
WinMove(x + dx, y + dy, width, height, winId)
|
|
||||||
}
|
|
||||||
|
|
||||||
SPECS := {
|
|
||||||
; 2x3 matrix
|
; 2x3 matrix
|
||||||
upperLeft : {x: 0, y: 0, w: 1/3, h: 1/2 },
|
upperLeft : {pos: {x: 0, y: 0}, size: {width: 1/3, height: 1/2 }},
|
||||||
upperMiddle : {x: 1/3, y: 0, w: 1/3, h: 1/2 },
|
upperMiddle : {pos: {x: 1/3, y: 0}, size: {width: 1/3, height: 1/2 }},
|
||||||
upperRight : {x: 2/3, y: 0, w: 1/3, h: 1/2 },
|
upperRight : {pos: {x: 2/3, y: 0}, size: {width: 1/3, height: 1/2 }},
|
||||||
lowerLeft : {x: 0, y: 1/2, w: 1/3, h: 1/2 },
|
lowerLeft : {pos: {x: 0, y: 1/2}, size: {width: 1/3, height: 1/2 }},
|
||||||
lowerMiddle : {x: 1/3, y: 1/2, w: 1/3, h: 1/2 },
|
lowerMiddle : {pos: {x: 1/3, y: 1/2}, size: {width: 1/3, height: 1/2 }},
|
||||||
lowerRight : {x: 2/3, y: 1/2, w: 1/3, h: 1/2 },
|
lowerRight : {pos: {x: 2/3, y: 1/2}, size: {width: 1/3, height: 1/2 }},
|
||||||
|
|
||||||
; full height thirds
|
; Full Height Thirds
|
||||||
thirdLeft : {x: 0, y: 0, w: 1/3, h: 1 },
|
thirdLeft : {pos: {x: 0, y: 0}, size: {width: 1/3, height: 1 }},
|
||||||
doubleLeft : {x: 0, y: 0, w: 2/3, h: 1 },
|
doubleLeft : {pos: {x: 0, y: 0}, size: {width: 2/3, height: 1 }},
|
||||||
thirdRight : {x: 2/3, y: 0, w: 1/3, h: 1 },
|
thirdRight : {pos: {x: 2/3, y: 0}, size: {width: 1/3, height: 1 }},
|
||||||
doubleRight : {x: 1/3, y: 0, w: 2/3, h: 1 },
|
doubleRight : {pos: {x: 1/3, y: 0}, size: {width: 2/3, height: 1 }},
|
||||||
|
|
||||||
; full height halves
|
; Full Height Halves
|
||||||
halfLeft : {x: 0, y: 0, w: 1/2, h: 1 },
|
halfLeft : {pos: {x: 0, y: 0}, size: {width: 1/2, height: 1 }},
|
||||||
halfRight : {x: 1/2, y: 0, w: 1/2, h: 1 },
|
halfRight : {pos: {x: 1/2, y: 0}, size: {width: 1/2, height: 1 }},
|
||||||
|
|
||||||
; center
|
; Center
|
||||||
mainFocus : {x: 0.18, y: 0, w: 0.64, h: 1 },
|
mainFocus : {pos: {x: 0.18, y: 0}, size: {width: 0.64, height: 1 }},
|
||||||
}
|
}
|
||||||
|
|
||||||
^!r::Reload
|
^!r::Reload
|
||||||
|
|
||||||
|
; Make sure NumLock is active so that Numpad mappinfs below will work.
|
||||||
|
SetNumLockState True
|
||||||
|
|
||||||
; 2x3 matrix
|
; 2x3 matrix
|
||||||
!#Numpad7:: positionWindow(SPECS.upperLeft)
|
!#Numpad7:: WinSetRelativeRect(POS.upperLeft)
|
||||||
!#NumpadDiv:: positionWindow(SPECS.upperMiddle)
|
!#NumpadDiv:: WinSetRelativeRect(POS.upperMiddle)
|
||||||
!#Numpad8:: positionWindow(SPECS.upperMiddle)
|
!#Numpad8:: WinSetRelativeRect(POS.upperMiddle)
|
||||||
!#Numpad9:: positionWindow(SPECS.upperRight)
|
!#Numpad9:: WinSetRelativeRect(POS.upperRight)
|
||||||
!#Numpad1:: positionWindow(SPECS.lowerLeft)
|
!#Numpad1:: WinSetRelativeRect(POS.lowerLeft)
|
||||||
!#NumpadSub:: positionWindow(SPECS.lowerMiddle)
|
!#NumpadSub:: WinSetRelativeRect(POS.lowerMiddle)
|
||||||
!#Numpad2:: positionWindow(SPECS.lowerMiddle)
|
!#Numpad2:: WinSetRelativeRect(POS.lowerMiddle)
|
||||||
!#Numpad3:: positionWindow(SPECS.lowerRight)
|
!#Numpad3:: WinSetRelativeRect(POS.lowerRight)
|
||||||
|
|
||||||
; Full height thirds
|
; Full height thirds
|
||||||
!#Numpad4:: positionWindow(SPECS.thirdLeft)
|
!#Numpad4:: WinSetRelativeRect(POS.thirdLeft)
|
||||||
!#NumpadMult:: positionWindow(SPECS.doubleLeft)
|
!#NumpadMult:: WinSetRelativeRect(POS.doubleLeft)
|
||||||
!#Numpad5:: positionWindow(SPECS.doubleRight)
|
!#Numpad5:: WinSetRelativeRect(POS.doubleRight)
|
||||||
!#Numpad6:: positionWindow(SPECS.thirdRight)
|
!#Numpad6:: WinSetRelativeRect(POS.thirdRight)
|
||||||
|
|
||||||
; Full height halves
|
; Full height halves
|
||||||
!^Numpad1::positionWindow(SPECS.halfLeft)
|
!^Numpad1:: WinSetRelativeRect(POS.halfLeft)
|
||||||
!^Numpad3::positionWindow(SPECS.halfRight)
|
!^Numpad3:: WinSetRelativeRect(POS.halfRight)
|
||||||
|
|
||||||
; Center and...
|
; Center and...
|
||||||
!#NumpadAdd:: positionWindow(SPECS.mainFocus) ; ... resize to default.
|
!#NumpadAdd:: WinSetRelativeRect(POS.mainFocus) ; ... resize to default.
|
||||||
!^Numpad5:: centerWindow() ; ... keep size.
|
!^Numpad5:: WinCenter() ; ... keep size.
|
||||||
|
|
||||||
; Move to other monitor
|
; Move to other monitor (FIXME this is a hack, but works on my current setup)
|
||||||
; !^Left:: TODO move to other monitor
|
!^Left:: WinSetMonitor(2)
|
||||||
; !^Right:: TODO move to other monitor
|
!^Right:: WinSetMonitor(1)
|
||||||
|
|
||||||
; Move without resize
|
; Move without resize
|
||||||
step := 50 ; dx dy
|
step := 50 ; dx dy
|
||||||
!^Numpad4:: moveWindow(-step, 0) ; left (H)
|
!^Numpad4:: WinTranslate(-step, 0) ; left (H)
|
||||||
!^Numpad2:: moveWindow( 0, step) ; down (J)
|
!^Numpad2:: WinTranslate( 0, step) ; down (J)
|
||||||
!^Numpad8:: moveWindow( 0, -step) ; up (K)
|
!^Numpad8:: WinTranslate( 0, -step) ; up (K)
|
||||||
!^Numpad6:: moveWindow( step, 0) ; right (L)
|
!^Numpad6:: WinTranslate( step, 0) ; right (L)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue