Make programs (specifically chrome) open on same virtual desktop

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
}

I tried harrymc's solution and it worked fine on a Win10 64-bits, v1903. The solution allows to record multiple Chrome windows running in different virtual desktops (Fn+F11). If all Chrome windows appear in the same virtual desktop after reboot, using (Fn+F12) sends each Chrome window to the recorded virtual desktop.

I tried with 50 Chrome windows distributed over 10 virtual desktops. It took 2-3 seconds to generate the file.

@harrymc: Thank you very much! For some reason I need to press Fn+F11 or Fn+F12 in my laptop. The F11 and F12 keys alone do not trigger the functions of the AutoHotKey script.


My solution is basically the same as @harrymc with following improvements:

  • Works on the latest Window 10 (v2004 as of this writing)
  • Saves the browser window assignments in the background (every 5 minutes)
  • Uses URL to (more reliably) identify browser windows
  • Compatible with "The Great Suspender"
  • Backup support

AHK script https://github.com/onefork/windows-desktop-switcher/releases

PM me if you need a .exe file instead.