X11 - как поднять окно другого приложения с помощью Python

Я хотел бы иметь возможность поднять окно другого приложения с помощью Python.

Я видел это, и я думаю, что мог бы попробовать:

X11: поднять существующее окно с помощью командной строки?

однако я бы предпочел сделать это на Python, если это вообще возможно.

3 ответов


чтобы активировать другое окно, правильная вещь на уровне протокола Xlib-отправить сообщение _NET_ACTIVE_WINDOW, как описано в спецификации EWMH http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html

Это может быть сделано с python-xlib (предположительно) или с gdk_window_focus () на иностранном GdkWindow с использованием GDK через pygtk

_NET_ACTIVE_WINDOW превосходит XRaiseWindow () и был во всех важных WMs в течение многих лет.

вы должны избегать XSetInputFocus (), который вызовет проблемы (особенно, если вы получите метку времени неправильно). Проблема в том, что WM не может перехватить SetInputFocus (), поэтому он вызывает странные условия гонки и несоответствия пользовательского интерфейса.

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

существует библиотека под названием libwnck, которая позволит вам активировать windows (среди прочего) , но, к сожалению он добавляет довольно много накладных расходов, потому что он всегда отслеживает все открытые окна из любого приложения, даже если вам это не нужно. Однако, если вы хотите отслеживать windows из других приложений в любом случае, тогда libwnck имеет функцию для активации тех окон, которые делают правильную вещь и были бы хорошим выбором.

строго правильный подход-проверить поддержку EWMH _NET_ACTIVE_WINDOW (документы EWMH, как это сделать) и вернуться к XRaiseWindow, если WM не имеет _NET_ACTIVE_WINDOW. Однако, поскольку любой WM, который активно работал в течение последних многих лет, имеет EWMH, многие люди ленивы о резервном варианте для устаревших WMs.


вы можете посмотреть на пакет python ewmh. документация содержит примеры, но вот как вы можете достичь того, чего вы хотите:

from ewmh import EWMH
import random
ewmh = EWMH()

# get every displayed windows
wins = ewmh.getClientList()

# let's active one window randomly
ewmh.setActiveWindow(random.choice(wins))

# flush requests - that's actually do the real job
ewmh.display.flush()

вам нужно использовать питон-библиотеки Xlib и звонок .circulate(Xlib.X.RaiseLowest) на объекте окна (который может быть идентифицирован многими, многими различными способами-не могу догадаться, какой из них подходит для вас из нулевого количества информации об этом в вашем Q;-). Для отличного примера использования python-xlib, проверьте tinywm window manager -- После версии C автор дает версию Python, которая занимает около 30 непустых строк без комментариев (для полезной, если крошечная,окно менеджер!--8-->...!-).