Page 1 of 1

Window Position Manager

Posted: 08 Oct 2020, 16:05
by BoBo
At AHK's Discord channel fellow member @KraXen72 has :arrow: posted the following request/requirements to manage a set of windows ...
hotkey: ctrl = main monitor / shift = secondary monitor
- capture the current size and positions for all windows that are not minimized on the monitor
- gui prompt to name the layout and assign a hotkey for it
- save that into a json file or something -
- hotkeys assigned will restore all programs that are running and are included in the layout
- there will be a cycle hotkey for each monitor which cycles through all layouts
Here's @elModo7's solution who coded "a window pos/res saver" AKA 'Window Position Manager'.

Code: Select all

; code by elModo7
; https://github.com/elModo7
; https://discord.com/channels/115993023636176902/653362249687105536/763809349155946547

#NoEnv
#SingleInstance Force
#Persistent
SetBatchLines, -1
#Include <json>
#Include <JSON_FromObj>
#Include <json_beautifier>
global currentMonitor := 1

F1:: 			; Save Config
windowData := {}
Loop, Files, data\monitor\%currentMonitor%\*.json
{
	FileDelete, data\monitor\%currentMonitor%\%A_LoopFileName%
}
for k, v in getWindows()
{
	FileAppend, % JSON_Beautify(json_fromobj(v)), % "data\monitor\" currentMonitor "\" v.exe "_" v.class ".json"
}
return

F2::			; Load Config
windowData := {}
for k, v in getWindows_Json()
{
	if(WinExist(v.title " ahk_class " v.class " ahk_exe " v.exe))
	{
		WinMove, % v.title " ahk_class " v.class " ahk_exe " v.exe,, % v.x, v.y, v.w, v.h
		;~ MsgBox, % "Moving " v.title " to: " v.x " - " v.y " - " v.w " - " v.h
	}
}
return

F3::			; Open config gui
	if(!WinExist("WinPos Manager Config"))
	{
		Gui Font, s16 Bold
		Gui Add, Button, x16 y56 w184 h65 gmonitor1, First Monitor
		Gui Add, Button, x240 y56 w184 h65 gmonitor2, Second Monitor
		Gui Font, s14
		Gui Add, Text, x18 y13 w407 h23 +0x200 +Center, Monitor Layout in use?
		Gui Show, w438 h143, WinPos Manager Config
	}else
	{
		WinActivate, WinPos Manager Config
	}
return

getWindows_Json()
{
	winList := {}
	Loop, Files, data\monitor\%currentMonitor%\*.json
	{
		FileRead, file, data\monitor\%currentMonitor%\%A_LoopFileName%
		win := JSON.Load(file)
		winList[winList.length()+1] := win 
	}
	return winList
}

getWindows()
{
	winList := {}
    WinGet, OpenWindow, List 
    Loop, %OpenWindow%
    {
        WinGetTitle, title, % "ahk_id " OpenWindow%A_Index%
        WinGetClass, class, % "ahk_id " OpenWindow%A_Index%
		WinGet, exe, ProcessName, % "ahk_id " OpenWindow%A_Index%
		WinGetPos, x, y, w, h, % "ahk_id " OpenWindow%A_Index%
        if(Title != "") 
		{
			win := {}
            win["title"] := title
            win["class"] := class
            win["exe"] := exe
            win["x"] := x
            win["y"] := y
            win["w"] := w
            win["h"] := h
			winList[winList.length()+1] := win 
		}
    }
    return winList
}

monitor1:
	currentMonitor := 1
	Gui, Destroy
return

monitor2:
	currentMonitor := 2
	Gui, Destroy
return

Esc::ExitApp
Full set of (include) files attached.
Questions? Join AHK's Discord Server (see Menu-Option above)!

Re: Window Position Manager

Posted: 08 Oct 2020, 16:21
by elModo7
Was fun doing it on stream!
There are many things to improve but it's a decent base to start with I guess.

Re: Window Position Manager

Posted: 10 Oct 2020, 00:03
by JRW254
That's some crafty code there. I've been playing around and if you pair it with :arrow: VirtualDesktopAccessor.dll you can use a laptop and have the profiles move into any number of virtual desktops.

Appreciate the effort elModo7 put into coming up with this. Hope other folks find it useful too.

Thanks!

Re: Window Position Manager

Posted: 11 Feb 2021, 05:41
by Peter2
elModo7 wrote:
08 Oct 2020, 16:21
..There are many things to improve but it's a decent base to start with I guess.
So is this code "ready to use" or more a "concept of functionality"?

Re: Window Position Manager

Posted: 28 Feb 2021, 10:30
by elModo7
@Peter2 it is ready to use, but it was meant as a concept of functionality. It's a sketch script I did just because someone asked.

Re: Window Position Manager

Posted: 17 Apr 2024, 08:55
by spidell
Here's one I just made, this just requires that there is a Temp folder (C:\Temp\window_positions.txt) to save the positions to:

Code: Select all

#SingleInstance force
Gui, Add, Button, x10 y10 w140 h20 gSaveWindows, Save Windows
Gui, Add, Button, x160 y10 w140 h20 gRestoreWindows, Restore Windows
ScreenCenterX := A_ScreenWidth // 2 - 150  ; Adjusted for centered alignment
ScreenY := 30
Gui, Show, x%ScreenCenterX% y%ScreenY% w312 h40, Window Positions
return

SaveWindows:
SaveWindowState()
return

RestoreWindows:
RestoreWindowState()
return

GuiClose:
ExitApp

SaveWindowState() {
    WinGet, id, list,,, Program Manager
    FileDelete, C:\Temp\window_positions.txt
    Loop, %id% {
        this_ID := id%A_Index%
        WinActivate, ahk_id %this_ID%
        WinGetTitle, title, ahk_id %this_ID%
        WinGetPos, X, Y, Width, Height, ahk_id %this_ID%
        if (title != "" && !(title contains "JobBOSS" && Width < 100 && Height < 100)) {
            FileAppend, %title%|%X%|%Y%|%Width%|%Height%`n, C:\Temp\window_positions.txt
        }
    }
    MsgBox, Window states saved successfully!
    return
}

RestoreWindowState() {
    FileRead, data, C:\Temp\window_positions.txt
    Loop, parse, data, `n, `r
    {
        if (A_LoopField == "")
            continue
        StringSplit, windowInfo, A_LoopField, |
        WinTitle := windowInfo1
        IfWinExist, %WinTitle%
        {
            WinActivate, %WinTitle%
            WinMove, %WinTitle%, , %windowInfo2%, %windowInfo3%, %windowInfo4%, %windowInfo5%
        }
    }
    MsgBox, Window states restored successfully!
    return
}
[Mod edit: Added [code][/code] tags. Please use them yourself when posting code!]