Не удается изменить свойство _NET_WM_STRUT_PARTIAL
Я хочу зарезервировать место на экране для моего приложения Gtk, написанного на Python. Я написал эту функцию:
import xcb, xcb.xproto
import struct
def reserve_space(xid, data):
connection = xcb.connect()
atom_cookie = connection.core.InternAtom(True, len("_NET_WM_STRUT_PARTIAL"),
"_NET_WM_STRUT_PARTIAL")
type_cookie = connection.core.InternAtom(True, len("CARDINAL"), "CARDINAL")
atom = atom_cookie.reply().atom
atom_type = type_cookie.reply().atom
data_p = struct.pack("I I I I I I I I I I I I", *data)
strat_cookie = connection.core.ChangeProperty(xcb.xproto.PropMode.Replace, xid,
atom, xcb.xproto.Atom.CARDINAL, 32, len(data_p), data_p)
connection.flush()
Это звонок выглядит так:
utils.reserve_space(xid, [0, 60, 0, 0, 0, 0, 24, 767, 0, 0, 0, 0])
К сожалению, это не работает. Где ошибка в моем коде?
UPD: Вот мой вывод xprop. Мой WM это Compiz.
2 ответа
Переход к использованию ChangePropertyChecked(), а затем проверка результата дает исключение BadLength.
Я думаю, что ошибка в том, что ChangeProperty()
параметр data_len
количество элементов размера, заданного format
, а не количество байтов, в данных свойства data
,
Слегка измененный код, который работает для меня:
def reserve_space(xid, data):
connection = xcb.connect()
atom_cookie = connection.core.InternAtom(False, len("_NET_WM_STRUT_PARTIAL"),
"_NET_WM_STRUT_PARTIAL")
atom = atom_cookie.reply().atom
data_p = struct.pack("12I", *data)
strat_cookie = connection.core.ChangePropertyChecked(xcb.xproto.PropMode.Replace, xid,
atom, xcb.xproto.Atom.CARDINAL, 32, len(data_p)/4, data_p)
strat_cookie.check()
connection.flush()
Я загрузил суть, которая демонстрирует, как указать распорку в верхней части текущего монитора для того, что может быть панелью задач. Это может помочь объяснить некоторые из них.
Суть моей сущности ниже:
window = gtk.Window()
window.show_all()
topw = window.get_toplevel().window
topw.property_change("_NET_WM_STRUT","CARDINAL",32,gtk.gdk.PROP_MODE_REPLACE,
[0, 0, bar_size, 0])
topw.property_change("_NET_WM_STRUT_PARTIAL","CARDINAL",32,gtk.gdk.PROP_MODE_REPLACE,
[0, 0, bar_size, 0, 0, 0, 0, 0, x, x+width, 0, 0])
Сначала мне показалось, что аргументы сторновки сбивают с толку, поэтому вот объяснение, которое, я надеюсь, будет более ясным:
мы установили _NET_WM_STRUT
, старый механизм, а также _NET_WM_STRUT_PARTIAL
но оконные менеджеры игнорируют первое, если поддерживают второе. Числа в массиве следующие:
0, 0, bar_size, 0
количество пикселей, которые нужно зарезервировать вдоль каждого края экрана, в следующем порядке: слева, справа, сверху и снизу. Здесь размер полосы зарезервирован в верхней части экрана, а остальные края оставлены в покое._NET_WM_STRUT_PARTIAL
также поставляет еще четыре пары, каждая из которых является начальной и конечной позициями для стойки (им не нужно занимать весь край).
В этом примере мы устанавливаем верхнее начало для координаты x текущего монитора, а верхнее - для того же значения плюс ширина этого монитора. Конечным результатом является то, что место зарезервировано только на текущем мониторе.
Обратите внимание, что координаты указываются относительно экрана (т.е. все мониторы вместе).
(см. ссылочную суть для полного контекста)