Re: Programatically activate menu like a mouse click




Ok, so I have made a little progress on this, albeit in a one step
forward, two steps back kind-of way.

This code in my `keybinder_callback` half-works:

    import Xlib
    from Xlib import X
    from Xlib.display import Display
    from Xlib.ext.xtest import fake_input

    ....

    display = Display()
    mpos = display.screen().root.query_pointer()._data
    display.screen().root.warp_pointer(x,5)
    display.sync()
    fake_input(display,X.ButtonPress,1, X.CurrentTime, X.NONE, x, 5)
    display.sync()
    fake_input(display,X.ButtonRelease,1)
    display.screen().root.warp_pointer(mpos['root_x'],
                                       mpos['root_y'])


It partially activates the menu bar (the first item is highlighted but
the drop-down does not appear) and generates the following error message:

    Gdk-CRITICAL **: Window 0x1e7c660 has not been made visible in
    GdkSeatGrabPrepareFunc

After that, nothing works.

However, the exact same code in a stand-alone program executed in a
second terminal window works absolutely fine:

    #!/usr/bin/env python
    import Xlib
    from Xlib import X
    from Xlib.display import Display
    from Xlib.ext.xtest import fake_input

    display = Display()
    mpos = display.screen().root.query_pointer()._data
    display.screen().root.warp_pointer(1605,5)
    display.sync()
    fake_input(display,X.ButtonPress,1, X.CurrentTime, X.NONE, 1605, 5)
    display.sync()
    fake_input(display,X.ButtonRelease,1)
    display.screen().root.warp_pointer(mpos['root_x'], mpos['root_y'])
    display.sync()

So I tried this:

    import time

    ...

    def keybinder_callback(self, keystr, user_data):
        time.sleep(0.2)
        x = self.get_position().root_x+5
        display = Display()
        mpos = display.screen().root.query_pointer()._data
        display.screen().root.warp_pointer(x,5)
        display.sync()
        fake_input(display,X.ButtonPress,1, X.CurrentTime, X.NONE, x, 5)
        display.sync()
        fake_input(display,X.ButtonRelease,1)
        display.screen().root.warp_pointer(mpos['root_x'],
                                           mpos['root_y'])
        display.sync()

Guess what? It's nasty, but it works!

Once I discovered the sleep, I found that this also works (I tried this
before but it exhibited the same problem described above):

    def keybinder_callback(self, keystr, user_data):
      time.sleep(0.2)
      run("xdotool mousemove %d 10 click 1 mousemove restore" %
                (self.get_position().root_x+5) , shell=True)

Without the `sleep(0,2)`, I get the above critical error.

So there is some timing issue that I need to consider. Any ideas what
this is and how to cater for it without the `sleep` sledehammer ?



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]