Question

I want to reserve some space on the screen for my Gtk application written in Python. 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. My WM is Compiz.

Était-ce utile?

La solution 2

Changing to using ChangePropertyChecked(), and then checking the result gives a BadLength exception.

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.

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

Autres conseils

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:

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

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. The net result is that space is reserved only on the current monitor.

Note that co-ordinates are specified relative to the screen (i.e. all monitors together).

(see the referenced gist for the full context)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top