This can be done with the below AutoHotKey script,
which accepts two shortcut keys:
- F11 : Will write the titles of all current windows and their
virtual desktop numbers to a text file specified in the parameter
FILENAME
that is found at the beginning of the script.
- F12 : Reads the text file and moves all the windows it can find
by their title to the specified virtual desktop.
Copy the following text into an .ahk
file, possibly changing "FILENAME",
"F11" and "F12".
Double-click the file to start it executing. It will create a green "H"
icon in the traybar that you can right-click and select Exit
to stop.
If you always want this script to execute, copy it to the user Startup folder at
C:\Users\<user name>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
.
This script requires to download from the Github project
windows-desktop-switcher
the DLL
VirtualDesktopAccessor.dll
and storing it in the same folder as the AutoHotKey script.
It might not work for Windows 10 versions below 1809.
The script itself is below and is programmed for only one monitor.
It does not create the virtual desktops, so they should be created
before running it.
It worked for me, but should be tested.
As it's using undocumented features, it might
stop working some time in the future.
DetectHiddenWindows Off
SetTitleMatchMode, 2
FILENAME = C:\Temp\possaves.txt
hVirtualDesktopAccessor := DllCall("LoadLibrary", Str, "VirtualDesktopAccessor.dll", "Ptr")
MoveWindowToDesktopNumberProc := DllCall("GetProcAddress", Ptr, hVirtualDesktopAccessor, AStr, "MoveWindowToDesktopNumber", "Ptr")
IsWindowOnDesktopNumberProc := DllCall("GetProcAddress", Ptr, hVirtualDesktopAccessor, AStr, "IsWindowOnDesktopNumber", "Ptr")
global numdesktops := GetDesktopsNumber()
F11:: ; Write list of "desktop@title"
EnumAddress := RegisterCallback("EnumWindowsProc", "Fast")
global numwins := 0
global file := FileOpen(FILENAME, "w")
DllCall("EnumWindows", "Ptr", EnumAddress, "Ptr", 0)
file.Close()
return
F12:: ; Read list and execute
global result
Loop, Read, %FILENAME%
{
word_array := StrSplit(A_LoopReadLine, "@",, 2) ; Omits periods.
hwnd := WinExist(word_array[2])
if (hwnd)
DllCall(MoveWindowToDesktopNumberProc, UInt, hwnd, UInt, word_array[1] - 1)
}
return
GetDesktopsNumber()
{
RegRead, cur, HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\SessionInfo\1\VirtualDesktops, CurrentVirtualDesktop
RegRead, alldesktops, HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VirtualDesktops, VirtualDesktopIDs
return floor(strlen(alldesktops) / strlen(cur))
}
EnumWindowsProc(hwnd, lParam)
{
WinGetTitle, title, ahk_id %hwnd%
if title {
desktopnum := GetHWNDDesktopNumber(hwnd)
if (desktopnum >= 0) {
numwins := numwins + 1
line = % desktopnum "@" title "`r`n"
file.Write(line)
}
}
return true
}
GetHWNDDesktopNumber(hwnd)
{
global numdesktops, IsWindowOnDesktopNumberProc
Loop, %numdesktops% {
ix := A_Index - 1
windowIsOnDesktop := DllCall(IsWindowOnDesktopNumberProc, UInt, hwnd, UInt, ix)
if (windowIsOnDesktop == 1)
return A_Index
}
return -1
}
Best Answer
There is no memory benefit to using virtual desktops, it's purely organizational.
Microsoft is simply implementing a feature that other operating systems have offered for decades. I suspect that some people will use it heavily but most will ignore it.
The one place I've found virtual desktops to be useful was in my Solaris development days almost 20 years ago when we were running Smalltalk.
Most Smalltalk development systems used several windows concurrently making task switching to non-development tasks annoying as you would be constantly replacing all your development windows afterwards.
If you spent most of your time in only a few windows then the feature is not going to benefit you much but if if you do lots of multi-tasking spread out over dozens of related windows it's a useful tool.