Jump to content


Photo

Dual monitor swap


  • Please log in to reply
12 replies to this topic

#1 alanmusician

alanmusician
  • Members
  • 1 posts

Posted 22 May 2007 - 09:21 PM

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
}


#2 Thalon

Thalon
  • Members
  • 641 posts

Posted 23 May 2007 - 06:43 AM

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


#3 Jeffrey

Jeffrey
  • Guests

Posted 14 September 2007 - 09:41 PM

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.

#4 Jeffrey

Jeffrey
  • Guests

Posted 14 September 2007 - 10:01 PM

Lol just updated Ultramon to the 3.0Beta and now all works fine. Great script

#5 Lexikos

Lexikos
  • Administrators
  • 8835 posts

Posted 15 September 2007 - 03:07 AM

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.

#6 xenrik

xenrik
  • Guests

Posted 22 October 2008 - 02:50 PM

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
}


#7 More

More
  • Guests

Posted 20 December 2008 - 09:03 PM

Great script Alan. Works fine. Thank you!!

#8 Lexikos

Lexikos
  • Administrators
  • 8835 posts

Posted 20 December 2008 - 11:52 PM

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.

#9 jellymann

jellymann
  • Members
  • 1 posts

Posted 11 September 2010 - 11:47 AM

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
}


#10 musicgold

musicgold
  • Members
  • 7 posts

Posted 09 June 2011 - 12:05 PM

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.

#11 kiropes

kiropes
  • Members
  • 78 posts

Posted 09 June 2011 - 01:16 PM

<!-- m -->http://www.autohotke...pic.php?t=45036<!-- m -->

#12 musicgold

musicgold
  • Members
  • 7 posts

Posted 09 June 2011 - 02:13 PM

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.

#13 rodfell

rodfell
  • Members
  • 138 posts

Posted 11 June 2011 - 09:40 AM

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.