让程序(特别是 chrome)在同一个虚拟桌面上打开

让程序(特别是 chrome)在同一个虚拟桌面上打开

Windows 有虚拟桌面,这很棒。我使用单独的桌面来处理不同的工作。但是如果我关闭某个程序(或重新启动),那么当我再次打开该程序时,该程序就会出现在我当前所在的桌面上。所以我必须手动将程序移回原位。

我猜对于 chrome 来说情况会更复杂,因为它是同一个程序,但窗口不同。如果窗口在关闭前仍停留在桌面上就好了。


与这些问题类似,不同之处在于我的问题要求记住窗口的位置,而不是明确设置它。

编辑(2022):现在所有这些解决方法似乎都没有必要。Chrome 现在将在桌面上打开关闭 Chrome 时的窗口。

答案1

可以通过以下方式完成自动热键脚本,它接受两个快捷键:

  • F11:将所有当前窗口的标题及其虚拟桌面编号写入FILENAME 脚本开头的参数中指定的文本文件中。
  • F12:读取文本文件并将根据标题找到的所有窗口移动到指定的虚拟桌面。

将以下文本复制到文件中.ahk,可能更改“FILENAME”、“F11”和“F12”。双击该文件以开始执行。它将在托盘栏中创建一个绿色的“H”图标,您可以右键单击并选择Exit停止。如果您始终希望执行此脚本,请将其复制到用户启动文件夹中 C:\Users\<user name>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup

此脚本需要从Github项目下载 Windows 桌面切换器 DLL 虚拟桌面访问器 并将其存储在与 AutoHotKey 脚本相同的文件夹中。它可能不适用于 1809 以下的 Windows 10 版本。

脚本本身如下所示,仅针对一台显示器进行编程。它不会创建虚拟桌面,因此应在运行之前创建它们。它对我来说很有效,但应该进行测试。由于它使用了未记录的功能,它可能会在将来的某个时候停止工作。

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
}

答案2

我的解决方案与@harrymc 基本相同,但有以下改进:

  • 适用于最新的 Windows 10(撰写本文时为 v2004)
  • 在后台保存浏览器窗口分配(每 5 分钟一次)
  • 使用 URL 来(更可靠地)识别浏览器窗口
  • 与“The Great Suspender”兼容
  • 备份支持

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

如果您需要 .exe 文件,请给我发私信。

答案3

我尝试了 harrymc 的解决方案,它在 Win10 64 位 v1903 上运行良好。该解决方案允许记录在不同虚拟桌面中运行的多个 Chrome 窗口(Fn+F11)。如果重启后所有 Chrome 窗口都出现在同一个虚拟桌面中,则使用(Fn+F12)将每个 Chrome 窗口发送到录制的虚拟桌面。

我尝试在 10 个虚拟桌面上分布 50 个 Chrome 窗口。生成文件需要 2-3 秒。

@harrymc:非常感谢!出于某种原因,我需要在笔记本电脑上按 Fn+F11 或 Fn+F12。F11 和 F12 键本身无法触发 AutoHotKey 脚本的功能。

答案4

据说从 chrome 88 版开始就已修复此问题,因此此时使用测试版是一种解决方案。或者您可以直接等待 2021 年 1 月 19 日发布。

这个问题在https://bugs.chromium.org/p/chromium/issues/detail?id=1065557 之前已在 Unix 和 X11 中报告过此问题并标记为已修复,但在我的计算机上它也不能与 Ubuntu 和 Google Chrome 87 一起使用。88 似乎已通过简短的测试在我的 Ubuntu 上修复了此问题。

相关内容