Skip to content
Advertisement

Does Python evdev library have an event specific grab or passthrough?

A python evdev device has a .grab() function that prevents other processes from getting input events on the device. Is there any way to limit this to specific events from a device?

For my example, if I .grab() a pen input device that has pressure sensitivity and tilt and 2 click buttons on the side, how would I ‘grab’ ONLY the 2 click buttons but let the rest of the input (the tip, pressure sensitivity and tilt) be caught by the rest of the system as normal?

One of my pen buttons is normally a right click mouse event. I want to make it do something else but it still pops up the right click menu so I’m trying to figure out how to stop that.

I tried doing the grab and ungrab when the event occurs. Like event > grab > do my stuff > ungrab. But that is obviously too late and the OS still pops up the menu.

I tried doing the full grab, then in the event loop if it is a button press do my stuff, otherwise create a UInput event injection by just passing the event back to the system. This was a bit of a tangled mess. Permissions are required. When I finally got past that, the movement was offset and the pressure/tilt wasn’t working… I think it is something to do with the DigiMend driver that actually makes that stuff work and/or xinput settings I have to pass to calibrate the tablet. But I’m not interested in writing all the pressure/tilt functionality from scratch or anything like that, so I need the DigiMend stuff to work as normal. So I gave up on this idea for now.

The only other thought I had was figure out why the OS defaults to the behavior it does and see if I can just manually disable the actions (i.e. Why does it think that button is a right mouse click and make it think that button is nothing instead.)

So I guess this is a 3 level question.

  1. Can I achieve the the grab functionality on select events instead of the device as a whole?
  2. If the passthrough idea was better, is there a way to achieve this without having to do any permission modifications and be able to pass the exact event (i.e. no offset and such that I experienced?)
  3. If evdev does not have this ability or it’d be easier to do in another way, like disabling the defaults for the pen in the OS somehow, I am open to suggestions. I am using Kubuntu 20.04 if that helps.

Any help would be appreciated, let me know if more info is needed, thanks in advance!

Advertisement

Answer

I ended up going with #3 and using xinput. Figured I’d put up this answer for now in case others come across this and want to do something similar.

The workaround was actually kind of simple. I just use xinput to remap the 2 buttons. So evdev doesn’t have to grab at all. Just disable those buttons and everything goes normally except those, which I listen for with evdev.

xinput set-button-map {} 1 0 0 4 5 6 7

My device has 7 buttons and are normally mapped 1-7. Which are all mouse equivalents of left click, middle click, right click, etc…

By using that string and passing the device ID in for the {} I just run that with subprocess first. And voila, no more right click menu. And I can use evdev to map the events to whatever I want.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement