问题描述
这是我尚未找到解决方案的一般问题的具体示例。
我有一个程序(Android 虚拟设备管理器),它从内部启动 ‘sub-programs'(即模拟器或虚拟设备)(也可以从其他地方启动)。我希望将这些程序中的任何一个实例分组在同一个 Unity 图标下。
我创建了一个 .desktop
文件来尝试完成此操作,但不完全知道如何去做。桌面文件如下:
#!/usr/bin/env xdg-open
[Desktop Entry]
Version=1.0
Type=Application
Terminal=false
Name=Android Virtual Device
Icon=/home/ben/.icons/android.svg
Exec=/home/ben/usr/bin/android avd
StartupWMClass=Android Virtual Device Manager
据我了解,我需要设置 StartupWMClass
才能正确实现这一目标。我在相应的窗口上使用 xprop WM_CLASS
获得了两个类名(“Android 虚拟设备管理器”和 ’emulator64-arm’)。两者都单独工作(无论以何种方式启动,启动器图标都正确附加到程序),但我无法让它同时工作。
我假设我需要为 StartupWMClass
设置两个值,但无法正确执行(或知道它是否是有效操作)。我已经尝试过,冒号分隔如环境变量、逗号分隔、引号等,但我在 official documentation 中找不到任何提示。
有什么建议么?
编辑:
另一个更迂腐但可能更容易识别的例子是 Matlab
。我正在运行 2013a,最初显示的初始屏幕和程序具有完全不同的 WM_CLASS
值。这意味着,当我单击其中包含 StartupWMClass=com-mathworks-util-PostVMInit
的启动器时,启动屏幕会出现一个不同的(默认未知)Unity
图标,而其余的则出现在我的启动器下。
通过使用 xprop WMCLASS
并首先单击启动屏幕,然后使用活动的 Matlab
会话重复,我得到以下终端输出:
ben@ben-OptiPlex-9010:~$ xprop WM_CLASS
WM_CLASS(STRING) = "MATLAB", "MATLAB"
ben@ben-OptiPlex-9010:~$ xprop WM_CLASS
WM_CLASS(STRING) = "sun-awt-X11-XFramePeer", "com-mathworks-util-PostVMInit"
如果我可以指定以下内容:
StartupWMClass=com-mathworks-util-PostVMInit&&MATLAB
这将完美地工作(因为两者都单独工作)但我不知道语法,如果它甚至存在的话。我只知道到目前为止我所尝试的一切都没有奏效。
无论哪种方式,任何帮助或明确的答案都会很棒,因为我相信这是运行良好的桌面的一个非常基本的元素。
最佳方法
星际争霸 II 启动 throw playonlinux 对我来说也有同样的问题。首先有一个应用程序启动器:
-
(WM_CLASS(STRING) = "Blizzard Launcher.exe", "Wine")
然后是游戏本身: -
(WM_CLASS(STRING) = "SC2.exe", "Wine")
我猜想 wine 正在使用二进制可执行文件设置类。
我查看了 bamf 代码(bamf_matcher.c,insert_desktop_file_class_into_table() 方法):
-
有一张Map可以在桌面文件和一个且只有一个类之间建立关联,
-
使用 g_key_file_get_string() 读取键 StartupWMClass,其目的不是返回字符串列表,
-
g_key_file_get_string_list() 可以做到这一点,但 bamf 开发人员并没有将框架设计为能够将多个类关联到一个桌面文件。
在我的情况下,我通过创建 2 个具有相同键但 StartupWMClass 的桌面文件来作弊。这并不完美,因为在启动器中我仍然有 2 个 Uniy 图标,但重要的是我知道为什么 :-)。
次佳方法
我知道这个问题真的很老,但是在经历了同样的问题之后,我想我终于为此创建了一个解决方法,并决定与遇到此问题的任何人分享:
由于我们不能为单个 .desktop 文件设置多个 WMClass,为什么不将所有窗口设置为单个 WMClass?
我们可以这样做(显然,将 Window 1
、 Window 2
和 potatoes
替换为您的窗口名称和所需的 WMClass):
xprop -name "Window 1" -f WM_CLASS 8s -set WM_CLASS "potatoes"
xprop -name "Window 2" -f WM_CLASS 8s -set WM_CLASS "potatoes"
在 .desktop 文件中,我们可以这样做:StartupWMClass=potatoes
塔达姆!现在所有窗口都已分组。但是,嘿,每次程序打开时我们都要手动执行吗?当然不是。
我们可以创建一个 bash 脚本,它每半秒自动执行一次:
while true
do
xprop -name "Window 1" -f WM_CLASS 8s -set WM_CLASS "potatoes"
xprop -name "Window 2" -f WM_CLASS 8s -set WM_CLASS "potatoes"
sleep 0.5
done
最后,将我们创建的 .sh 设置为在每次操作系统启动时运行:
希望我的回答对浏览这个问题的人有所帮助。