2012-11-19 72 views
3

我想为我用Python编写的Gtk应用程序在屏幕上保留一些空间。我已经写了这个功能:无法更改_NET_WM_STRUT_PARTIAL属性

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: Here是我的xprop输出。我的WM是Compiz。

+0

你可以在调用之前和之后打印'xprop -id [xid here]'吗?你使用的是什么窗口管理器? –

回答

0

更改为使用ChangePropertyChecked(),然后检查结果给出BadLength异常。

我觉得这里的错误是,ChangeProperty()参数data_lenformat给出的,而不是字节数大小的元素的个数,在属性数据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() 
+0

请注意,对InternAtom使用only_if_exists = FALSE可能是一个好主意,因此如果此客户端在WM(或任何其他实例为“_NET_WM_STRUT_PARTIAL”的实例)客户端启动, – jturney

2

我已上传gist演示如何指定什么可能是一个任务栏跨越当前显示器的顶部的支柱。这可能有助于解释这一点。

我的要旨,其要旨在于以下:

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坐标,将顶端设置为相同的值加上监视器的宽度。最终的结果是该空间仅在当前监视器上保留。

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