[pygtk] Sending a message to the window manager (switch to desktop # X)

Osmo Maatta osmoma at gmail.com
Wed Feb 10 18:56:01 WST 2010


Hello,

I have code that sends a message to the window manager to switch to a 
given desktop number.
I try converted this code from C to GDK on Ubuntu Linux.

# The code is this.
import gtk.gdk
import struct

# Switch to desktop number X

gdk_root = gtk.gdk.get_default_root_window()       
gdk_disp = gtk.gdk.display_get_default()
gdk_event = gtk.gdk.Event(gtk.gdk.CLIENT_EVENT)

atom_property = gtk.gdk.atom_intern("_NET_CURRENT_DESKTOP", False)
# atom_property = gtk.gdk.atom_intern("_NET_DESKTOP_VIEWPORT", False)

# event_send_client_message_for_display

gdk_event.window = gdk_root
gdk_event.send_event = True
gdk_event.message_type = atom_property
gdk_event.data_format = 32
# Data is: desktop number (0 based), time, 0, 0, 0
gdk_event.data = struct.pack("LLLLL", 1, gtk.get_current_event_time(), 
0, 0, 0)

print"struct.calcsize(fmt)=", struct.calcsize("L")
# print gdk_event.data

mask = gtk.gdk.STRUCTURE_MASK | gtk.gdk.SUBSTRUCTURE_MASK
ret = gtk.gdk.event_send_client_message_for_display(gdk_disp, gdk_event, 
mask)
#ret = gdk_disp.put_event(gdk_event)
#ret = gdk_event.put()
print "ret=", ret    

gdk_disp.sync()
gdk_disp.flush()

# ------------------------------------------

But the code doe not work. It does nothing.
It should switch to desktop number 1 (the second Metacity desktop).

This is the original C/Xlib code that works very well.
http://code.google.com/p/gscreendump/source/browse/trunk/src/sd_xutils.c

Function:
void metacity_set_active_desktop(guint desktop_num)
{
    /* Switch to/set active desktop.
       The desktop_num is zero-based: 0, 1, 2...
    */

    /* Metacity or other standards respecting window manager */
    if (desktop_num+1 > get_number_of_desktops()) return;

    Display *display = GDK_DISPLAY();
    Window root_win = GDK_WINDOW_XWINDOW(gdk_get_default_root_window());

    Atom atom_net_current_desktop = XInternAtom(display, 
"_NET_CURRENT_DESKTOP", False);

    XEvent xevent;
    xevent.type   = ClientMessage;
    xevent.xclient.type = ClientMessage;
    xevent.xclient.display  = display;
    xevent.xclient.window = root_win;
    xevent.xclient.message_type = atom_net_current_desktop;
    xevent.xclient.format  = 32;
    xevent.xclient.data.l[0] = desktop_num;
    xevent.xclient.data.l[1] = CurrentTime;
    xevent.xclient.data.l[2] = 0;
    xevent.xclient.data.l[3] = 0;
    xevent.xclient.data.l[4] = 0;
    XSendEvent(display, root_win, False, SubstructureNotifyMask | 
SubstructureRedirectMask, &xevent);

    XFlush(display);
}

---------------------
Notice:  The atom "_NET_CURRENT_DESKTOP" works only with flat Metacity 
or equivalent window manager.
Compiz uses "_NET_DESKTOP_VIEWPORT" atom. And the data values are not 
desktop numbers, but viewport widths.
This is explained in the compiz_set_active_viewport(guint viewport_num) 
function in the above C code link.

You should absolutely switch to Metacity (or equivalent GNOME/KDE) 
window manager before testing this Python code. It will not work with 
Compiz WM. Type
$ metacity --replace
---------------------

I also send this question to [Python-xlib-users],  xlib version of the code
http://sourceforge.net/mailarchive/message.php?msg_name=4B7280E5.60300%40gmail.com

Thanks in advance.

Kindly Moma Antero.
Oslo, Norway




-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.daa.com.au/pipermail/pygtk/attachments/20100210/6990ded2/attachment.htm 


More information about the pygtk mailing list