Automatically Restore Last Window Position For Each Process

Post your working scripts, libraries and tools
jeka
Posts: 8
Joined: 30 Mar 2018, 05:24

Re: Automatically Restore Last Window Position For Each Process

Post by jeka » 31 Mar 2018, 04:13

brutus_skywalker wrote:
jeka wrote:Playing a bit more with v2, noticed that if I resize-reposition mintty.exe window in the main monitor, the position is remembered/restored. If I move mintty.exe to the secondary, then close and re-open, it opens up in the last position for the main monitor. Is this expected?
EDIT: i updated -v2- post, try it now, let me know how it performs, i can't test it because i have a single monitor, but i removed the constraints that were logically causing the issue.
Brilliant.
jeka
Posts: 8
Joined: 30 Mar 2018, 05:24

Re: Automatically Restore Last Window Position For Each Process

Post by jeka » 31 Mar 2018, 09:40

Emacs tends to open quite slowly, and usually sets its initial window size after it is fully loaded. That means that v2 immediately moves/resizes Emacs window to its last known position (perfectly sensible) immediately upon Emacs launch, but then Emacs finishes loading and resizes its window to what is its default setting.

One way to avoid this, perhaps, to delay in v2 resizing/moving of Emacs window by some time. Is this sensible? Possible?
ovnis
Posts: 12
Joined: 25 Mar 2018, 13:40

Re: Automatically Restore Last Window Position For Each Process

Post by ovnis » 31 Mar 2018, 11:50

I have try to find all the night why it's not works on my computer but without success. Finaly your first version is pretty good. I will stay with it... Thx for your help. :)
brutus_skywalker
Posts: 175
Joined: 24 Dec 2016, 13:16
Location: Antarctica

Re: Automatically Restore Last Window Position For Each Process

Post by brutus_skywalker » 31 Mar 2018, 13:39

jeka wrote:Emacs tends to open quite slowly, and usually sets its initial window size after it is fully loaded. That means that v2 immediately moves/resizes Emacs window to its last known position (perfectly sensible) immediately upon Emacs launch, but then Emacs finishes loading and resizes its window to what is its default setting.

One way to avoid this, perhaps, to delay in v2 resizing/moving of Emacs window by some time. Is this sensible? Possible?

Just add the following lines above both WinMove commands in the script:

Code: Select all

IfEqual, activeProcessName, emacs.exe		;change the exe name to the name of your emacs executable, if different to this.
	Sleep, 5000			;in milliseconds,  change this to what ever delay you've noticed with emacs starting up
Outsourcing Clicks & Presses Since 2004.
mankvl
Posts: 15
Joined: 23 Sep 2016, 03:58

Re: Automatically Restore Last Window Position For Each Process

Post by mankvl » 03 Apr 2018, 09:41

brutus_skywalker wrote:
mankvl wrote:Would be nice to have title ExclusionList. I wan't main outlook windows to be maximized but new message only half screen. Is this possible ?
This should allow you to filter out altering the position of a filtered application so long as it's title is also blacklisted against resizing or moving... just add the title you wish to filter in a new line as shown below, there should be a Title_Filter variable to which you can add titles to filter just under the application filter list. ;)

Code: Select all

Title_Filter =		;add every new title on a new line
(
Automatically Restore Last Window Position For Each Process - AutoHotkey Community - Mozilla Firefox
)

Code: Select all


; Automatically Restore Previous Window Size/Pos

; To make this script run when windows starts, make sure RegistryAdd.ahk is in the same directory as this script, run this script, and it will be added to the registry. Then delete RegistryAdd.ahk
; #Include *i RegistryAdd.ahk

; To easily remove the previously added registry entry, make sure RegistryRemove.ahk is in the same directory as this script, run this script, and it will be removed from the registry. Then delete RegistryRemove.ahk
; #Include *i RegistryRemove.ahk

#NoTrayIcon

#SingleInstance Force
#Persistent
#NoEnv
SetWinDelay, 50
Process, Priority, , Normal

MatchList := ""

; Build the MatchList
WinGet, id, list,,, Program Manager
Loop, %id%
{
    this_id := id%A_Index%
	if (MatchList = "")
	MatchList := this_id
	else
	MatchList := MatchList . "," . this_id 
}

;Filter - only programs listed here have their size and position automatically managed,otherwise without this filter wierd malfunctions occur with dialog boxes being resized to their parent program and such...
Filter = xulrunner.exe,firefox.exe,notepad.exe,chrome.exe,notepad++.exe
Title_Filter =		;add every new title on a new line
(
Automatically Restore Last Window Position For Each Process - AutoHotkey Community - Mozilla Firefox
)

; ExclusionList		--- use this as alternative to filter above,i.e this will exclude applications below from automated resize/relocate
ExclusionList = ShellExperienceHost.exe,SearchUI.exe,notepad++.exe,cpuz.exe,gpu-z.0.3.3.exe


; The main program loop, which manages window positions/sizes and saves their last known configuration to an ini file in the script directory.
Loop,
{
Title_Filter_reInit:		;a patch to allow terminating further checks when a filtered title is active within a filtered application

	Sleep, 350
	WinGet, active_id, ID, A
	if active_id not in %MatchList% ; Then this is a new window ID! So, check if it has a configuration saved.
	{
		MatchList := MatchList . "," . active_id ; This window ID is not new anymore!
		WinGet, active_ProcessName, ProcessName, A
		WinGetClass, active_Class, A
		IniRead, savedSizePos, %A_ScriptDir%\WindowSizePosLog.ini, Process Names, %active_ProcessName%
		; MsgBox, debug marker 1  %pClass%
		if (savedSizePos != "ERROR" AND active_Class != "MultitaskingViewFrame" AND active_class != "Shell_TrayWnd" ) ; Then a saved configuration exists, size/move the window!
		{
			StringSplit OutputArray, savedSizePos,`,
			if (active_ProcessName = "explorer.exe" AND active_Class != "CabinetWClass")
			{
				
			}
			else
			{
			;Last minute check to make sure Active windows matches specified classname
			WinGetClass, active_Class, A
			IniRead, pClass, %A_ScriptDir%\WindowSizePosLog.ini, Process Names, %active_ProcessName%_pClass
			if ( pClass = active_Class )
				{
				if ( active_Class != #32770 )	;filter open/save dialog boxes
					{
					WinMove, A,, OutputArray1, OutputArray2, OutputArray3, OutputArray4
					; MsgBox, debug marker 0 %pClass% v %active_Class%
					}
				}
			}
		}
		else ; No saved configuration exists, save the current window size/pos as a configuration instead!
		{
			WinGetPos X, Y, Width, Height, A
			WinGet, active_ProcessName, ProcessName, A
			WinGetClass, active_Class, A
			If (X != "" AND Y != "" AND Width != "" AND Height != "" AND Width > 0 AND Height > 0 AND active_Class != "MultitaskingViewFrame" AND active_class != "Shell_TrayWnd")
			{
				if (active_ProcessName = "explorer.exe" AND active_Class != "CabinetWClass")
				{
					
				}
				else if active_ProcessName not in %ExclusionList%
				{
				if active_ProcessName in %Filter%																					;TWEAK to only add specific programs to windowConfiguration
					{
					;Title_Filter patch
					WinGetActiveTitle, this_activeTitle
					IfInString, Title_Filter, this_activeTitle	;if active window is filtered by title, return to beginning of loop until active window is unfiltered
						Goto, Title_Filter_reInit
											
					
					WinGetClass, active_Class, A
					IniRead, pClass, %A_ScriptDir%\WindowSizePosLog.ini, Process Names, %active_ProcessName%_pClass
					;To PREVENT SIZE OF DIALOG BOX BEING ASSIGNED AS SIZE AND LOCATION OF MAIN PROCESS WINDOW
					if ( pClass = active_Class OR pClass = "ERROR" )		;if process has not yet been assigned class value or if active window matches process class write!.
						{
						IniWrite %X%`,%Y%`,%Width%`,%Height%, %A_ScriptDir%\WindowSizePosLog.ini, Process Names, %active_ProcessName%
						}
					WinGetClass, exePrimaryClass, ahk_exe %active_ProcessName%
					if ( pClass = "ERROR" )		;to make sure the class tied to an exe is only written when the window is first detected,so it's position can be updated but not it's class name.
						{
						; MsgBox, debug marker 2  %ExEpClass%  - %exePrimaryClass%
						IniWrite %exePrimaryClass%, %A_ScriptDir%\WindowSizePosLog.ini, Process Names, %active_ProcessName%_pClass
						}
					}
				}
			}
		}
	}
	else ; Save/overwrite the active window size and position to a file with a link to the processname, for later use.
	{
		WinGetPos X, Y, Width, Height, A
		WinGet, active_ProcessName, ProcessName, A
		WinGetClass, active_Class, A
		If (X != "" AND Y != "" AND Width != "" AND Height != "" AND Width > 0 AND Height > 0 AND active_Class != "MultitaskingViewFrame" AND active_class != "Shell_TrayWnd")
		{
			if (active_ProcessName = "explorer.exe" AND active_Class != "CabinetWClass")
			{
				
			}
			else if active_ProcessName not in %ExclusionList%
			{
			if active_ProcessName in %Filter%																					;TWEAK to only add specific programs to windowConfiguration
				{
				;Title_Filter patch
				WinGetActiveTitle, this_activeTitle
				IfInString, Title_Filter, this_activeTitle	;if active window is filtered by title, return to beginning of loop until active window is unfiltered
					Goto, Title_Filter_reInit

				
				WinGetClass, active_Class, A
				IniRead, pClass, %A_ScriptDir%\WindowSizePosLog.ini, Process Names, %active_ProcessName%_pClass
				;To PREVENT SIZE OF DIALOG BOX BEING ASSIGNED AS SIZE AND LOCATION OF MAIN PROCESS WINDOW
				if ( pClass = active_Class OR pClass = "ERROR" )		;if process has not yet been assigned class value or if active window matches process class write!.
					{
					IniWrite %X%`,%Y%`,%Width%`,%Height%, %A_ScriptDir%\WindowSizePosLog.ini, Process Names, %active_ProcessName%
					}
				WinGetClass, exePrimaryClass, ahk_exe %active_ProcessName%
				if ( pClass = "ERROR" )		;to make sure the class tied to an exe is only written when the window is first detected,so it's position can be updated but not it's class name.
					{
					; MsgBox, debug marker 3  %ExEpClass%  - %exePrimaryClass%
					IniWrite %exePrimaryClass%, %A_ScriptDir%\WindowSizePosLog.ini, Process Names, %active_ProcessName%_pClass
					}
				}
			}
		}
	}
}
Return


I still don't get it. So I need to put the exact title of the outlook window that I don't want to move and resize? Can i use just a part of it, or this is only set to SetTitleMatchMode 1?

Code: Select all

;Filter - only programs listed here have their size and position automatically managed,otherwise without this filter wierd malfunctions occur with dialog boxes being resized to their parent program and such...
Filter = outlook.exe, AcroRd32.exe, WINWORD.EXE,  EXCEL.EXE,  
Title_Filter =		;add every new title on a new line
(
Inbox - email@email.com - Microsoft Outlook
)

; ExclusionList		--- use this as alternative to filter above,i.e this will exclude applications below from automated resize/relocate
ExclusionList = ShellExperienceHost.exe,SearchUI.exe,notepad++.exe,cpuz.exe,gpu-z.0.3.3.exe
Even with adding the title it always resizes the windows after outlook launch. Any way to make smth similar to WinSize2 but just not outdated, i have few problems with always on top. I would like to save the position o the window by its name and class or exe, and then make AHK always resize/move it to the same position when I launch the programs.
brutus_skywalker
Posts: 175
Joined: 24 Dec 2016, 13:16
Location: Antarctica

Re: Automatically Restore Last Window Position For Each Process

Post by brutus_skywalker » 07 Apr 2018, 08:27

@mankvl
It does a basic absolute string matching of active title in title_filter list, so title does need to be complete title,you can use Active Window Info utility. And i Highly recommend ESPECIALLY if you don't use Windows Universal Platform Apps in windows 10, that you switch to my -v2 rewrite posted in page-2, it's more intuitive for me but also for anyone who wants to understand & tweak it to their whim. Here's a TESTED patch of the title filter though,in case you want to stick with the old version.

It's a straight forward fix, a check for a title match in title_filter for active window title at every top level if-else statement, and restart loop if match is found...

EDIT:Fixed typo.

Code: Select all


; Automatically Restore Previous Window Size/Pos

; To make this script run when windows starts, make sure RegistryAdd.ahk is in the same directory as this script, run this script, and it will be added to the registry. Then delete RegistryAdd.ahk
; #Include *i RegistryAdd.ahk

; To easily remove the previously added registry entry, make sure RegistryRemove.ahk is in the same directory as this script, run this script, and it will be removed from the registry. Then delete RegistryRemove.ahk
; #Include *i RegistryRemove.ahk

#NoTrayIcon

#SingleInstance Force
#Persistent
#NoEnv
SetWinDelay, 50
Process, Priority, , Normal

MatchList := ""

; Build the MatchList
WinGet, id, list,,, Program Manager
Loop, %id%
{
    this_id := id%A_Index%
	if (MatchList = "")
	MatchList := this_id
	else
	MatchList := MatchList . "," . this_id 
}

;Filter - only programs listed here have their size and position automatically managed,otherwise without this filter wierd malfunctions occur with dialog boxes being resized to their parent program and such...
Filter = xulrunner.exe,firefox.exe,notepad.exe,chrome.exe,notepad++.exe
Title_Filter =		;add every new title on a new line
(
Automatically Restore Last Window Position For Each Process - AutoHotkey Community - Mozilla Firefox
)

; ExclusionList		--- use this as alternative to filter above,i.e this will exclude applications below from automated resize/relocate
ExclusionList = ShellExperienceHost.exe,SearchUI.exe,notepad++.exe,cpuz.exe,gpu-z.0.3.3.exe


; The main program loop, which manages window positions/sizes and saves their last known configuration to an ini file in the script directory.
Loop,
{
Title_Filter_reInit:		;a patch to allow terminating further checks when a filtered title is active within a filtered application

	Sleep, 350
	WinGet, active_id, ID, A
	if active_id not in %MatchList% ; Then this is a new window ID! So, check if it has a configuration saved.
	{
	;Title_Filter patch
	WinGetActiveTitle, this_activeTitle
	IfInString, Title_Filter, %this_activeTitle%	;if active window is filtered by title, return to beginning of loop until active window is unfiltered
		Goto, Title_Filter_reInit

			MatchList := MatchList . "," . active_id ; This window ID is not new anymore!
		WinGet, active_ProcessName, ProcessName, A
		WinGetClass, active_Class, A
		IniRead, savedSizePos, %A_ScriptDir%\WindowSizePosLog.ini, Process Names, %active_ProcessName%
		; MsgBox, debug marker 1  %pClass%
		if (savedSizePos != "ERROR" AND active_Class != "MultitaskingViewFrame" AND active_class != "Shell_TrayWnd" ) ; Then a saved configuration exists, size/move the window!
		{
			StringSplit OutputArray, savedSizePos,`,
			if (active_ProcessName = "explorer.exe" AND active_Class != "CabinetWClass")
			{
				
			}
			else
			{
			;Last minute check to make sure Active windows matches specified classname
			WinGetClass, active_Class, A
			IniRead, pClass, %A_ScriptDir%\WindowSizePosLog.ini, Process Names, %active_ProcessName%_pClass
			if ( pClass = active_Class )
				{
				if ( active_Class != #32770 )	;filter open/save dialog boxes
					{
					WinMove, A,, OutputArray1, OutputArray2, OutputArray3, OutputArray4
					; MsgBox, debug marker 0 %pClass% v %active_Class%
					}
				}
			}
		}
		else ; No saved configuration exists, save the current window size/pos as a configuration instead!
		{
			WinGetPos X, Y, Width, Height, A
			WinGet, active_ProcessName, ProcessName, A
			WinGetClass, active_Class, A
			If (X != "" AND Y != "" AND Width != "" AND Height != "" AND Width > 0 AND Height > 0 AND active_Class != "MultitaskingViewFrame" AND active_class != "Shell_TrayWnd")
			{
				if (active_ProcessName = "explorer.exe" AND active_Class != "CabinetWClass")
				{
					
				}
				else if active_ProcessName not in %ExclusionList%
				{
				if active_ProcessName in %Filter%																					;TWEAK to only add specific programs to windowConfiguration
					{
											
					
					WinGetClass, active_Class, A
					IniRead, pClass, %A_ScriptDir%\WindowSizePosLog.ini, Process Names, %active_ProcessName%_pClass
					;To PREVENT SIZE OF DIALOG BOX BEING ASSIGNED AS SIZE AND LOCATION OF MAIN PROCESS WINDOW
					if ( pClass = active_Class OR pClass = "ERROR" )		;if process has not yet been assigned class value or if active window matches process class write!.
						{
						IniWrite %X%`,%Y%`,%Width%`,%Height%, %A_ScriptDir%\WindowSizePosLog.ini, Process Names, %active_ProcessName%
						}
					WinGetClass, exePrimaryClass, ahk_exe %active_ProcessName%
					if ( pClass = "ERROR" )		;to make sure the class tied to an exe is only written when the window is first detected,so it's position can be updated but not it's class name.
						{
						; MsgBox, debug marker 2  %ExEpClass%  - %exePrimaryClass%
						IniWrite %exePrimaryClass%, %A_ScriptDir%\WindowSizePosLog.ini, Process Names, %active_ProcessName%_pClass
						}
					}
				}
			}
		}
	}
	else ; Save/overwrite the active window size and position to a file with a link to the processname, for later use.
	{
	;Title_Filter patch
	WinGetActiveTitle, this_activeTitle
	IfInString, Title_Filter, %this_activeTitle%	;if active window is filtered by title, return to beginning of loop until active window is unfiltered
		Goto, Title_Filter_reInit

		WinGetPos X, Y, Width, Height, A
		WinGet, active_ProcessName, ProcessName, A
		WinGetClass, active_Class, A
		If (X != "" AND Y != "" AND Width != "" AND Height != "" AND Width > 0 AND Height > 0 AND active_Class != "MultitaskingViewFrame" AND active_class != "Shell_TrayWnd")
		{
			if (active_ProcessName = "explorer.exe" AND active_Class != "CabinetWClass")
			{
				;checi if active explorer window contains an address bar with a path
				WinGetText, activeWinText, A
				Loop, Parse, activeWinText, `n
					If A_LoopField contains Address
						If A_LoopField contains :\
					
			}
			else if active_ProcessName not in %ExclusionList%
			{
			if active_ProcessName in %Filter%																					;TWEAK to only add specific programs to windowConfiguration
				{				
				WinGetClass, active_Class, A
				IniRead, pClass, %A_ScriptDir%\WindowSizePosLog.ini, Process Names, %active_ProcessName%_pClass
				;To PREVENT SIZE OF DIALOG BOX BEING ASSIGNED AS SIZE AND LOCATION OF MAIN PROCESS WINDOW
				if ( pClass = active_Class OR pClass = "ERROR" )		;if process has not yet been assigned class value or if active window matches process class write!.
					{
					IniWrite %X%`,%Y%`,%Width%`,%Height%, %A_ScriptDir%\WindowSizePosLog.ini, Process Names, %active_ProcessName%
					}
				WinGetClass, exePrimaryClass, ahk_exe %active_ProcessName%
				if ( pClass = "ERROR" )		;to make sure the class tied to an exe is only written when the window is first detected,so it's position can be updated but not it's class name.
					{
					; MsgBox, debug marker 3  %ExEpClass%  - %exePrimaryClass%
					IniWrite %exePrimaryClass%, %A_ScriptDir%\WindowSizePosLog.ini, Process Names, %active_ProcessName%_pClass
					}
				}
			}
		}
	}
}
Return


Outsourcing Clicks & Presses Since 2004.
ovnis
Posts: 12
Joined: 25 Mar 2018, 13:40

Re: Automatically Restore Last Window Position For Each Process

Post by ovnis » 15 May 2018, 12:35

Hello,

Do you know why when Windows wakeup form hybernation/hybrid hybernation or when your screen turnes back on, sometimes, somes windows aren't recall at the good place or size dispite the "Automatically Restore Last Window Position For Each Process" activated ?
brutus_skywalker
Posts: 175
Joined: 24 Dec 2016, 13:16
Location: Antarctica

Re: Automatically Restore Last Window Position For Each Process

Post by brutus_skywalker » 16 May 2018, 12:59

ovnis wrote:Hello,

Do you know why when Windows wakeup form hybernation/hybrid hybernation or when your screen turnes back on, sometimes, somes windows aren't recall at the good place or size dispite the "Automatically Restore Last Window Position For Each Process" activated ?
There've been quite a number of instances where in win8/10 I've noticed not just scripts but even other processes being stuck in a suspended state,perhaps your issue is along those lines. Can't think of anything else, the script is literally just a simple conditional loop without any 'while' statements.

https://superuser.com/questions/1056944 ... nded-state
Outsourcing Clicks & Presses Since 2004.
ovnis
Posts: 12
Joined: 25 Mar 2018, 13:40

Re: Automatically Restore Last Window Position For Each Process

Post by ovnis » 21 May 2018, 14:28

Hi, thx for the replay.

I have found "windowManager" from dekstof. The software is amazing, and now I have zero window issue. All windows work great ! OneNote, task manager, etc.
Post Reply

Return to “Scripts and Functions”