PyUserInput icon indicating copy to clipboard operation
PyUserInput copied to clipboard

dont catch emulated events

Open byaka opened this issue 10 years ago • 7 comments

my problem: i want to catch mouse (and keyboard) events, check conditions, and in one case return this event to system, in another case - return another event to system. for example i want to transform mouseWheelUp into keyPress(w), but other mouse events must work without changes.

from pymouse import *
mouse=PyMouse()
from pykeyboard import *
kbrd=PyKeyboard()

class hook(PyMouseEvent):
   def __init__(self):
      PyMouseEvent.__init__(self)

   def click(self, x, y, button, press):
      print 'MOUSECLICK:', button, press
      if not press: return
      if button==4: #wheelUp
         kbrd.tap_key('w') #emulate W button
      else:
         mouse.click(x, y, button) #return original event to system

if __name__ == '__main__':
   mainHook=hook()
   mainHook.captwure = True
   # mainHook.daemon = True
   mainHook.start() #start()
   while True:
      time.sleep(0.1)

this code doesnt work :angry:

byaka avatar Dec 16 '13 11:12 byaka

I'm actually working on a slightly different bug related to your code at the moment (scrolling down creates some weird loop)... however if you change mainHook.captwure = True to mainHook.capture = True the event capturing should work.

SavinaRoja avatar Dec 16 '13 20:12 SavinaRoja

houuu, so stupid error, sorry. but problem doesnt solves... when i click on left MouseButton (for example), i want to send this event to system without changes. if hook.capture==False, im catch events and emulate needed (in example - keyPress W) but mouseWheelUp also sended to system (i don't want this) if hook.capture==True, im catch events and emulate needed (in example - keyPress W) and mouseWheelUp prevented from system, but also all another mouse events too. mouse.click() doesnt send events to system... sorry for bad and strange explainig of problem, hope u understand me ^^

byaka avatar Dec 16 '13 20:12 byaka

Ah, I think I understand the issue better now. The basic trouble is that events generated by PyMouse will be picked up by PyMouseEvent. So when capturing is set, a net is cast through which the synthetic ones won't escape. I wonder why I did not see infinite loops for all of the buttons though? I did verify that PyMouseEvent does observe all events generated by Pymouse (on X11) in a separate basic test however. This is also true for PyKeyboard and PykeyboardEvent.

There are two ways I can think of right now to address the problem, and perhaps others may be discussed. This issue touches on the topic of fine-grained capturing control in PyUserInput. One way to fix this would be to support a feature where capturing can be implemented only on a subset of mouse buttons; this seems like a sensible feature for advanced users, so long as the complexity is hidden from novices. Another way to fix this would be to provide a feature where event capturing ignores synthetic events.

Until these things are cleared up, capturing input to generate input of the same type is going to be a tricky pitfall for PyUserInput.

@byaka This is a good issue to raise, and it may be a bit of a challenge. Hopefully I'll have some time to look at it shortly after the holidays.

SavinaRoja avatar Dec 16 '13 21:12 SavinaRoja

yes, u understand me. second variant is good and elegant, imho. hope u win this challenge ;) велосипед i'm try to solve my problem with evrouter. In this time i cant create a bicycle :laughing:

byaka avatar Dec 16 '13 21:12 byaka

Wait... uhm I was under the impression that you could return the event. But no... This would be the equivalent of JS like so

el.onclick = function (e) {
    if (...) {
        ...
        return false
    } else {
        return true
}

Or the more modern e.preventDefault()

pepijndevos avatar Dec 17 '13 07:12 pepijndevos

@pepijndevos I was hoping you might have some insight into this. The only method I am currently familiar with in Xlib is how to grab a key or mouse button individually for capturing. I believe the same is possible in windows. It would be better to selectively uncapture the event in the scheme illustrated by your JS example however.

SavinaRoja avatar Dec 17 '13 07:12 SavinaRoja

The Mac code already does return the event or a Null event under the covers: https://github.com/SavinaRoja/PyUserInput/blob/master/pymouse/mac.py#L130-L133

On Mac you can't capture one key only.

pepijndevos avatar Dec 17 '13 08:12 pepijndevos