Jump to content

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

DockWin (Store/Recall window positions)


  • Please log in to reply
31 replies to this topic
AutoPaul
  • Members
  • 10 posts
  • Last active: Feb 26 2015 09:36 PM
  • Joined: 05 Jul 2014

I hate how Windows can't remember the position of all of your program windows. This is especially apparent when I undock my laptop and it goes from _dual_ 1920x1080 displays to its small, single display. When I redock I need to manually move the windows back to my preferred positions.

 

I really thought there would be a AHK script to record the current window locations and then be able to recall them when you want. I found some scripts (including one in French) but none really worked for me.

 

So I wrote the following script. Use Win-Shift-0 (zero above the P key, not on the numpad) to record the current window positions. The positions are stored in a file called WinPos.txt which is saved in the same folder as the script. You can then edit the window titles to be more generic (i.e., just "Mozille Firefox" instead of including the URL) and remove any you do not want saved.

 

To restore the window positions, use Win-0 (zero above the P key, not on the numpad).

 

The nice thing is the script creates a separate section that depends on the number of monitors, the primary monitor, and the total resolution. That means the script recognizes when the laptop is docked (and how you like your windows positioned) and also when it's undocked (and how you like your windows positioned).

 

This is my first real script and so I'm sure it's ripe for improvements. Please have at it and we will all benefit!

;DockWin v0.3 - Save and Restore window positions when docking/undocking (using hotkeys)
; Paul Troiano, 6/2014
;
; Hotkeys: ^ = Control; ! = Alt; + = Shift; # = Windows key; * = Wildcard;
;          & = Combo keys; Others include ~, $, UP (see "Hotkeys" in Help)

;#InstallKeybdHook
#SingleInstance, Force
SetTitleMatchMode, 2		; 2: A window's title can contain WinTitle anywhere inside it to be a match. 
SetTitleMatchMode, Fast		;Fast is default
DetectHiddenWindows, off	;Off is default
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
CrLf=`r`n
FileName:="WinPos.txt"



;Win-0 (Restore window positions from file)
#0::
  WinGetActiveTitle, SavedActiveWindow
  ParmVals:="Title x y height width"
  SectionToFind:= SectionHeader()
  SectionFound:= 0
 
  Loop, Read, %FileName%
  {
    if !SectionFound
    {
      ;Read through file until correction section found
      If (A_LoopReadLine<>SectionToFind) 
	Continue
    }	  

		;Exit if another section reached
		If ( SectionFound and SubStr(A_LoopReadLine,1,8)="SECTION:")
			Break

                SectionFound:=1
		Win_Title:="", Win_x:=0, Win_y:=0, Win_width:=0, Win_height:=0

		Loop, Parse, A_LoopReadLine, CSV 
		{
			EqualPos:=InStr(A_LoopField,"=")
			Var:=SubStr(A_LoopField,1,EqualPos-1)
			Val:=SubStr(A_LoopField,EqualPos+1)
			IfInString, ParmVals, %Var%
			{
				;Remove any surrounding double quotes (")
				If (SubStr(Val,1,1)=Chr(34)) 
				{
					StringMid, Val, Val, 2, StrLen(Val)-2
				}
				Win_%Var%:=Val  
			}
		}

		If ( (StrLen(Win_Title) > 0) and WinExist(Win_Title) )
		{	
			WinRestore
			WinActivate
			WinMove, A,,%Win_x%,%Win_y%,%Win_width%,%Win_height%
		}

  }

  if !SectionFound
  {
    msgbox,,Dock Windows, Section does not exist in %FileName% `nLooking for: %SectionToFind%`n`nTo save a new section, use Win-Shift-0 (zero key above letter P on keyboard)
  }

  ;Restore window that was active at beginning of script
  WinActivate, %SavedActiveWindow%
RETURN


;Win-Shift-0 (Save current windows to file)
#+0::

 MsgBox, 4,Dock Windows,Save window positions?
 IfMsgBox, NO, Return

 WinGetActiveTitle, SavedActiveWindow

 file := FileOpen(FileName, "a")
 if !IsObject(file)
 {
	MsgBox, Can't open "%FileName%" for writing.
	Return
 }

  line:= SectionHeader() . CrLf
  file.Write(line)

  ; Loop through all windows on the entire system
  WinGet, id, list,,, Program Manager
  Loop, %id%
  {
    this_id := id%A_Index%
    WinActivate, ahk_id %this_id%
    WinGetPos, x, y, Width, Height, A ;Wintitle
    WinGetClass, this_class, ahk_id %this_id%
    WinGetTitle, this_title, ahk_id %this_id%

	if ( (StrLen(this_title)>0) and (this_title<>"Start") )
	{
		line=Title="%this_title%"`,x=%x%`,y=%y%`,width=%width%`,height=%height%`r`n
		file.Write(line)
   	}
  }

  file.write(CrLf)  ;Add blank line after section
  file.Close()

  ;Restore active window
  WinActivate, %SavedActiveWindow%
RETURN

; -------

;Create standardized section header for later retrieval
SectionHeader()
{
	SysGet, MonitorCount, MonitorCount
	SysGet, MonitorPrimary, MonitorPrimary
	line=SECTION: Monitors=%MonitorCount%,MonitorPrimary=%MonitorPrimary%

        WinGetPos, x, y, Width, Height, Program Manager
	line:= line . "; Desktop size:" . x . "," . y . "," . width . "," . height

	Return %line%
}

;<EOF>

Paul



pomj
  • Members
  • 30 posts
  • Last active: Jan 29 2017 09:15 PM
  • Joined: 22 Feb 2007

Perfect! Just what I have been looking for. On initial test seems to work perfectly. Will try it out tomorrow in a multimonitor environment.



AutoPaul
  • Members
  • 10 posts
  • Last active: Feb 26 2015 09:36 PM
  • Joined: 05 Jul 2014

To give folks a better idea of how this works, here is my WinPos.Txt file. It has three sections for which I commonly use: my laptop docked with dual screens, my laptop plugged into an external monitor (at home), and just the free-standing laptop. I just use Win-0 and the script recongnizes which setup it is operating under and resets the windows accordingly. Note that you can see how I generalized the window names so that they are not tied to specific documents. (You could actually do this if you wanted to.)

SECTION: Monitors=1,MonitorPrimary=1; Desktop size:0,0,1366,768
Title="Calendar - Paul",x=150,y=0,width=1055,height=728
Title="Inbox - Paul",x=150,y=0,width=1055,height=728
Title="Mozilla Firefox",x=76,y=0,width=1283,height=728
Title="Microsoft Excel",x=120,y=0,width=1246,height=728
Title="Microsoft PowerPoint",x=65,y=0,width=1295,height=728
Title="Reminder",x=623,y=235,width=473,height=336

SECTION: Monitors=2,MonitorPrimary=2; Desktop size:-1920,0,3840,1080
Title="Calendar - Paul",x=-1921,y=0,width=871,height=1080
Title="Inbox - Paul",x=-1056,y=0,width=1055,height=1080
Title="Internet Explorer",x=-1477,y=20,width=1265,height=995
Title="Microsoft PowerPoint",x=291,y=41,width=1506,height=945
Title="Mozilla Firefox",x=180,y=72,width=1359,height=937
Title="Microsoft Excel",x=398,y=17,width=1424,height=996
Title="Reminder",x=623,y=235,width=473,height=336

SECTION: Monitors=1,MonitorPrimary=1; Desktop size:0,0,1920,1080
Title="Calendar - Paul",x=205,y=0,width=871,height=1040
Title="Inbox - Paul",x=127,y=0,width=1055,height=1040
Title="Windows Internet Explorer",x=289,y=46,width=1332,height=955
Title="Mozilla Firefox",x=227,y=17,width=1329,height=968
Title="Microsoft Excel",x=399,y=0,width=1424,height=1040
Title="Microsoft PowerPoint",x=662,y=0,width=1256,height=1040
Title="Reminder",x=623,y=235,width=473,height=336

Again you don't need to create this file, the script will append a section every time you use Win-Shift-0.

 



Run1e
  • Moderators
  • 173 posts
  • ( ͡° ͜ʖ ͡°)
  • Last active: Nov 06 2015 01:46 PM
  • Joined: 18 Aug 2013

That file syntax looks pretty awesome. Nice work!


Take a look at my WIP website! - http://runie.me/

Check out my scripts! -
Columbus - program launcher / focus switcher
BF4 NoRecoil - Assault

AutoPaul
  • Members
  • 10 posts
  • Last active: Feb 26 2015 09:36 PM
  • Joined: 05 Jul 2014

That file syntax looks pretty awesome. Nice work!

Thanks! I'm finding this small tool to be a big time saver.



Skrell
  • Members
  • 384 posts
  • Last active: Jul 07 2016 05:03 PM
  • Joined: 23 Aug 2011

Any chance this script could be made more transparent by automatically recording the location and size of windows upon closing them and then restoring them when the windows are then respawned? 



tin0men
  • Members
  • 2 posts
  • Last active: Feb 03 2016 06:20 PM
  • Joined: 11 Jun 2014

Excellent piece of work!

 

I'm in a similar situation: laptop screen as monitor2 at work, and sole-display when working remotely; hibernating Win7 on trips between and fighting/dragging windows around to keep things in the right places to stay productive.

 

I was contemplating writing my own script (for the nth time), and actively looking again for some code in the niche, when I found your new post: Your script quickly snaps everything exactly where I want it!

 

Only observation I had, was that I had some issues running it when I tried to splice it into my master .ahk (fileopen issues, seemed unable to create/find the WinPost.txt file). But it works just fine run from it's own ahk. Probably a conflict with my use of SetTitleMatchMode RegEx

 

Thanks!



AutoPaul
  • Members
  • 10 posts
  • Last active: Feb 26 2015 09:36 PM
  • Joined: 05 Jul 2014

Any chance this script could be made more transparent by automatically recording the location and size of windows upon closing them and then restoring them when the windows are then respawned? 

Possibly, but I don't think I could do it. The only way I know of how to even attempt something like this is to constantly scan the windows and look for one that "disappears" (i.e., is closed) or one that was just newly created (i.e., opened). I would think this would create a tremendous amout of overhead and slow the computer down substantially. So it would take some with much greater knowledge of the inner workings of windows (maybe there are events that fire when windows open/close). Hopefully someone more knowledgable than me will  contribute their ideas

 

At the end of the day, it sounds like the approach you want to managing windows is solving for a different problem than what my script does.

 

Excellent piece of work!

...

Only observation I had, was that I had some issues running it when I tried to splice it into my master .ahk (fileopen issues, seemed unable to create/find the WinPost.txt file). But it works just fine run from it's own ahk. Probably a conflict with my use of SetTitleMatchMode RegEx

 

Thanks! I too use a master AHK file to keep my shortcuts but I have not tried pulling this code into it. If the problem is the RegEx setting, you could try modifiying the #0:: (restore window postions) section to change the TitleMatchMode to "2". (Actually I would save the value in A_TitleMatchMode to a variable, change the setting to 2, and then before the RETURN line restore the TitleMatchMode to the saved value. I would also make sure to move the setting of the "global" variables (CrLF,  FileName, SetWorkingDIr, etc.) to the top of your master script file. I believe they don't run if they are not at the top.

 

If I have a chance this weekend, I'll see if I can pull the DockWin scripts into my master script file.



AutoPaul
  • Members
  • 10 posts
  • Last active: Feb 26 2015 09:36 PM
  • Joined: 05 Jul 2014

Any chance this script could be made more transparent by automatically recording the location and size of windows upon closing them and then restoring them when the windows are then respawned? 

Possibly, but I don't think I could do it. The only way I know of how to even attempt something like this is to constantly scan the windows and look for one that "disappears" (i.e., is closed) or one that was just newly created (i.e., opened). I would think this would create a tremendous amout of overhead and slow the computer down substantially. So it would take some with much greater knowledge of the inner workings of windows (maybe there are events that fire when windows open/close). Hopefully someone more knowledgable than me will  contribute their ideas

 

At the end of the day, it sounds like the approach you want to managing windows is solving for a different problem than what my script does.

 

Excellent piece of work!

...

Only observation I had, was that I had some issues running it when I tried to splice it into my master .ahk (fileopen issues, seemed unable to create/find the WinPost.txt file). But it works just fine run from it's own ahk. Probably a conflict with my use of SetTitleMatchMode RegEx

 

Thanks! I too use a master AHK file to keep my shortcuts but I have not tried pulling this code into it. If the problem is the RegEx setting, you could try modifiying the #0:: (restore window postions) section to change the TitleMatchMode to "2". (Actually I would save the value in A_TitleMatchMode to a variable, change the setting to 2, and then before the RETURN line restore the TitleMatchMode to the saved value. I would also make sure to move the setting of the "global" variables (CrLF,  FileName, and the SetWorkingDIr) to the top of your master script file. I believe they don't run if they are not at the top.

 

If I have a chance this weekend, I'll see if I can pull the DockWin scripts into my master script file and post how it goes.



Skrell
  • Members
  • 384 posts
  • Last active: Jul 07 2016 05:03 PM
  • Joined: 23 Aug 2011

Possibly, but I don't think I could do it. The only way I know of how to even attempt something like this is to constantly scan the windows and look for one that "disappears" (i.e., is closed) or one that was just newly created (i.e., opened). I would think this would create a tremendous amout of overhead and slow the computer down substantially. So it would take some with much greater knowledge of the inner workings of windows (maybe there are events that fire when windows open/close). Hopefully someone more knowledgable than me will  contribute their ideas

 

At the end of the day, it sounds like the approach you want to managing windows is solving for a different problem than what my script does.

 

 

What about if you used the ONMESSAGE function of autohotkey?  I'm not expert, but i would think that every time a window is created or destroyed a message would be generated by windows that you could pick up and then execute your function with.  This shouldn't slow down a PC at all i would think.  What do you think ? 



AutoPaul
  • Members
  • 10 posts
  • Last active: Feb 26 2015 09:36 PM
  • Joined: 05 Jul 2014

What about if you used the ONMESSAGE function of autohotkey?  I'm not expert, but i would think that every time a window is created or destroyed a message would be generated by windows that you could pick up and then execute your function with.  This shouldn't slow down a PC at all i would think.  What do you think ? 

 

I think you're right that ONMESSAGE could be leveraged to potentially do what you want. I really know nothing about the internal messaging system in Windows and what they all mean. It would take a fair amount of research and experimentation for me to figure it out.

 

I don't find pressing Win-0 to restore my window locations to be a big deal, and so I am still thinking you are trying to solve for different problem. Hopefully our conversation will plant a seed in someone with the right skills and needs similar to yours.



vertigoelectric
  • Members
  • 53 posts
  • Last active: Sep 07 2016 03:26 PM
  • Joined: 06 May 2009

This script is something I'm looking for but I'm having a very strange problem.  When I try to run it I get an error for a call to a nonexistent function:

 

snap_(2014-08-21)(13.25.08)_1940.png

 

 

Same error when script is compiled:

 

snap_(2014-08-21)(13.25.43)_1941.png

 

 

I'm using the latest version of AHK.

 

Why in the world would this be happening?



AutoPaul
  • Members
  • 10 posts
  • Last active: Feb 26 2015 09:36 PM
  • Joined: 05 Jul 2014

This script is something I'm looking for but I'm having a very strange problem.  When I try to run it I get an error for a call to a nonexistent function:

...

 

I'm using the latest version of AHK.

 

Why in the world would this be happening?

 

Actually I don't think you are using the latest version. I was having a similar problem when I was testing the script on my home PC. I'm running Version v1.1.14.03 (check your version # by looking at the initial Help screen).

 

You can download from http://ahkscript.org. My mistake was trying to download from autohotkey.com which seems to have an older version. I'm really not sure why there are two websites for ahk.

 

Good luck.

 

Paul

 



HudsonMC
  • Members
  • 1 posts
  • Last active: Nov 03 2014 09:19 PM
  • Joined: 03 Nov 2014

I'm getting the following erros when I press win-shift-0 and clicking "yes"

 

Can't open "" for writing. 

 

I don't know why the filename isn't saving. Is there something that must be done to "initialize" the script?

 

EDIT: Never mind. I re-read some of these posts in here, and realized they were, in fact, talking about the same problem. Got it fixed by moving the dockwin script to the top of the ahk file. 



Winkyboy
  • Members
  • 2 posts
  • Last active: Nov 04 2014 02:52 PM
  • Joined: 21 Oct 2014

Argh.  Sadly, this does not remember all "satellite" windows of Visual Studio.... but thank you for this script - it's awesome nonetheless!