Рисовать поверх экрана с помощью xlib

Я хочу нарисовать некоторые примитивы поверх всех окон на экране. Я нашел некоторый код на C и попытался перенести его, чтобы использовать xlib python:

from Xlib.display import Display
from Xlib import X
from Xlib import protocol

display = Display(':0')
root = display.screen().root
gc = root.create_gc()
root.fill_rectangle(gc, 100, 100, 500, 500)

Но на экране ничего не появляется (правда, корневое окно назначено: хватая клавиатуру после него работает). Как это сделать правильно?


person aplavin    schedule 07.01.2013    source источник
comment
Если вы не пишете оконный менеджер, писать корень X — действительно плохая идея. Кража фокуса ввода от всего остального — пример того, насколько грубым может быть приложение, которое это делает. Я бы искал модальный диалог в любом наборе инструментов GUI, который вы используете.   -  person msw    schedule 07.01.2013
comment
@msw: Я пишу не оконный менеджер, а другое низкоуровневое приложение, так что действительно нужно рисовать поверх всех окон.   -  person aplavin    schedule 07.01.2013


Ответы (1)


Вы можете рисовать в корневом окне - ваш код, вероятно, работает, но корневое окно может быть закрыто каким-либо окном рабочего стола (nautilus, рабочий стол kde и т. д.). Попробуйте запустить сеанс X без запущенных программ, и вы увидите обновления (для этого вы можете использовать Xephyr или Xnest)

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

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

Из спецификации составного протокола:

Версия 0.3 протокола добавляет окно Composite Overlay Window, которое предоставляет менеджерам композитинга поверхность, на которой можно рисовать без помех. Это окно всегда находится над обычными окнами и всегда ниже окна заставки. Это окно ввода-вывода, ширина и высота которого являются размерами экрана. Его визуал является корневым визуалом, а ширина его границы равна нулю. Попытки перенаправить его с помощью составного расширения игнорируются. Это окно не отображается в ответе на запрос QueryTree. Это также переопределяющее окно перенаправления. Последние две функции делают его невидимым для оконных менеджеров и других клиентов X11. Единственный способ получить доступ к XID этого окна — через запрос CompositeGetOverlayWindow. Первоначально окно композитного наложения не отображается.

CompositeGetOverlayWindow возвращает XID составного окна наложения. Если окно еще не отображено, оно отображается этим запросом. Когда все клиенты, вызвавшие этот запрос, прервали свои соединения X11, окно сбрасывается.

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

person Andrey Sidorov    schedule 11.01.2013
comment
К сожалению, документация по xlib ужасна, и хотя в ней реализовано составное расширение, руководства по его использованию нет. - person Benubird; 06.05.2015
comment
Рисование поверх окна наложения (т. е. использование cairo) требует запроса и освобождения наложения каждый раз, когда мы хотим что-то нарисовать. Но после рисования изображения поверх оверлея оно исчезнет через пару миллисекунд. Кажется, нам нужно какое-то уведомление (выставить событие?) для составного окна наложения, чтобы знать, когда нам разрешено рисовать в нем. - person Daniel; 20.02.2018