Community Pick: Many members of our community have endorsed this article.

How to move all windows on one monitor to another monitor with one keystroke - AutoHotkey Script

Joe WinogradDeveloper
CERTIFIED EXPERT
50+ years in computers
EE FELLOW 2017 — first ever recipient of Fellow award
MVE 2015,2016,2018
CERTIFIED GOLD EXPERT
DISTINGUISHED EXPERT
Published:
Updated:
Edited by: Andrew Leniart
An EE member wants to move all open windows at once (not one window at a time) from a primary monitor to a secondary one by pressing a hotkey. Bonus: another hotkey that goes in the other direction — move all windows from the secondary to the primary monitor. This article presents such a solution.

In an interesting question here at Experts Exchange, a member asked how to "in Windows 10 move all open windows at once/in one go (i.e., not window by window) from one screen (monitor) to a second screen".

In further clarification, he wants to press a "key combination" (aka a hotkey) to perform the move of all windows from the "primary/first" monitor to the "secondary/second" monitor and, as a "bonus", wants a different "key combination" (hotkey) to perform the move from the second screen back to the first one.

This article presents a solution to the member's question. It is a script that I wrote in the AutoHotkey programming/scripting language. If you are not familiar with AutoHotkey, my Experts Exchange article will get you going on it:

AutoHotkey - Getting Started

Here is the script in a code block (it is also attached as a file at the end of the article for easy downloading):

; Joe Winograd 18-Jun-2019
#Warn,UseUnsetLocal ; warning on uninitialized variables
#NoEnv ; avoid checking empty variables to see if they are environment variables
#SingleInstance Force ; replace old instance immediately
SetBatchLines,-1 ; run at maximum speed

!^f:: ; pick whatever hotkey you want - this is Alt+Ctrl+f (stands for First screen)
NewX:=100 ; the X coordinate where all windows will be moved (may be negative)
NewY:=50 ; the Y coordinate where all windows will be moved
Gosub,MoveAllWindows
Return

!^s:: ; pick whatever hotkey you want - this is Alt+Ctrl+s (stands for Second screen)
NewX:=2560 ; the X coordinate where all windows will be moved (may be negative)
NewY:=0 ; the Y coordinate where all windows will be moved
Gosub,MoveAllWindows
Return

MoveAllWindows:
WinGet,AllWindows,List ; get a list of all windows
Loop,%AllWindows% ; loop through all the windows
{
  UniqueID:=AllWindows%A_Index% ; get the unique ID of each window
  WinGetTitle,Title,ahk_id %UniqueID% ; get the Title of each window
  If ((Title="Program Manager") or (Title="")) ; list any exclusions here by adding "or" clauses
    Continue ; this Title has been excluded from moving
  WinGet,MinMaxState,MinMax,ahk_id %UniqueID% ; get the minimized/maximized state of the window
  If (MinMaxState!=0) ; -1 means it is minimized, 1 means it is maximized, 0 means it is neither
    WinRestore,ahk_id %UniqueID% ; if it is minimized or maximized, restore it before moving
  WinMove,ahk_id %UniqueID%,,%NewX%,%NewY% ; move it to its new location
}
Return


I hope that the descriptive variable names along with the extensive comments in the script provide enough documentation for readers to modify it, but if you have any questions, post them here and I'll try to assist.

The hotkeys for "move to first monitor" and "move to second monitor" may be any keys that you want. I chose the letters "f" and "s", but you could use numbers, function keys, punctuation, etc. The characters before the key that you choose may be any combination of these four characters (they are called "modifiers"):

(exclamation mark)
(caret, circumflex, hat)
(plus sign)
(hash mark, pound sign, octothorpe)

The modifiers may be in any order. They represent these keys:

is Alt
is Ctrl
is Shift
is Win (the Windows logo key)

As you can see in the source code, I chose Alt+Ctrl+f and Alt+Ctrl+s as the hotkeys, but make them whatever you prefer.

The variables for the X and Y coordinates (NewX and NewY) provide total flexibility in where the windows will be moved. Of course, they'll all be moved to the same X/Y coordinates.

In terms of determining the desired X/Y coordinates, note that there's a script called Window Spy that comes with a standard AutoHotkey installation (the installer places a shortcut to it in the AutoHotkey program group). This is very helpful in figuring out X/Y coordinates on monitors (and determining colors, too). Simply run the script and it brings up this display:



As you move the mouse, the Window Spy dialog shows in real-time the X/Y coordinates (and the color) where the mouse is located. So, to figure out what values you want for NewX and NewY in the script, run Window Spy, move the mouse to the upper left corner of where you want the script to move all the windows, and put the Screen values in the NewX and NewY variables (even though Window Spy says "less often used", the Screen value is what you want in this case).

I tested the script on W7/64-bit with three monitors and W10/64-bit with two monitors — worked perfectly. In the W7 configuration, the monitor on the left has negative X coordinates, while the monitor on the right has positive X coordinates, and the one in the middle begins with X=0 (and is positive after that).

The script should work in all versions of Windows from XP through W10, both 32-bit and 64-bit, and with any number of monitors. In fact, it even works with only one monitor, moving all the windows to the same X/Y location (for what that's worth). If you run it on a system other than the two I tested, please post your results in a Comment below. Update: I just tested it on an XP/32-bit system with one monitor — worked fine.


Article update on 19-Jun-2019 shortly after initial publication
During the publication review process, the Article Editor, Andrew Leniart, tested the script on his W10 system and came up with some great comments/questions that I'll address here.

• If a window is in a Minimized or Maximized state, the script does a Restore before moving it (see lines 27-29 in the attached script). In the case of Minimized, doing the Restore is necessary, because the WinMove command cannot move a Minimized window. In the case of a Maximized window, it is not necessary to do a Restore, but moving a Maximized window to a larger size screen results in the Maximized indicator in the window (upper right corner, middle icon), but the window is not really maximized on the larger screen. To avoid this undesirable behavior, I chose to do a Restore on a Maximized window. If you prefer not to do that, change line 28 in the script to this:

If (MinMaxState=-1) ; -1 means it is minimized, 1 means it is maximized, 0 means it is neither

• If a window is not visible (by intention), doing the Restore on the Minimized window is likely to make it visible when it is moved to the other monitor. If you do not want this to happen, exclude the window from being moved by putting another "or" clause in the "If" statement on line 25 of the script, such as:

If ((Title="Program Manager") or (Title="Task Scheduler") or (Title=""))


You may need more complex logic than the equality test shown above if, for example, the Title needs to start with a string or contain a string.

Another idea is to modify the script to save the MinMax state of each window prior to moving it and then reestablish that state after moving it. I'll leave that to the motivated reader. :)

• Be sure to change the NewX and NewY variables on lines 8, 9, 14, 15 in the script so that they are appropriate for your system and move the windows where you want them. Inappropriate values for NewX and NewY will likely result in strange, undesirable movement.


• This is an extremely simple, lightweight solution. The entire script (not counting blank lines and comments) is only 28 lines of code. It is, of course, not meant to compete with commercial products, like Actual Multiple Monitors, DisplayFusion, and UltraMon, which are large, robust programs with tons of features. My program, by design, does not even have the tiniest fraction of those programs' functionality.


My thanks to Andrew for his feedback during the publication process. The changes above that were inspired by his feedback have resulted in an improved article.


Article update on 16-Nov-2023
Tested script on Windows 11 — works perfectly!


If you find this article to be helpful, please click the thumbs-up icon below. This lets me know what is valuable for EE members and provides direction for future articles. Thanks very much! Regards, Joe


MoveAllWindows.ahk

9
11,927 Views
Joe WinogradDeveloper
CERTIFIED EXPERT
50+ years in computers
EE FELLOW 2017 — first ever recipient of Fellow award
MVE 2015,2016,2018
CERTIFIED GOLD EXPERT
DISTINGUISHED EXPERT

Comments (4)

Qlemo"Batchelor", Developer and EE Topic Advisor
CERTIFIED EXPERT
Top Expert 2015

Commented:
It should be easy to maintain window offsets. As I understand it, your script positions all windows to the same coordinates?
Joe WinogradDeveloper
CERTIFIED EXPERT
Fellow
Most Valuable Expert 2018

Author

Commented:
Hi Qlemo,

> As I understand it, your script positions all windows to the same coordinates?

Correct. They are all moved to the NewX/NewY coordinates.

> It should be easy to maintain window offsets.

Don't know if I would call it "easy" (that is subject to interpretation), but it is definitely doable. Here are some thoughts on an approach:

(1) AutoHotkey has a WinGetPos command that retrieves the position (and size) of the specified window. Use this on all the windows returned by the WinGet,AllWindows,List command in my posted code to determine the position of every window.

(2) AutoHotkey has a SysGet command that retrieves information about all monitors in a multi-monitor configuration. One of its sub-commands is Monitor, which retrieves the bounding coordinates (top, bottom, left, right) of the specified monitor.

(3) Combining (1) and (2) with some simple math, figure out the appropriate coordinates for each window on the destination monitor. However, the program would need some code to handle the situation where the destination monitor has fewer pixels than the source monitor, such as moving from a large, high resolution external display to a small, low resolution laptop screen. The math might calculate a coordinate (X or Y or both) that does not exist on the destination monitor. The program would then have to figure out where to put such a window. As I said earlier, perhaps not "easy" (depending on your definition), but certainly doable.

Regards, Joe
IT GuySys Admin/Windows Admin

Commented:
Thank you for this excellent script.
Joe WinogradDeveloper
CERTIFIED EXPERT
Fellow
Most Valuable Expert 2018

Author

Commented:
You're welcome, IT Guy, and thanks back at you for the compliment and the article Endorsement...both appreciated! Regards, Joe

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.