views:

1249

answers:

1

Hello, At the moment I'm trying to use Python to detect when the left mouse button is being held and then start to rapidly send this event instead of only once. What I basically want to do is that when the left mouse button is held it clicks and clicks again until you let it go. But I'm a bit puzzled with the whole Xlib, I think it's very confusing actually. Any help on how to do this would be really awesome. That's what I've got so far:

#!/usr/bin/env python

import Xlib
import Xlib.display

def main():
    display = Xlib.display.Display()
    root = display.screen().root
    while True:
        event = root.display.next_event()
        print event

if __name__ == "__main__":
    main()

But there is unfortunately no output in the console. After a quick search on the internet I found the following:

root.change_attributes(event_mask=Xlib.X.KeyPressMask)
root.grab_key(keycode, Xlib.X.AnyModifier, 1, Xlib.X.GrabModeAsync,
              Xlib.X.GrabModeAsync)

This is seemingly import to catch a special event with the given keycode. But firstly what keycode does the left-mouse click have, if any at all? And secondly how can I detect when it is being held down and then start sending the mouseclick event rapidly. I would be really grateful for help. (Maybe a way to stop this script with a hotkey would be cool aswell...)

+2  A: 

Actually you want Xlib.X.ButtonPressMask | Xlib.X.ButtonReleaseMask, to get events for button presses and releases (different from key presses and releases). The events are ButtonPress and ButtonRelease, and the detail instance variable gives you the button number. From when you get the press event, to when you get the release event, you know the button is being held down. Of course you can also receive key events and do something else (e.g. exit your script) when a certain key is pressed.

Edit: this version works fine for me, for example...:

import Xlib
import Xlib.display

def main():
    display = Xlib.display.Display(':0')
    root = display.screen().root
    root.change_attributes(event_mask=
        Xlib.X.ButtonPressMask | Xlib.X.ButtonReleaseMask)

    while True:
        event = root.display.next_event()
        print event

if __name__ == "__main__":
    main()
Alex Martelli
So how would I go about specifying "root.grab_key"?
cryzed
Just tried several combinations, nothing worked :(. Could you do me a favor and quickly write the script or atleast the base? Elsewise I know it would take for forever until I finally get it running although it isn't all that complicated. I would be really grateful.
cryzed
Alex Martelli
I use this code, and got:<class 'Xlib.error.BadAccess'>: code = 10, resource_id = 256, sequence_number = 9, major_opcode = 2, minor_opcode = 0what is wrong?
linjunhalida
@linjun, unfortunately X11's docs aren't the best, so (besides the fact that there's an attempt to access a private resource) it's hard to know what's going on -- esp. when you don't provide the full traceback, without which debugging any Python issue is a nigthmare! I know it won't fit in a comment -- you need to open a new question to copy and paste the traceback if you want any chance to get help. (As long as you're at it, giving us complete, precise details on your platform, Python version, etc, is, _as usual_, an excellent idea too).
Alex Martelli