Open josephernest opened 3 years ago
The feature-injected branch contains an implementation of this. I have yet to find a way to implement it for Xorg though, so I have not merged it.
I would appreciate your input on the way the feature is introduced though!
I have yet to find a way to implement it for Xorg though
I'm not too familiar with input events, but testing with xev
with xfce as my wm:
pynput.keyboard.Controller.press('a')
/ .release('a')
vs tapping 'a' on my keyboard:
(also xdotool key a
shows as synthetic NO
)
But interestingly, upon checking with pynput.keyboard.Listener._event_to_key = lambda s, d, e: print(e)
I don't see anything printed when I use Controller.press
-- only with my hardware keyboard and xdotool. Might be something there?
Just dropping some random investigation on the matter for posterity, and hopefully reviving interest in merging at least the existing support ;)
Tested in a manjaro vm.
Can this be done with the mouse as well?
@FujiwaraChoki, the implementation in the feature branch makes the injected flag available for all types of listeners, so yes.
However, as stated above, I would like some feedback on the feature before merging it. Since last I commented, I have implemented it for X as well.
I'd like to detect real mouse wheelscrolls, and based on timing condition (to detect if there is a fast "acceleration"), then generate additional scrollwheels with
pynput
. Problem: the real wheelscrolls and the pynput-generated wheelscrolls arrive in the same Listener. Question: Is there a way to distinguish between real and pynput generated wheelscrolls? And avoid that the generated scrolls arrive in theon_scroll
listener?
I am doing the same thing as OP in Windows and face the same problem. Now my workaround is filter out all scroll events during my generation process, which is barely workable, making it not responding to real scroll events. So I too wish this feature come into release version sooner. Anyway thanks to this excellent library!
@moses-palmer Hello!
I tested feature-inject
branch in windows, it does differentiates real and generated scroll(mouse wheel) events. And left/right/middle buttons listening for real events also works(I didn't try to generate them, so no generated event listening test), but it crashes when I press xbutton1 or xbutton2. The exception message is as follows:
Unhandled exception in listener callback
Traceback (most recent call last):
File "D:\Develop\Python\anaconda3\Lib\site-packages\pynput\_util\win32.py", line 386, in _handler
converted = self._convert(code, msg, lpdata)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\Develop\Python\anaconda3\Lib\site-packages\pynput\_util\win32.py", line 401, in _convert
raise NotImplementedError()
NotImplementedError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "D:\Develop\Python\anaconda3\Lib\site-packages\pynput\_util\__init__.py", line 230, in inner
return f(self, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\Develop\Python\anaconda3\Lib\site-packages\pynput\_util\win32.py", line 390, in _handler
self._handle(code, msg, lpdata)
File "D:\Develop\Python\anaconda3\Lib\site-packages\pynput\mouse\_win32.py", line 221, in _handle
self.on_click(data.pt.x, data.pt.y, button, pressed)
File "D:\Develop\Python\anaconda3\Lib\site-packages\pynput\_util\__init__.py", line 146, in inner
if f(*args) is False:
^^^^^^^^
TypeError: on_click() missing 1 required positional argument: 'injected'
The code is plain and simple:
def on_scroll(x, y, dx, dy, injected):
if injected:
return
try:
event_collector.on_scroll(x, y, dx, dy)
except Exception as e:
print(f"Error in on_scroll: {traceback.print_exception(e)}")
def on_click(x, y, button, pressed, injected):
if pressed:
event_generator.generator_running = False
print(f"------------------------------------------------------------------------------------ mouse event: {button} {pressed} ({x}, {y}), {injected}")
with mouse.Listener(on_scroll=on_scroll, on_click=on_click) as listener:
try:
listener.join()
except KeyboardInterrupt:
print("Stopped listening for scroll events.")
Windows version: 11 23H2 (22635.4082) Python version: 3.12.3
I also found that pynput will regard ALL mouse events forwarded from client as injected when running in remote desktop server side, even if the mouse event is triggered from a real mouse at client side. Understandable though, since the mouse events can be seen as injected by remote desktop software. I tested Microsoft remote desktop and NoMachine, both behaves so. Perhaps what we can do is just mention this issue in doc.
@WilliamStone, thank you for your feedback.
I have updated the feature branch to fix the error reported here.
Regarding the issue with remote desktop software, I think the observed behaviour is reasonable, but as you suggest, it should be noted in the documentation.
I'd like to detect real mouse wheelscrolls, and based on timing condition (to detect if there is a fast "acceleration"), then generate additional scrollwheels with
pynput
. Problem: the real wheelscrolls and the pynput-generated wheelscrolls arrive in the same Listener. Question: Is there a way to distinguish between real and pynput generated wheelscrolls? And avoid that the generated scrolls arrive in theon_scroll
listener?