Menu

#32 display.send_event works, window.send_event doesn't

open
nobody
None
5
2012-12-07
2009-06-18
No

I was using python-xlib-0.14 to send keypresses to another window. When I used window.send_event to send keypresses, the keypresses silently disappeared (even when the onerror handler was provided). Then I used display.send_event, the keypresses were correctly received by the application.

Probably need to change window.send_event to specify the window (self), not the window.id (self.id). That's the only difference I could see between the two methods.

Discussion

  • Peter Liljenberg

    In that context, self.id is identical to self, just a bit of an optimization, so that's not the cause.

    Did you pass the same window object as first argument to display.send_event()? Sending input events directly to windows with send_event() is quite complicated (at least I have never tried to understand the propagation etc) while PointerWindow and InputFocus is a bit more straight-forward. Did you also remember to sync the connection through display.sync()? If not in a small test program the requests might never be sent to the X server.

    As an alternative, you could look at the XTEST extension which allows you to simulate input events much more simply (although not directing them at a specific window, rather obeying the normal focus rules).

     
  • Nobody/Anonymous

    This may be a bug in my code, but I'm not sure. Probably what I'm doing with display is non-standard...

    Here's some more details of what I'm doing:
    1. I have one function that grabs the pointer and then has the user select a window. I take the click event and use it to find the window (event.child). I save this event.
    The display object is local to this function so it falls out of scope.
    2. I have another function that sends events. Since the display object from the other function is not accessible, I use display.Display() again to get a display, then build an event and send it.

    If I change my code to use a global display object instead of letting the first display go out of scope, both methods work fine.

    def grabWindow:
    global event
    d = display.Display()
    cf = d.open_font('cursor')
    curse = cf.create_glyph_cursor(cf,Xcursorfont.based_arrow_up,Xcursorfont.based_arrow_up,(0,0,0),(1,1,1))
    d.screen().root.grab_pointer(False, X.ButtonPressMask | X.ButtonReleaseMask, X.GrabModeSync, X.GrabModeAsync, 0, curse, X.CurrentTime)
    cf.close()
    while (True):
    d.allow_events(X.SyncPointer,X.CurrentTime)
    event = d.next_event()
    if (event.type == X.ButtonPress):
    break
    d.ungrab_pointer(X.CurrentTime)
    d.flush()

    def SendEvent:
    global event
    d = display.Display()
    sevent = protocol.event.KeyPress(state = 0,
    time = X.CurrentTime+1,
    detail = d.keysym_to_keycode(XK.string_to_keysym(string)),
    sequence_number = 0,
    root = X.NONE,
    window = event.child,
    child = X.NONE,
    root_x = 1,
    root_y = 1,
    event_x = 1,
    event_y = 1,
    same_screen = True)
    event.child.send_event(sevent)

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.