首页 > 解决方案 > Gnome 在启动桌面应用程序时究竟做了什么?

问题描述

我正在使用 Zorin OS,但我相信同样的事情适用于所有基于 Ubuntu 的发行版。

通过概览屏幕上的搜索启动应用程序时,Gnome 具有以下行为:

它究竟是如何做“将窗口带到前台”部分的?

例如,从(通过 安装)检查 Google Chrome 的.desktop文件,我看到命令是,它总是创建一个新窗口。因此,当应用程序已经运行时,Gnome 显然在做其他事情。/usr/share/applications.debExec/usr/bin/google-chrome-stable %U

我正在尝试为我最常用的每个应用程序实现一个全局快捷方式,并且我想要完全相同的行为,“如果已经运行,则打开或将其置于前台”。

我已经使用 编写了一个脚本wmctrl,但是该解决方案似乎不太可靠也不优雅,因为我使用 grep 来查找当前应用程序的窗口。另外,如果我没记错的话,它不适用于wayland。

如果我能以某种方式触发 Gnome,那将是一个更好的解决方案。

标签: gnomexorgwayland

解决方案


GNOME Shell 的窗口管理器代码总是尝试将每个窗口与其 .desktop 文件相关联(基于 WM_NAME 和其他启发式方法)。例如,这就是它知道在顶部栏中显示什么应用程序图标和标题的方式,独立于实际窗口的标题。在内部,这是“shell-window-tracker”模块。

因此,当启动器想要启动一个应用程序时,它首先要求窗口管理器显示一个与同一个 .desktop 文件关联的窗口,并且只有在没有任何匹配的窗口时才执行该程序。

但请注意,同一个GNOME Shell 既是应用程序启动器,也是窗口管理器。它不会进行任何外部 API 调用来实现这一点——概述/启动器代码只是使用内部函数与窗口管理代码进行通信,因为它们都在同一个进程中运行。

要在外部实现相同的功能,您需要使用 Shell 的 D-Bus API,尽管它似乎没有用于启动特定应用程序的 API,因此您可能需要以org.gnome.Shell.Eval()这种方式使用和调用 Shell 内部的 GJS 函数。

未经测试:

busctl --user call org.gnome.Shell \
    /org/gnome/Shell org.gnome.Shell Eval \
    s "Shell.AppSystem.get_default().lookup_app('foo.desktop').activate();"

推荐阅读