I'm sure some of you switched between Eyefinity/Surround (or both together known as SLS - Single Large Surface) multiple times a day. And every time all windows positions have been totally messed up. Well, tonight i had enough of that.
I've used AutoIT to write a simple tool which runs in the Background and automatically repositions all my open Windows when i switch from Extended Mode to Eyefinity or back.
You can see it in Action in this short Youtube clip:
[youtube]https://youtube.com/v/W2QFIwgY6mo[/youtube]
How does it work?
Every 2 Seconds a List of all Windows which are not minimized is created.
it checks in this list if the Main Monitor is on the Top Left Corner or not. If you have any monitor left from your Main Monitor it will detect a Extended Setup.
if you switch to Eyefinity/Surround it detects that change and knows top right corner is on 0 0 and not -1920 0 anymore.
After a Delay of 22 seconds (Yes, it really takes over 20 seconds for Radeon Settings to Switch to Eyefinity and get the Radeon settings Menu back online with the Eyefinity specific settings) all the Windows will be moved to the Position 6 seconds before the change has been detected.
This also works the other way around. Switching back from Eyefinity to Extended takes a 3 seconds delay and then moves all the windows as they have been 6 seconds before the detected change.
Does it Work with nVidia Surround?
It should.... most Likely... i have no possiblity to test it but if it doesn't take longer than 22 seconds to setup Surround after the Desktop Resolution has changed it should.
What Operating Systems?
Tested on Windows 10!
8.1 most likely works too. 7 and Vista might work.
The compiled .exe is x86
Does it work with Bezel Correction?
Yes, after version 1.0.1
Does it work with 3440x1400?
Currently not, it's optimized for 1920 width monitors. But if you change the Values yourself there is no reason why it wouldn't.
Virus detected!
It's an AutoIt script compiled into an .exe they often are missdetected as a virus. If you don't trust the .exe simply copy the code and compile it yourself.
Changelog:
v1.0.4 08.01.2015
modified the Delay. It's preset to 1second and waits as long as it takes until it can move a window before it continues.
Might cause problems if you close or minimze a window in that moment when you switch to EF. Increase Dealy to prevent this.
v1.0.3 30.12.2015
fixed the pause function
Added a "Start at Boot" functionality
v1.0.2 28.12.2015
Added a GUI for setting up bezel correction and Delays
Added a Tray Icon with Settings/Pause/Exit functions
Added a settings.ini file which stores all settings for reboot
Added security to prevent the script from running twice
Set an Icon
Should now support every 3x1L or 3x1P Setup
V1.0.1 26.12.2015
Added Bezel correction.
V1.0.0 Initial Release 26.12.2015
Here you have the full AutoIt code: A compiled .exe is attached below.
Code: Select all
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=mm.ico
#AutoIt3Wrapper_UseX64=n
#AutoIt3Wrapper_Res_Fileversion=1.0.4.0
#AutoIt3Wrapper_Res_SaveSource=y
#AutoIt3Wrapper_Add_Constants=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#cs ----------------------------------------------------------------------------
AutoIt Version: 3.3.12.0
Author: Haldi
Script Function:
Moves Windows into correct Position after switching to Eyefinity / Surround
#ce ----------------------------------------------------------------------------
#include <Array.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <TrayConstants.au3>
TraySetIcon("mm.ico")
Opt('TrayMenuMode', 3)
Opt('TrayOnEventMode', 1)
Global $aWinListOld[1][6] = [["Name", "Handle", "PosX", "PosY", "Width", "Heigth"]]
Global $aWinListOld1[1][6] = [["Name", "Handle", "PosX", "PosY", "Width", "Heigth"]]
Global $sSLSmode = 0, $sXwidth = 1920, $sDelayS = 1000, $sDelayE = 1000, $sBezelcorrection = 0, $iniName="AutoWindowsMoverSettings.ini", $pause
$g_szVersion = "AutoWindowMover"
If WinExists($g_szVersion) Then
MsgBox(16++65536+262144, "Error", "Already running",10)
Exit ;Script already Running
EndIf
AutoItWinSetTitle($g_szVersion)
Sleep(5000) ;STARTUP DELAY
If @DesktopWidth/@DesktopHeight> 2.4 Then $sSLSmode = 1 ;Aspectratio bigger than 21:9 Detected, SLS Activated
TrayCreateItem ("Settings")
TrayItemSetOnEvent(-1, "GUI")
$trayPause = TrayCreateItem ("Pause")
TrayItemSetOnEvent(-1, "Pause")
TrayCreateItem ("Exit")
TrayItemSetOnEvent(-1, "Exitscript")
#Region Load Settings / First Boot
If FileExists($iniName) = 1 Then
ToolTip(" ",@DesktopWidth/2, @DesktopHeight/2,"Starting Script",1, 2)
Sleep(500)
ToolTip("")
$sBezelcorrection = IniRead($iniName, "Settings", "Bezelcorrection", "")
$sXwidth = IniRead($iniName, "Settings", "ExtendedWidth", "")
Else
MsgBox(262144, "First Start", "Please take a moment and configure your Bezelcorrection"&@CRLF&@CRLF&"You can find this Menu by clicking the Tray Icon")
GUI()
EndIf
#EndRegion
Func Exitscript()
Exit
EndFunc
Func Pause()
If TrayItemGetState($trayPause) = 68 Then
TrayItemSetState($trayPause, $TRAY_CHECKED)
$pause =1
ElseIf TrayItemGetState($trayPause) = 65 Then
TrayItemSetState($trayPause, $TRAY_UNCHECKED)
$pause =0
If @DesktopWidth/@DesktopHeight> 2.4 Then
$sSLSmode = 1 ;Aspectratio bigger than 21:9 Detected, SLS Activate
Else
$sSLSmode = 0
EndIf
EndIf
EndFunc
#Region Move Windows
While 1
Global $aWinList[1][6] = [["Name", "Handle", "PosX", "PosY", "Width", "Heigth"]]
GetPos()
;~ _ArrayDisplay($aWinList)
;~ _ArrayDisplay($aWinListOld1)
If $pause = 0 Then
If $sSLSmode = 0 Then
If $aWinList[UBound($aWinList)-1][2] >= 0 Then ;Is in SLS Mode
ToolTip("Waiting"&@CRLF&"Bezelcorrection: "&$sBezelcorrection&@CRLF&"Desktop: "&$aWinList[UBound($aWinList)-1][4],@DesktopWidth/2, @DesktopHeight/2,"Switching to SLS Mode",1, 2)
$sSLSmode = 1
$aWinList=$aWinListOld1
Sleep($sDelayS)
SwitchToEF()
EndIf
ElseIf $sSLSmode = 1 Then
If $aWinList[UBound($aWinList)-1][2] < 0 Then ;Is in Extended Mode
$sSLSmode = 0
$aWinList=$aWinListOld1
ToolTip("Waiting"&@CRLF&"Bezelcorrection: "&$sBezelcorrection&@CRLF&"Desktop: "&$aWinList[UBound($aWinList)-1][4],@DesktopWidth/2, @DesktopHeight/2,"Switching to Single Mode",1, 2)
Sleep($sDelayE)
SwitchToSingle()
EndIf
EndIf
Else
EndIf
$aWinListOld2 = $aWinListOld1
$aWinListOld1 = $aWinListOld
$aWinListOld = $aWinList
$aWinList=0
Sleep(2000)
WEnd
Func GetPos()
$iarray = 1
Local $aList = WinList()
For $i = 1 To $aList[0][0]
If $aList[$i][0] <> "" And BitAND(WinGetState($aList[$i][1]), 2) Then
$aPos=WinGetPos($aList[$i][1])
;~ _ArrayDisplay($aPos)
If $aPos[0] <> "-32000" Then
_ArrayAdd($aWinList, $aList[$i][0])
$aWinList[$iarray][1] = $aList[$i][1]
$aWinList[$iarray][2] = $aPos[0]
$aWinList[$iarray][3] = $aPos[1]
$aWinList[$iarray][4] = $aPos[2]
$aWinList[$iarray][5] = $aPos[3]
$iarray= $iarray+1
EndIf
;~ _ArrayDisplay($aWinList)
EndIf
Next
EndFunc
Func SwitchToEF()
$iSEF =1
_ArrayDelete($aWinList, UBound($aWinList)-1)
Do ;Check if windows are moveable, take last window
WinMove($aWinList[UBound($aWinList)-1][1], "", ($aWinList[UBound($aWinList)-1][2])+1, $aWinList[UBound($aWinList)-1][3])
Sleep(100)
$aPosCheck = WinGetPos($aWinList[UBound($aWinList)-1][1])
ConsoleWrite('Window: '&$aWinList[UBound($aWinList)-1][1]&' posold: '&$aWinList[UBound($aWinList)-1][2]&@CRLF)
Sleep(200)
Until $aPosCheck[0] = ($aWinList[UBound($aWinList)-1][2])+1 ; END Check
ToolTip("Moving",@DesktopWidth/2, @DesktopHeight/2,"Switching to SLS Mode",1, 2)
Do
If $aWinList[$iSEF][2] <= 0 Then
WinMove($aWinList[$iSEF][1], "", ($aWinList[$iSEF][2])+$sXwidth, $aWinList[$iSEF][3])
ElseIf $aWinList[$iSEF][2] > 0 And $aWinList[$iSEF][2] < $sXwidth Then
WinMove($aWinList[$iSEF][1], "", ($aWinList[$iSEF][2])+$sXwidth+$sBezelcorrection, $aWinList[$iSEF][3])
ElseIf $aWinList[$iSEF][2] >= $sXwidth Then
WinMove($aWinList[$iSEF][1], "", ($aWinList[$iSEF][2])+$sXwidth+($sBezelcorrection*2), $aWinList[$iSEF][3])
EndIf
$iSEF = $iSEF+1
Until $iSEF >= UBound($aWinList)
ToolTip("Done",@DesktopWidth/2, @DesktopHeight/2,"Switching to SLS Mode",1, 2)
Sleep(500)
ToolTip("")
EndFunc
Func SwitchToSingle()
_ArrayDelete($aWinList, UBound($aWinList)-1)
$iSS =1
Do ;Check if windows are moveable, Take first Window
WinMove($aWinList[$iSS][1], "", ($aWinList[$iSS][2])-1, $aWinList[$iSS][3])
Sleep(100)
$aPosCheck = WinGetPos($aWinList[$iSS][1])
Sleep(200)
Until $aPosCheck[0] = ($aWinList[$iSS][2])-1 ;End Check
ToolTip("Moving",@DesktopWidth/2, @DesktopHeight/2,"Switching to Single Mode",1, 2)
Do
If $aWinList[$iSS][2] < $sXwidth Then
WinMove($aWinList[$iSS][1], "", ($aWinList[$iSS][2])-$sXwidth, $aWinList[$iSS][3])
ElseIf $aWinList[$iSS][2] >= $sXwidth+$sBezelcorrection And $aWinList[$iSS][2] <= $sXwidth+$sXwidth+($sBezelcorrection*2) Then
WinMove($aWinList[$iSS][1], "", ($aWinList[$iSS][2])-($sXwidth+$sBezelcorrection), $aWinList[$iSS][3])
ElseIf $aWinList[$iSS][2] >= $sXwidth+$sXwidth+$sBezelcorrection+$sBezelcorrection Then
WinMove($aWinList[$iSS][1], "", ($aWinList[$iSS][2])-($sXwidth+$sBezelcorrection*2), $aWinList[$iSS][3])
Endif
$iSS = $iSS+1
Until $iSS >= UBound($aWinList)
ToolTip("Done",@DesktopWidth/2, @DesktopHeight/2,"Switching to Single Mode",1, 2)
Sleep(500)
ToolTip("")
EndFunc
#EndRegion
#Region GUI
Func GUI()
$sExtendedHeigth = @DesktopHeight
$sSLSHeigth = @DesktopHeight
$sSLSBHeigth = @DesktopHeight
If $sSLSmode = 0 Then ;Detection Extended
$sSLSmodeName = "Extended"
$sExtendedWidth = @DesktopWidth
$sSLSWidth = $sExtendedWidth*3
$sSLSBWidth = $sExtendedWidth*3+$sBezelcorrection*2
Elseif $sSLSmode = 1 Then ;Detection SLS
$sSLSmodeName = "SLS"
$sExtendedWidth = @DesktopWidth/3-$sBezelcorrection*2
$sSLSBWidth = @DesktopWidth-$sBezelcorrection*2
$sSLSWidth = $sExtendedWidth*3
Endif
If FileExists($iniName) = 1 Then ;Load Settings
$sExtendedWidth = IniRead($iniName, "Settings", "ExtendedWidth", "")
$sExtendedHeigth = Iniread($iniName, "Settings", "ExtendedHeigth", "")
$sSLSWidth = IniRead($iniName, "Settings", "SLSWidth", "")
$sSLSHeigth = IniRead($iniName, "Settings", "SLSHeigth", "")
$sSLSBWidth = IniRead($iniName, "Settings", "SLSBWidth", "")
$sSLSBHeigth = IniRead($iniName, "Settings", "SLSBHeigth", "")
$sBezelcorrection = IniRead($iniName, "Settings", "Bezelcorrection", "")
$sDelayS = IniRead($iniName, "Settings", "DelaySLS", "")
$sDelayE = IniRead($iniName, "Settings", "DelayExtended", "")
EndIf
$hGUI = GUICreate("AutoWindowsMover", 270, 231, -1, -1)
$hLabel = GUICtrlCreateLabel("Currently in "&$sSLSmodeName&" Mode", 10, 10, 250, 20)
$hLabel2 = GUICtrlCreateLabel("Extended Resolution:", 10, 40, 110, 20)
$hInput = GUICtrlCreateInput($sExtendedWidth, 10, 55, 40, 20, 0x2000)
$hInput2 = GUICtrlCreateInput($sExtendedHeigth, 70, 55, 40, 20,0x2000)
$hLabel3 = GUICtrlCreateLabel("x", 50, 55, 20, 20, 0x01)
$hLabel4 = GUICtrlCreateLabel("SLS Resolution:", 150, 40, 110, 20)
$hLabel5 = GUICtrlCreateLabel("x", 190, 55, 20, 20, 0x01)
$hInput3 = GUICtrlCreateInput($sSLSWidth, 150, 55, 40, 20, 0x2000)
$hInput4 = GUICtrlCreateInput($sSLSHeigth, 210, 55, 40, 20, 0x2000)
$hButton = GUICtrlCreateButton("Save Settings", 140, 190, 120, 30)
$hLabel6 = GUICtrlCreateLabel("Bezel Correction:", 10, 90, 170, 20)
$hInput5 = GUICtrlCreateInput($sBezelcorrection, 10, 105, 40, 20, 0x2000)
$hLabel7 = GUICtrlCreateLabel("Bezel Corrected Resolution:", 10, 140, 170, 20)
$hLabel8 = GUICtrlCreateLabel("x", 50, 155, 20, 20, 0x01)
$hInput6 = GUICtrlCreateInput($sSLSBWidth, 10, 155, 40, 20, 0x2000)
$hInput7 = GUICtrlCreateInput($sSLSBHeigth, 70, 155, 40, 20, 0x2000)
$hLabel9 = GUICtrlCreateLabel("SLS Delay:", 150, 90, 110, 20)
$hInput8 = GUICtrlCreateInput($sDelayS/1000, 150, 105, 40, 20, 0x2000)
$hLabel10 = GUICtrlCreateLabel("Extended Delay:", 150, 140, 170, 20)
$hInput9 = GUICtrlCreateInput($sDelayE/1000, 150, 155, 40, 20, 0x2000)
$hCheckbox = GUICtrlCreateCheckbox("Start with Windows", 10, 190)
if FileExists(@StartupDir & "\AutoWindowMover.lnk") Then ;AutoStart Check
GUICtrlSetState($hCheckbox, $GUI_CHECKED)
EndIf
GUISetState()
While 1
$hMsg = GUIGetMsg()
Switch $hMsg
Case $GUI_EVENT_CLOSE
ExitLoop
Case $hButton
If GUICtrlRead($hCheckbox) = 1 Then ;Is checked
If Not FileExists(@StartupDir & "\AutoWindowMover.lnk") Then
FileCreateShortcut(@ScriptFullPath, @StartupDir & "\AutoWindowMover.lnk", @ScriptDir, "", "AutoWindowMover Start at Boot")
EndIf
ElseIf GUICtrlRead($hCheckbox) = 4 Then ;Is UNchecked
If FileExists(@StartupDir & "\AutoWindowMover.lnk") Then
FileDelete(@StartupDir & "\AutoWindowMover.lnk")
EndIf
EndIf
$sExtendedWidth = GUICtrlRead($hInput)
$sExtendedHeigth = GUICtrlRead($hInput2)
$sSLSWidth = GUICtrlRead($hInput3)
$sSLSHeigth = GUICtrlRead($hInput4)
$sSLSBWidth = GUICtrlRead($hInput6)
$sSLSBHeigth = GUICtrlRead($hInput7)
$sBezelcorrection = GUICtrlRead($hInput5)
$sDelayS = GUICtrlRead($hInput8)*1000
$sDelayE = GUICtrlRead($hInput9)*1000
IniWrite($iniName, "Settings", "ExtendedWidth", $sExtendedWidth)
IniWrite($iniName, "Settings", "ExtendedHeigth", $sExtendedHeigth)
IniWrite($iniName, "Settings", "SLSWidth", $sSLSWidth)
IniWrite($iniName, "Settings", "SLSHeigth", $sSLSHeigth)
IniWrite($iniName, "Settings", "SLSBWidth", $sSLSBWidth)
IniWrite($iniName, "Settings", "SLSBHeigth", $sSLSBHeigth)
IniWrite($iniName, "Settings", "Bezelcorrection", $sBezelcorrection)
IniWrite($iniName, "Settings", "DelaySLS", $sDelayS)
IniWrite($iniName, "Settings", "DelayExtended", $sDelayE)
$sXwidth = $sExtendedWidth
ExitLoop
Case $hInput2 ;Heigth Changes
GUICtrlSetData($hInput4, GUICtrlRead($hInput2))
GUICtrlSetData($hInput7, GUICtrlRead($hInput2))
Case $hInput4 ;Heigth SLS Changes
GUICtrlSetData($hInput2, GUICtrlRead($hInput4))
GUICtrlSetData($hInput7, GUICtrlRead($hInput4))
Case $hInput7 ;Height SLS B Changes
GUICtrlSetData($hInput2, GUICtrlRead($hInput7))
GUICtrlSetData($hInput4, GUICtrlRead($hInput7))
Case $hInput5 ; Bezelcorrection changes
If $sSLSmode = 1 Then
GUICtrlSetData($hInput,((GUICtrlRead($hInput6))-(GUICtrlRead($hInput5)*2))/3)
GUICtrlSetData($hInput3, (GUICtrlRead($hInput6))-(GUICtrlRead($hInput5)*2))
Else
GUICtrlSetData($hInput6,(GUICtrlRead($hInput)*3)+(GUICtrlRead($hInput5)*2))
EndIf
Case $hInput ;Extended Width Changes
GUICtrlSetData($hInput3, GUICtrlRead($hInput)*3)
If $sSLSmode = 0 Then
GUICtrlSetData($hInput6, GUICtrlRead($hInput)*3+(GUICtrlRead($hInput5)*2))
Else
GUICtrlSetData($hInput5, (GUICtrlRead($hInput6)-(GUICtrlRead($hInput)*3))/2)
EndIf
Case $hInput6 ;SLS B Changes
GUICtrlSetData($hInput3, GUICtrlRead($hInput6)-(GUICtrlRead($hInput5)*2))
GUICtrlSetData($hInput, ((GUICtrlRead($hInput6))-(GUICtrlRead($hInput5)*2))/3)
EndSwitch
WEnd
GUIDelete()
EndFunc
#EndRegion





