Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GeGenericEvent is not hoisted to xinput event type #99

Open
danielnelson opened this issue Jan 16, 2020 · 10 comments
Open

GeGenericEvent is not hoisted to xinput event type #99

danielnelson opened this issue Jan 16, 2020 · 10 comments

Comments

@danielnelson
Copy link

My goal is to write a program that monitors xinput hierarchy events, but I can only receive xcffib.xproto.GeGenericEvent, which I can't figure out how to do anything of use with.

I'm new to XCB and X11 programming, so I'm sure the fault is my code. I have looked at some examples using libxcb directly though, and I'm having trouble figuring out the python calls. Here is what I have come up with so far:

#!/usr/bin/env python3.6

import xcffib
import xcffib.xinput

conn = xcffib.connect()
xinput = conn(xcffib.xinput.key)

root = conn.get_setup().roots[0].root

mask = xcffib.xinput.EventMask.synthetic(
        xcffib.xinput.Device.All, 1, [xcffib.xinput.XIEventMask.Hierarchy])
xinput.XISelectEvents(root, 1, [mask])
conn.flush()

while True:
    event = conn.wait_for_event()
    if event is None:
        break

    print(type(event))

Reproduction Steps:

  • Run script and plugin/unplug keyboard.

Expected Output:

$ python xinput-test.py
<class 'xcffib.xinput.HierarchyEvent'>
<class 'xcffib.xinput.HierarchyEvent'>
<class 'xcffib.xinput.HierarchyEvent'>

Actual Output:

$ python xinput-test.py
<class 'xcffib.xproto.GeGenericEvent'>
<class 'xcffib.xproto.GeGenericEvent'>
<class 'xcffib.xproto.GeGenericEvent'>
@tych0
Copy link
Owner

tych0 commented Jan 16, 2020

What happens if you do a xinput.HeirarchyEvent(xcffib.MemoryUnpacker(event.buf))?

@tych0
Copy link
Owner

tych0 commented Jan 16, 2020

(meaning, is the resulting event reasonable?). Also does xtrace say something different?

@danielnelson
Copy link
Author

At first I got this error:

Traceback (most recent call last):
  File "xinput-test.py", line 22, in <module>
    print(xcffib.xinput.HierarchyEvent(xcffib.MemoryUnpacker(event.buf)))
AttributeError: 'GeGenericEvent' object has no attribute 'buf'

I switched the code to this, but I'm not sure if this is valid:

    e = xcffib.xinput.HierarchyEvent(xcffib.MemoryUnpacker(event.pack()))
    print(e.deviceid)
    print(e.flags)
    print(e.infos)

I couldn't see any interesting data after my attempted conversion:

deviceid 0
flags 0
infos []

From xtrace:

000:<:0006: 20: XInputExtension-Request(131,46): XISelectEvents win=0x0000016a masks={device=0 mask=0x00000800;};
000:>:0006: Event Generic(35) XInputExtension(131) HierarchyChanged(11) extension=0x83 length=45 evtype=0x000b data=0x00,0x00,0x9c,0xff,0xff,0x0d,0x80,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x03,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x02,0x00,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x02,0x00,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x03,0x00,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x03,0x00,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x03,0x00,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x03,0x00,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x00,0x03,0x00,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0x03,0x00,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x02,0x00,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,0x03,0x00,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x00,0x03,0x00,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x03,0x00,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x03,0x00,0x04,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x0b,0x00,0x02,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00;
000:>:0006: Event Generic(35) XInputExtension(131) HierarchyChanged(11) extension=0x83 length=45 evtype=0x000b data=0x00,0x00,0x9c,0xff,0xff,0x0d,0x08,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x03,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x02,0x00,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x02,0x00,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x03,0x00,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x03,0x00,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x03,0x00,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x03,0x00,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x00,0x03,0x00,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0x03,0x00,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x02,0x00,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,0x03,0x00,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x00,0x03,0x00,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x03,0x00,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x0b,0x00,0x02,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00;

@tych0
Copy link
Owner

tych0 commented Jan 17, 2020

Dang. I was hoping this would just be a matter of re-interpreting the event, but it seems it's more complicated than that. As the readme notes, we don't really have a great readme for XGE, in part because even xcb-proto has never really supported it.

Oddly, the xcb-proto spec has documentation, but not an implementation of the members. So I think it needs a patch like this: tych0/xcb-proto@54da72b

And then you could do it with xcffib.xinput.HierarchyEvent(xcffib.MemoryUnpacker(e.data)). I'm not exactly sure on the layout though, see the docs cited in the above commit for details.

Another nice thing would be, if this actually works, to build in an API from GeGenericEvent that would auto-parse things based on the extension and event, assuming the above works. I'll see if I can play around with it more this weekend, but those are my initial thoughts.

@danielnelson
Copy link
Author

Thanks, appreciate you looking into this.

@rolfmorel
Copy link

Hi there. I have a similar issue, though for XInput's pointer barriers.

I gather that rebuilding xcffib with your amended xproto should maybe allow me to go from a GeGenericEvent to a BarrierHitEvent. So I set out to try this out.

I managed to get make xcffib GEN=xcffibgen CABAL=true XCBDIR=../xcb-proto/src to work (based on ArchLinux's packaging of this project), with ../xcb-proto being a checkout of your support-gegenric branch. Using this local build, by creating a symlink named xcffib2, I get the following error when obtaining a connection:

xcffib2.XcffibException: No core protocol object has been set.  Did you import xcffib.xproto?

And, yes, I import xcffib2.xproto at the top of the file.

I would like to use python (and your library) for this project, though the effort to do so is rather high at the moment. Could you point out how to make the (rather convoluted) build system produce a working build, for which I could check the xproto fix.

@tych0
Copy link
Owner

tych0 commented Jun 7, 2020

Using this local build, by creating a symlink named xcffib2

I'd just install it in a virtual env or something. Calling it xcffib2 will confuse lots of things, I think.

@elParaguayo
Copy link
Contributor

elParaguayo commented Jun 6, 2022

Hi Tych0!

I'm just running into this issue now as we're looking at whether using pointer barriers in qtile may be a way to change the focus when a mouse moves to a new screen.

I'm getting the same GeGenericEvent but I can't see how to convert it into a BarrierHitEvent.

There's reference to a support-gegeneric branch above but I'm assuming that was merged into master so I'm not sure what I'm missing.

Current code is here: elParaguayo/qtile@4eb5786

Dumping the event's __dict__ gives me: event.__dict__={'response_type': 35, 'sequence': 3855, 'bufsize': 26}. Not sure what I can do with that!

@elParaguayo
Copy link
Contributor

@tych0 I've been doing a bit more digging here (with a disclaimer that I've spent very little time in the xcffib library and know virtually nothing about ffi) and have some observations.

My main issue is that the GeGenericEvent that gets returned doesn't seem to match the spec. None of the data fields that I expect to see are available which means there's no way to identify which event is actually being triggered.

Ideally, GeGenericEvent would have these fields but xcffib would also look up the relevant extension and event_type and hoist the event to that class type.

I'd be happy to help work on that last bit but I'm at a loss to understand why GeGenericEvent doesn't have the right fields.

Any ideas?

FWIW - I played with some code that m-col wrote and was able to cast the xcb_generic_event_t event to the the xcb_ge_generic_event_t type and could then access the relevant fields so I'm sure it's possible to do in xcffib.

@tych0
Copy link
Owner

tych0 commented Jun 10, 2022

There's reference to a support-gegeneric branch above but I'm assuming that was merged into master so I'm not sure what I'm missing.

I don't think any of this was ever merged, that was a local hack that I had to just see if we could get it to work. might be an interesting starting point, though.

My main issue is that the GeGenericEvent that gets returned doesn't seem to match the spec. None of the data fields that I expect to see are available which means there's no way to identify which event is actually being triggered.

Yeah, i suspect that's because the xml doesn't have the right fields (hence my hack patch above). you might start a discussion on the https://lists.freedesktop.org/mailman/listinfo/xcb mailing list about implementing XGE support to see if anyone else is interested in helping wire up the xml.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants