简体   繁体   English

无法更改_NET_WM_STRUT_PARTIAL属性

[英]Can't change _NET_WM_STRUT_PARTIAL property

I want to reserve some space on the screen for my Gtk application written in Python. 我想在屏幕上为我用Python编写的Gtk应用程序保留一些空间。 I've wrote this function: 我写过这个函数:

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

It's call looks like this: 这个电话看起来像这样:

utils.reserve_space(xid, [0, 60, 0, 0, 0, 0, 24, 767, 0, 0, 0, 0])

Unfortunately, it doesn't work. 不幸的是,它不起作用。 Where is an error in my code? 我的代码中的错误在哪里?

UPD: Here is my xprop output. UPD: 是我的xprop输出。 My WM is Compiz. 我的WM是Compiz。

I have uploaded a gist that demonstrates how to specify a strut across the top of the current monitor for what might be a task-bar. 我上传了一个要点 ,该要点演示了如何在当前监视器的顶部指定一个可能是任务栏的支柱。 It may help explain some of this. 它可能有助于解释其中一些。

The gist of my gist is below: 我要点的要点如下:

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

I found the strut arguments confusing at first, so here is an explanation that I hope is clearer: 我发现strut的论点起初很混乱,所以这里有一个解释,我希望更清楚:

we set _NET_WM_STRUT , the older mechanism as well as _NET_WM_STRUT_PARTIAL but window managers ignore the former if they support the latter. 我们设置_NET_WM_STRUT ,旧机制以及_NET_WM_STRUT_PARTIAL但窗口管理器如果支持后者则忽略前者。 The numbers in the array are as follows: 数组中的数字如下:

  • 0, 0, bar_size, 0 are the number of pixels to reserve along each edge of the screen given in the order left , right , top , bottom . 0, 0, bar_size, 0是按照的顺序给出的沿屏幕每个边缘保留的像素数。 Here the size of the bar is reserved at the top of the screen and the other edges are left alone. 这里,条形图的大小保留在屏幕顶部,其他边缘保持不变。
  • _NET_WM_STRUT_PARTIAL also supplies a further four pairs, each being a start and end position for the strut (they don't need to occupy the entire edge). _NET_WM_STRUT_PARTIAL还提供另外四对,每对都是支柱的起始位置和结束位置(它们不需要占据整个边缘)。

In the example, we set the top start to the current monitor's x co-ordinate and the top-end to the same value plus that monitor's width. 在该示例中,我们将顶部开始设置为当前监视器的x坐标,将顶端设置为相同的值加上监视器的宽度。 The net result is that space is reserved only on the current monitor. 最终结果是仅在当前监视器上保留空间。

Note that co-ordinates are specified relative to the screen (ie all monitors together). 请注意,坐标是相对于屏幕指定的(即所有监视器一起)。

(see the referenced gist for the full context) (有关完整上下文,请参阅引用的要点)

Changing to using ChangePropertyChecked(), and then checking the result gives a BadLength exception. 更改为使用ChangePropertyChecked(),然后检查结果会产生BadLength异常。

I think the bug here is that the ChangeProperty() parameter data_len is the number of elements of the size given by format , not the number of bytes, in the property data data . 我认为这里的错误是ChangeProperty()参数data_len是属性数据data format给出的大小的元素数,而不是字节数。

Slightly modified code which works for me: 稍微修改过的代码对我有用:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM