查找所有正在运行的 GUI 应用程序

查找所有正在运行的 GUI 应用程序

有一些与此类似的老问题;但是,我还没有找到一种方法来列出并选择性地关闭应用程序,最小化到系统托盘

在 Windows 中会话注销期间,Windows 会优雅地要求所有正在运行的 GUI 应用程序优雅地终止,并且只有当所有应用程序正常终止并确认此请求时,Windows 才会继续注销过程。

相反,在 Ubuntu 中,GNOME 不会要求所有应用程序正常终止,而只是kill在注销时退出。可能有些情况下,您只是没有注意到打开了带有未保存数据的编辑器,在这种情况下,您可能会丢失所有更新。或者可能有一些其他 GUI 应用程序需要正常关闭或必须继续运行,直到某些操作完成。

为此,我创建了一个脚本来找出所有打开的 GUI 窗口,然后“优雅地”逐个关闭它们。这个脚本的关键是wmctrl -lp列出应用程序并向wmctrl -ic <win_id>窗口 ID 已知的应用程序发送关闭消息的命令。但是,wmctrl -lp无法列出正在运行的任何应用程序最小化到系统托盘因此目前没有窗口(和窗口 ID)。我使用的一些可以最小化到系统托盘的示例应用程序是:Viber(.deb 软件包),电报(也是 .deb 包)或者一些葡萄酒(Windows)应用程序。请注意,我使用的是 snap 版本的火狐wmctrl成功检测到它的窗口 id,尽管 Firefox 的父级似乎是systemd

我目前正在使用 Xorg,并且更愿意继续使用 Xorg。但是,我也测试过 Wayland,结果更糟:Waylandwmctrl -lp无法列出 Xorg 中可轻松检测到的大多数“正常”应用程序。

注意:我测试过,发现最小化到托盘的应用程序会丢失其窗口 ID。恢复时(通过在系统托盘上的图标上用鼠标交互),它将获得一个新的窗口 ID。

我如何才能获得所有最小化到托盘应用程序的列表并恢复它们的窗口,以便我可以对它们进行操作wmctrl

答案1

以下脚本guir在手册列表的帮助下运行manlist,其中包含未显示的应用程序wmctrl -lp

#!/bin/bash

manlist=\
'Viber
Telegram
onboard
skype
xeyes'

mizer=$(wmctrl -lp|grep -v '@!0,0;BDHF'|tr -s ' ' '\t'|cut -f3|grep -v '^0$')

guip="$mizer
$manlist"

runners=$(ps -e |grep "^$guip$"|sed -e 's/^ *//' -e 's/ .*$//')
guir="$(ps $runners)"
echo "$guir"
if [  $(echo "$runners"|wc -l) -gt 1 ]
then
 echo "-------------------------------------------------------------------"
 echo "Please close some programs gracefully before logout/reboot/shutdown"
 exit 1
fi

测试运行:

$ ./guir 
    PID TTY      STAT   TIME COMMAND
   3006 ?        Ssl    0:59 /usr/libexec/gnome-terminal-server
   3042 pts/0    S+     0:58 xeyes -geometry +1775-0
   3043 pts/0    S+     0:58 xeyes -geometry +800+0
   3954 pts/0    Sl    10:02 /snap/firefox/2605/usr/lib/firefox/firefox
   5790 ?        Sl     3:39 /usr/lib/thunderbird/thunderbird
   6707 pts/0    Sl     1:18 geany
   9929 ?        Sl     0:07 /usr/bin/python3 /usr/bin/onboard
-------------------------------------------------------------------
Please close some programs gracefully before logout/reboot/shutdown
  • 如果您想使用此方法,您可能会修改这个脚本,例如向中添加一些程序manlist

  • 假设脚本在终端窗口中运行,则允许一个程序运行而无需关闭其他程序。您可能也想更改这一点。

  • 您可以关闭xeyes而不保存任何内容,它manlist仅作为演示,因为wmctrl没有找到它的进程号(列表0),并且可能还有其他程序受到类似影响。

  • 最后,我认为您打算在注销/重启/关机过程中自动使用脚本/程序,因此我修改了程序应正常关闭时的退出状态。

答案2

由于所有 GUI 进程都是窗口管理器的子进程(孙进程,...),因此您可以使用pgrep来查找窗口管理器的 PID,pspstree列出该 PID 的子进程。阅读man pgrep ps pstree

相关内容