Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Dual monitor swap


  • Please log in to reply
12 replies to this topic
alanmusician
  • Members
  • 1 posts
  • Last active: May 22 2007 09:23 PM
  • Joined: 22 May 2007
Here's a script that swaps all application windows from one monitor to another in a dual-monitor setup. It currently only works with two monitors, and they must be running at the same resolution.

I created this to work with SharpE desktop's virtual desktop switcher, which shifts virtual desktops left and right on dual monitors. I will probably try to create my own virtual desktop switcher with AutoHotkey if there is enough interest.

Here's the script:

; MonSwap - Swaps all the application windows from one monitor to another.
; v1.0
; Author: Alan Henager

SetWinDelay, 0 ; This switching should be instant

; Set this key combination to whatever.
+#s::
SwapAll:
{
  DetectHiddenWindows, Off ; I think this is default, but just for safety's sake...
  WinGet, WinArray, List ; , , , Sharp
  ; Enable the above commented out portion if you are running SharpE

  i := WinArray
  Loop, %i% {
     WinID := WinArray%A_Index%
     WinGetTitle, CurWin, ahk_id %WinID%
     If (CurWin = ) ; For some reason, CurWin <> didn't seem to work.
     {}
     else
     {
        WinGet, IsMin, MinMax, ahk_id %WinID% ; The window will re-locate even if it's minimized
        If (IsMin = -1) {
           WinRestore, ahk_id %WinID%
           SwapMon(WinID)
           WinMinimize, ahk_id %WinID%
        } else {
           SwapMon(WinID)
        }
     }
  }
  return
}

SwapMon(WinID) ; Swaps window with and ID of WinID onto the other monitor
{
  SysGet, Mon1, Monitor, 1
  SysGet, Mon2, Monitor, 2
  WinGetPos, WinX, WinY, WinWidth, , ahk_id %WinID%

  WinCenter := WinX + (WinWidth / 2) ; Determines which monitor this is on by the position of the center pixel.
  if (WinCenter > Mon1Left and WinCenter < Mon1Right) {
    WinX := Mon2Left + (WinX - Mon1Left)
  } else if (WinCenter > Mon2Left and WinCenter < Mon2Right) {
    WinX := Mon1Left + (WinX - Mon2Left)
  }

  WinMove, ahk_id %WinID%, , %WinX%, %WinY%
  return
}


Thalon
  • Members
  • 641 posts
  • Last active: Jan 02 2017 12:17 PM
  • Joined: 12 Jul 2005
A very similar script I wrote for 1 window (I hope I can post it in your thread):
(I assume that the smaller monitor (if any) is at the left side of the bigger one, otherwise you will have to do little codechanges)
ScreenWidth1 = 1280  ;Screen-width of smallest monitor 
ScreenHeight1 = 1024   ;Screen-heigth of smallest monitor
return

MButton::
MouseGetPos, , , ActiveWin
MoveWindowToMonitor(ActiveWin, ScreenWidth1, ScreenHeight1)
return

MoveWindowToMonitor(ActiveWin, ScreenWidth1, ScreenHeight1)
{
	WinGet, SizeState, MinMax, ahk_id %ActiveWin%
	if SizeState = 1	;Maximized
		WinRestore, ahk_id %ActiveWin%
		
	WinGetPos, WinXPos, WinYPos, WinWidth, WinHeight, ahk_id %ActiveWin%
	if WinXPos < 0		;Move window from left (small) to right monitor (bigger)
	{
		WinMove, ahk_id %ActiveWin%, , % WinXPos + ScreenWidth1
	}
	else		;Move window from right monitor (bigger) to small (left)
	{
		;Calculation of new size, so window doesn't reach outside the screen of the smaller monitor
		if WinWidth > %ScreenWidth1%
			WinWidth = %ScreenWidth1%
		if WinHeight > %ScreenHeight1%
			WinHeight = %ScreenHeight1%
		WinXPosWidth := WinXPos + WinWidth
		if WinXPosWidth > %ScreenWidth1%
			WinXOffset := WinXPosWidth
		else
			WinXOffset = %ScreenWidth1%
		WinYPosHeight := WinYPos + WinHeight
		if WinYPosHeight > %ScreenHeight1%
			WinYOffset := WinYPosHeight - ScreenHeight1
		else
			WinYOffset = 0
			
		;Resize and move window:
		WinMove, ahk_id %ActiveWin%, , % WinXPos - WinXOffset, % WinYPos - WinYOffset, %WinWidth%, %WinHeight%
	}
	if SizeState = 1	;Restores Maximize-State
		WinMaximize, ahk_id %ActiveWin%
	WinActivate ahk_id %ActiveWin%		;Necessary, because another window may overlap it otherwise...
}


Jeffrey
  • Guests
  • Last active:
  • Joined: --
Hey, your script is awesome Alan, but on my system I am running Ultramon. The task bar that ultramon creates, gets moved between the screens with the windows. I have been trying to figure out how to exclude the "ahk_class UltraMon Taskbar" but I cant figure it out.

I am wondering if someone might know how this could be accomplished?

On a quick side note ANYONE running dual monitors should check out Ultramon, its not free but the functionality it brings to multi displays is worth it.

Jeffrey
  • Guests
  • Last active:
  • Joined: --
Lol just updated Ultramon to the 3.0Beta and now all works fine. Great script

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
Didn't notice these scripts...

You might like to check out WindowPad, which provides similar functionality. (Win+NumpadDot to switch monitors, Win+NumpadDiv|Mult to gather all windows on monitor 2|1, and Win+Numpad* to simultaneously move and resize windows.)

Middle-click to move a window is a good idea... perhaps I'll add it to WindowPad.

xenrik
  • Guests
  • Last active:
  • Joined: --
Hi There,

I know this thread is ancient, however I was looking for a script that switched windows between monitors and this was the first one I found :).

After trying it out, I found it didn't quite do what I was after -- mainly because my monitors don't run at the same resolutions. Hence I've changed it slightly so that instead of just blindly swapping the windows between the monitors, it now swaps but maintains the relative size of the window based upon the size of the new monitor. This means that when full-screen windows are switched between the different monitors they still appear full screen when switched to a larger monitor, and don't grow outside the side of the monitor when switched to a smaller one.

The modified script is below:

; MonSwap - Swaps all the application windows from one monitor to another.
; v1.0.1
; Author: Alan Henager
;
; v1.0.1 - xenrik - Updated to use relative screen size when swapping

SetWinDelay, 0 ; This switching should be instant

; Set this key combination to whatever.
+#s::
SwapAll:
{
  DetectHiddenWindows, Off ; I think this is default, but just for safety's sake...
  WinGet, WinArray, List ; , , , Sharp
  ; Enable the above commented out portion if you are running SharpE

  i := WinArray
  Loop, %i% {
     WinID := WinArray%A_Index%
     WinGetTitle, CurWin, ahk_id %WinID%
     If (CurWin = ) ; For some reason, CurWin <> didn't seem to work.
     {}
     else
     {
        WinGet, IsMin, MinMax, ahk_id %WinID% ; The window will re-locate even if it's minimized
        If (IsMin = -1) {
           WinRestore, ahk_id %WinID%
           SwapMon(WinID)
           WinMinimize, ahk_id %WinID%
        } else {
           SwapMon(WinID)
        }
     }
  }
  return
}

SwapMon(WinID) ; Swaps window with and ID of WinID onto the other monitor
{
  SysGet, Mon1, Monitor, 1
  Mon1Width := Mon1Right - Mon1Left
  Mon1Height := Mon1Bottom - Mon1Top

  SysGet, Mon2, Monitor, 2
  Mon2Width := Mon2Right - Mon2Left
  Mon2Height := Mon2Bottom - Mon2Top

  WinGetPos, WinX, WinY, WinWidth, WinHeight, ahk_id %WinID%
  WinCenter := WinX + (WinWidth / 2)
  if (WinCenter >= Mon1Left and WinCenter <= Mon1Right) {
    NewX := (WinX - Mon1Left) / Mon1Width
    NewX := Mon2Left + (Mon2Width * NewX)

    NewWidth := WinWidth / Mon1Width
    NewWidth := Mon2Width * NewWidth

    NewY := (WinY - Mon1Top) / Mon1Height
    NewY := Mon2Top + (Mon2Height * NewY)

    NewHeight := WinHeight / Mon1Height
    NewHeight := Mon2Height * NewHeight
  } else {
    NewX := (WinX - Mon2Left) / Mon2Width
    NewX := Mon1Left + (Mon1Width * NewX)

    NewWidth := WinWidth / Mon2Width
    NewWidth := Mon1Width * NewWidth

    NewY := (WinY - Mon2Top) / Mon2Height
    NewY := Mon1Top + (Mon1Height * NewY)

    NewHeight := WinHeight / Mon2Height
    NewHeight := Mon1Height * NewHeight
  }

  WinMove, ahk_id %WinID%, , %NewX%, %NewY%, %NewWidth%, %NewHeight%
  return
}


More
  • Guests
  • Last active:
  • Joined: --
Great script Alan. Works fine. Thank you!!

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

it now swaps but maintains the relative size of the window based upon the size of the new monitor.

WindowPad does this and much more.

jellymann
  • Members
  • 1 posts
  • Last active: Sep 11 2010 11:44 AM
  • Joined: 11 Sep 2010
Thanks so much for your script! :)

I hope you don't mind, but I modified it to make it only swap the window under the mouse:

SetWinDelay, 0

#RButton::
{
    MouseGetPos, , , WinID, control

    SysGet, Mon1, Monitor, 1
    SysGet, Mon2, Monitor, 2
    WinGetPos, WinX, WinY, WinWidth, , ahk_id %WinID%

    WinCenter := WinX + (WinWidth / 2) ; Determines which monitor this is on by the position of the center pixel.
    if (WinCenter > Mon1Left and WinCenter < Mon1Right) {
        WinX := Mon2Left + (WinX - Mon1Left)
    } else if (WinCenter > Mon2Left and WinCenter < Mon2Right) {
        WinX := Mon1Left + (WinX - Mon2Left)
    }

    WinMove, ahk_id %WinID%, , %WinX%, %WinY%
    return
}


musicgold
  • Members
  • 7 posts
  • Last active: May 27 2011 08:44 PM
  • Joined: 27 May 2011
Hi guys,

I am looking for a simple solution but none of the above code snippets are useful for me.

I have two monitors, both with the same resolution. I just want to be able to quickly move the active window from one monitor to the other.
What do I need to do?

Thanks.

kiropes
  • Members
  • 78 posts
  • Last active: Oct 16 2014 05:35 AM
  • Joined: 21 Mar 2007
<!-- m -->http://www.autohotke...pic.php?t=45036<!-- m -->

musicgold
  • Members
  • 7 posts
  • Last active: May 27 2011 08:44 PM
  • Joined: 27 May 2011
Thank you kiropes.

I am not a savvy AHK programmer, but did I see the code has two key combinations, +m and +a. For me, +a is working fine. I am wondering what the use of +m is.

Thanks.

rodfell
  • Members
  • 138 posts
  • Last active: Jun 26 2011 10:02 PM
  • Joined: 05 Oct 2007

I am not a savvy AHK programmer, but did I see the code has two key combinations, +m and +a. For me, +a is working fine. I am wondering what the use of +m is.

It is used to move the window under the mouse to the next screen. It's to allow easy tie in with gesture programs, so that a defined gesture will make the window under the gesture move to the next screen.