gnome - Gnome 在启动桌面应用程序时究竟做了什么?
问题描述
我正在使用 Zorin OS,但我相信同样的事情适用于所有基于 Ubuntu 的发行版。
通过概览屏幕上的搜索启动应用程序时,Gnome 具有以下行为:
- 如果应用程序尚未运行,则启动它
- 如果应用程序已经在运行,则将其当前窗口置于前台
它究竟是如何做“将窗口带到前台”部分的?
例如,从(通过 安装)检查 Google Chrome 的.desktop
文件,我看到命令是,它总是创建一个新窗口。因此,当应用程序已经运行时,Gnome 显然在做其他事情。/usr/share/applications
.deb
Exec
/usr/bin/google-chrome-stable %U
我正在尝试为我最常用的每个应用程序实现一个全局快捷方式,并且我想要完全相同的行为,“如果已经运行,则打开或将其置于前台”。
我已经使用 编写了一个脚本wmctrl
,但是该解决方案似乎不太可靠也不优雅,因为我使用 grep 来查找当前应用程序的窗口。另外,如果我没记错的话,它不适用于wayland。
如果我能以某种方式触发 Gnome,那将是一个更好的解决方案。
解决方案
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();"
推荐阅读
- batch-file - 批处理:想按ping时间对网址进行排序并写入文件
- python - 基于k个最大特征值的krylov分解重排
- vb.net - 如果选定的树视图节点是父节点,有没有办法隐藏/取消启用组框?
- python - 使用 Python 使用 smtplib 库发送电子邮件
- java - 将 id 与实体一起使用的最佳方法是什么
- python - 尝试在 powershell 上安装 tensorflow-gpu python-package 时为什么权限被拒绝?
- python - 为什么这两个 2d 列表的初始化在 python 中不同
- vb.net - 如何从 2 个不同的来源(文件夹/目录)填充列表框?
- ajax - Laravel 使用参数发出 AJAX GET 请求的最佳方法
- webpack - 如何从 wasm rust 中正确导入 js 脚本