如何获取Unity Launcher中正在运行的GUI应用程序的列表?


8

我需要一个列表,其中仅包含那些在Dash中当前正在打开/运行的应用程序,这些应用程序的图标左侧带有白色小箭头。

有什么办法吗?

带有箭头的破折号


1
什么是上下文,您将如何使用列表(以什么形式)?
Jacob Vlijm '16

打开的窗口清单?可以轻松完成,但是正如Jacob所说,我们可能需要了解更多信息
Sergiy Kolodyazhnyy

相关,并且很可能重复:askubuntu.com/q/483554/295286
Sergiy Kolodyazhnyy

Answers:


4

与办法做到这一点qdbusorg.ayatana.bamf接口。

.desktop文件列出的打开的应用程序列表:

$ qdbus org.ayatana.bamf /org/ayatana/bamf/matcher \                           
> org.ayatana.bamf.matcher.RunningApplicationsDesktopFiles
/usr/share/applications/compiz.desktop
/usr/share/applications/firefox.desktop
/usr/share/applications/x-terminal-emulator.desktop

使用org.ayatana.bamf.matcher.RunningApplicationsorg.ayatana.bamf.view.Name方法

$ qdbus org.ayatana.bamf /org/ayatana/bamf/matcher  \                          
> org.ayatana.bamf.matcher.RunningApplications | \                             
> xargs -I {} qdbus org.ayatana.bamf {} org.ayatana.bamf.view.Name
Firefox Web Browser
MY CUSTOM TERMINAL
Compiz

现在令人印象深刻!
Jacob Vlijm '16

@JacobVlijm对此有更多的变化,但是它们有特定的用途,需要更多的代码和解析。我只是在这里粘贴了最简单的标签。但谢谢你:)
Sergiy Kolodyazhnyy 2016年

5

有趣的问题。

与往常一样,有多种方法可以获取这些应用程序的列表,每种方法都有其特定的优点和缺点。

使用窗口列表获取启动器中表示的进程列表

由于只有带有(映射)窗口的应用程序才会显示在启动器中,因此请使用:

wmctrl -lp 

wmctrl默认情况下未安装),我们可以获得打开的窗口的列表以及该窗口所属的进程ID。输出格式为:

0x05204641  0 12618  jacob-System-Product-Name verhaal (~) - gedit

对我们而言,最重要的信息在哪里:

  • 第一个字符串(0x05204641); 这是窗口-id
  • 第三个字符串(12618); 这是窗口所属的进程ID(pid),并且
  • 最后一节(verhaal (~) - gedit); 这是窗口名称

有了pid后,我们可以通过以下命令查找相应的进程名称

ps -p <pid> -o comm=

我们可以编写上述步骤的脚本,并列出现有窗口的输出,如下所示(使用python):

{'gnome-terminal', 'nautilus', 'gedit', 'GuitarPro.exe', 'firefox', 'thunderbird', 'soffice.bin'}

并发症

这似乎很简单。但是,一如既往,现实有点复杂。我们需要注意一些例外情况和复杂情况:

  1. 一些窗口将属于pid 0,这将在尝试获取其属性时引发错误。的视窗IdlepythonIDE),或者tkinter是这样的窗口。
  2. 某些窗口不是“真实”窗口,也不是诸如临时窗口(从其他窗口调用并属于其他窗口的窗口)之类的窗口,例如台式机本身。这些窗口在的输出中被列为窗口wmctrl,但在Dash中不会单独出现。
  3. 在某些情况下,应用程序的名称与进程名称完全不同,例如,LibreOffice在所有模块的进程名称均为的情况下soffice.bin。同时,运行命令 soffice.bin将不起作用。如果你需要识别模块CalcWriter等)分开,你需要得到更多的信息,从该窗口的名称,例如。
  4. 另一个示例是的名称gnome-terminal,显示在流程列表中,如的输出所示ps -e ww。在14.04中,gnome-terminal显示为gnome-terminal,但是在15.04 / 15.10中显示:/usr/lib/gnome-terminal/gnome-terminal-server

我们至少需要解决的问题

要解决以上最重要的问题,您需要:

  • 添加一个检查窗口是否为“真实”或“正常”窗口,并使用

    xprop -id <window_id>
    

    如果输出包含以下行:

    _NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_NORMAL
    

    该窗口在Unity Launcher的意义上是有效的窗口

  • 要修复gnome-terminalin 的流程名称15.x(假设您希望显示的流程名称为gnome-terminal),我们需要添加一个例外,gnome-terminal如果流程名称显示为,则将其重命名为 /usr/lib/gnome-terminal/gnome-terminal-server

脚本

#!/usr/bin/env python3
import subprocess
import sys

try:
    listed = sys.argv[1]
except IndexError:
    listed = []

get = lambda cmd: subprocess.check_output(cmd).decode("utf-8").strip()

def check_wtype(w_id):
    # check the type of window; only list "NORMAL" windows
    return "_NET_WM_WINDOW_TYPE_NORMAL" in get(["xprop", "-id", w_id])

def get_process(w_id):
    # get the name of the process, owning the window
    proc = get(["ps", "-p", w_id, "-o", "comm="])
    proc = "gnome-terminal" if "gnome-terminal" in proc else proc
    return proc

wlist = [l.split() for l in subprocess.check_output(["wmctrl", "-lp"])\
         .decode("utf-8").splitlines()]

validprocs = set([get_process(w[2]) for w in wlist if check_wtype(w[0]) == True])

if listed == "-list":
    for p in validprocs:
        print(p)
else:
    print(validprocs)

如何使用

  1. 该脚本需要wmctrl

    sudo apt-get install wmctrl
    
  2. 将上面的脚本复制到一个空文件中,另存为 get_running.py

  3. 通过以下命令运行它:

    python3 /path/to/get_running.py
    

    它将输出如下:

    {'gnome-terminal', 'nautilus', 'gedit', 'GuitarPro.exe', 'firefox', 'thunderbird', 'soffice.bin'}
    

    或者,使用参数运行-list

    thunderbird
    nautilus
    gnome-terminal
    firefox
    gedit
    GuitarPro.exe
    soffice.bin
    

笔记

从您的问题来看,尚不完全清楚找到列表的目的是什么。如果需要使用应用程序的名称(如界面中显示的名称)(“可读”名称),则可以采用完全不同的方法:

  • 所有全局安装的应用程序都在中有一个.desktop文件/usr/share/applications。在大多数情况下,我们可以从文件中得出应用程序的进程名称接口名称.desktop。使用此信息,我们可以相对容易地创建一个正在运行的GUI应用程序列表,以它们的“可读”名称表示。

此外,在这种情况下,然而,现实中也比较复杂那么理论,为解释在这里

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.