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