3

我想在屏幕上为我用 Python 编写的 Gtk 应用程序保留一些空间。我写了这个函数:

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。

4

2 回答 2

2

我已经上传了一个要点,它演示了如何在当前监视器的顶部为可能是任务栏的东西指定一个支柱。它可能有助于解释其中的一些。

我的要点如下:

 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])

起初我发现 strut 参数令人困惑,所以这里有一个我希望更清楚的解释:

我们设置_NET_WM_STRUT了旧的机制,_NET_WM_STRUT_PARTIAL但是如果窗口管理器支持后者,则忽略前者。数组中的数字如下:

  • 0, 0, bar_size, 0是沿屏幕每个边缘保留的像素数,按左的顺序给出。此处,条形图的大小保留在屏幕顶部,而其他边缘则保持不变。
  • _NET_WM_STRUT_PARTIAL还提供另外四对,每对都是支柱的开始和结束位置(它们不需要占据整个边缘)。

在示例中,我们将 top start 设置为当前监视器的 x 坐标,并将 top-end 设置为相同的值加上该监视器的宽度。最终结果是仅在当前监视器上保留空间。

请注意,坐标是相对于屏幕指定的(即所有监视器一起)。

(有关完整上下文,请参阅参考要点)

于 2014-05-12T11:21:44.633 回答
0

更改为使用 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()
于 2013-02-20T15:42:54.263 回答