Есть ли в xlib активное событие окна?

Я пытаюсь написать программу, которая отслеживает изменение активного окна с помощью Xlib. У меня проблемы с поиском лучшего способа сделать это. Это мои идеи на данный момент:

  • Каждую секунду используйте _NET_ACTIVE_WINDOW, чтобы получить активное окно, и, если оно изменилось, запустите соответствующий код для события.
  • Получите список всех окон и прослушайте их фокус в событии. Однако мне нужно было бы выяснить, как поддерживать актуальный список открытых окон.

Их проще / лучше? Я новичок в программировании с помощью Xlib.


person Jim    schedule 10.03.2011    source источник
comment
Прослушивание всех событий фокуса плюс регистрация всех обработчиков для всех окон кажутся чрезвычайно дорогими. Интересно, на самом деле прослушивание PointerMove в целом, а затем вызов XGetInputFocus() из обработчика событий, чтобы узнать, у кого он есть при перемещении, будет ли меньше накладных расходов. Насколько это должно быть в реальном времени? Если ответ на этот вопрос — секунда в порядке, то метод опроса кажется лучшим.   -  person FrankH.    schedule 10.03.2011
comment
Это не обязательно должно быть в реальном времени, через пару секунд будет нормально. Попробую свой первый способ. Спасибо ФранкХ.   -  person Jim    schedule 11.03.2011


Ответы (3)


Вот реализация Python того, что предложил @alanc.

import Xlib
import Xlib.display

disp = Xlib.display.Display()
root = disp.screen().root

NET_ACTIVE_WINDOW = disp.intern_atom('_NET_ACTIVE_WINDOW')
NET_WM_NAME = disp.intern_atom('_NET_WM_NAME')

last_seen = {'xid': None}
def get_active_window():
    window_id = root.get_full_property(NET_ACTIVE_WINDOW,
                                       Xlib.X.AnyPropertyType).value[0]

    focus_changed = (window_id != last_seen['xid'])
    last_seen['xid'] = window_id

    return window_id, focus_changed

def get_window_name(window_id):
    try:
        window_obj = disp.create_resource_object('window', window_id)
        window_name = window_obj.get_full_property(NET_WM_NAME, 0).value
    except Xlib.error.XError:
        window_name = None

    return window_name


if __name__ == '__main__':
    root.change_attributes(event_mask=Xlib.X.PropertyChangeMask)
    while True:
        win, changed = get_active_window()
        if changed:
            print(get_window_name(win))

        while True:
            event = disp.next_event()
            if (event.type == Xlib.X.PropertyNotify and
                    event.atom == NET_ACTIVE_WINDOW):
                break

Версия с более полными комментариями, которую я написал в качестве примера для кого-то, находится в этой сути.

person ssokolow    schedule 02.01.2017

Разве вы не можете просто выбрать PropertyChange в корневом окне, чтобы получать отправленные события PropertyNotify при обновлении любого свойства, а затем проверить каждое событие, чтобы увидеть, было ли оно для _NET_ACTIVE_WINDOW?

person alanc    schedule 16.06.2011

Я также искал «активный захват событий изменения окон». То, что я использую в настоящее время (и может быть полезно для вас), представляет собой комбинацию xdotool и xwininfo.

xwininfo -id "$(xdotool getactivewindow)"
person Grzegorz Wierzowiecki    schedule 16.06.2011
comment
это получает информацию об активном окне, но как это помогает в регистрации обработчика событий? - person phil294; 20.09.2020