Как получить список запущенных приложений с графическим интерфейсом в Unity Launcher?


8

Мне нужен список только с теми приложениями, которые в данный момент открыты / работают в Dash, с теми, которые имеют маленькую белую стрелку (и) в левой части значка.

Есть ли способ получить это?

тире со стрелками скриншот


1
Каков контекст и как бы вы хотели, чтобы список был доступен (в какой форме)?
— Джейкоб Влейм

Список открытых окон? Это легко сделать, но, как сказал Джейкоб, нам, вероятно, понадобится больше информации
— Сергей Колодяжный,

Связанный и, скорее всего, дубликат: askubuntu.com/q/483554/295286
— Сергей Колодяжный

Ответы:


4

Способ сделать это с qdbusи org.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.RunningApplicationsи org.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

Теперь это впечатляет!
— Джейкоб Влейм

@JacobVlijm Существует больше вариаций, но они имеют конкретное назначение и требуют больше кода и анализа. Я просто вставил самые простые здесь. Но спасибо :)
— Сергей Колодяжный

5

Интересный вопрос

Как всегда, есть разные способы получить список этих приложений, каждое из которых имеет свои преимущества и недостатки.

Получение списка процессов, представленных в Launcher, используя список окон

Поскольку в Launcher отображаются только приложения с (отображенным) окном, используя:

wmctrl -lp 

( wmctrlне устанавливается по умолчанию), мы можем получить список открытых окон и идентификатор процесса, к которому они принадлежат. Формат вывода:

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

где для нас самая важная информация находится в:

  • первая строка ( 0x05204641); это окно -id
  • третья строка ( 12618); это идентификатор процесса (pid), к которому принадлежит окно, и,
  • последний раздел ( verhaal (~) - gedit); это имя окна .

Получив pid, мы можем найти соответствующее имя процесса с помощью команды:

ps -p <pid> -o comm=

Мы можем написать сценарий, описанный выше, и перечислить вывод (ы) для существующих окон, используя (используя python):

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

осложнения

Это кажется простым. Однако, как всегда, реальность немного сложнее. Есть несколько исключений и осложнений, о которых нам нужно позаботиться:

  1. Некоторые окна будут принадлежать pid 0 , что приведет к ошибке при попытке получить их свойства. Окна Idle( pythonIDE) или tkinterесть такие окна.
  2. Некоторые окна не являются «реальными» или окнами, такими как переходные окна (окна, которые вызываются и принадлежат другим окнам) или, например, сам рабочий стол. Эти окна перечислены как окна в выходных данных wmctrl, но не отображаются отдельно в Dash.
  3. В некоторых случаях имя приложения сильно отличается от имени процесса, например, в случае, LibreOfficeкогда все модули имеют имя процесса soffice.bin. В то же время, выполнение команды soffice.bin не будет работать. В случае , если необходимо определить модули ( Calc, и Writerт.д.) отдельно, вы должны были бы получить дополнительную информацию, из окна названия , например.
  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-terminalв 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файла. Используя эту информацию, мы могли относительно легко создать список запущенных приложений с графическим интерфейсом, представленный их «читаемым» именем.

Однако и в этом случае реальность также более сложна, чем теория, как объясняется здесь .

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.