Skip to content

Ei protocol support using reis - #1388

Closed
ids1024 wants to merge 5 commits into
Smithay:masterfrom
ids1024:reis
Closed

Ei protocol support using reis#1388
ids1024 wants to merge 5 commits into
Smithay:masterfrom
ids1024:reis

Conversation

@ids1024

@ids1024 ids1024 commented Apr 14, 2024

Copy link
Copy Markdown
Member

The Ei protocol is needed for the xdg-desktop-portal RemoteDesktop portal to emulate input devices, as well as by the InputCapture portal for Synergy-like uses (input-leap supports Wayland with this portal).

This is quite incomplete, but the type-text example in reis now works in Anvil. Reis could still use somewhat better higher-level servere-side APIs.

It might make sense if ei exposed seats and devices matching those in Smithay (or would compositors not always want to do that?). Not sure how best to handle that.

Receiver contexts for the InputCapture portal are also a bit more complicated to implement. Those involve capturing input once the cursor crosses outside the display. That isn't implemented at all here yet.

@axelkar

axelkar commented Jul 15, 2025

Copy link
Copy Markdown
Contributor

Oops, I've been doing the same thing in Niri. I ruled out upstreaming to Smithay because I thought the implementation would have more Niri and org.gnome.Mutter.RemoteDesktop-specific features.

Some comments on your code: (smithay::backend::input shortened to sbi.. please name that module more uniquely next time)

I wrote an adapter struct between EisRequest and sbi::Event because I thought I had to avoid Rust's orphan rule (turns out just having the input backend defined by the same crate makes it work).

Doesn't Smithay specify that IDs must be unique? I currently pass a session_id (org.gnome.Mutter.RemoteDesktop session ID) through the adapter to sbi::Event::device and sbi::Device::id.

I can also provide a true sbi::KeyboardKeyEvent::count, and I combine axis requests into a single frame, similar to the wlr-virtual-pointer implementation in Niri.

@ids1024

ids1024 commented Jul 18, 2025

Copy link
Copy Markdown
Member Author

please name that module more uniquely next time

Yeah, the same module or type name being used for different things in different parts of smithay can be a bit confusing sometimes.

Doesn't Smithay specify that IDs must be unique? I currently pass a session_id (org.gnome.Mutter.RemoteDesktop session ID) through the adapter to sbi::Event::device and sbi::Device::id.

https://docs.rs/smithay/0.7.0/smithay/backend/input/trait.Device.html says "Unique id of a single device at a point in time." and "Note: This means ids may be re-used by the backend for later devices.".

I suppose with ei, the protocol object id would be unique in that manner.

@ids1024

ids1024 commented Jul 18, 2025

Copy link
Copy Markdown
Member Author

Probably the biggest question here is exactly how much of it Smithay should handle/abstract. But I think we probably should just clean up any issues with the event conversion, and merge a minimal version of this. Then see what further abstractions are useful to add in either smithay or reis later.

@ids1024

ids1024 commented Jan 16, 2026

Copy link
Copy Markdown
Member Author

I think I've come up with a reasonable API for input emulation using libei. (Input capture for something like the Input Capture portal may have different requirements). Mirroring the Smithay seat API a bit, to provide an API that should be flexible enough without requiring the compositor to do too much.

I've also moved some things into reis so they don't have to be dealt with here.

@ids1024

ids1024 commented Jan 17, 2026

Copy link
Copy Markdown
Member Author

I guess this will also need to send DeviceAdded and DeviceRemoved events.

For a unique device .id(), it could combine the fd and protocol id. I guess it just needs to not race a device removal with a device add on a different socket that connects with the same fd...

Edit: I guess fds racing isn't an issue, because as long as we're processing the event source, the fd isn't closed.

@ids1024
ids1024 force-pushed the reis branch 2 times, most recently from 1a6b229 to 587a092 Compare February 16, 2026 20:19
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 18.69%. Comparing base (cb9ea26) to head (587a092).
⚠️ Report is 10 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1388      +/-   ##
==========================================
- Coverage   18.77%   18.69%   -0.09%     
==========================================
  Files         180      182       +2     
  Lines       28743    28879     +136     
==========================================
+ Hits         5397     5399       +2     
- Misses      23346    23480     +134     
Flag Coverage Δ
wlcs-buffer 16.27% <ø> (-0.08%) ⬇️
wlcs-core 15.93% <ø> (-0.07%) ⬇️
wlcs-output 6.82% <ø> (-0.04%) ⬇️
wlcs-pointer-input 17.69% <ø> (-0.08%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

ids1024 added 5 commits April 13, 2026 12:54
The EI protocol is needed for the xdg-desktop-portal `RemoteDesktop`
portal to emulate input devices, as well as by the `InputCapture` portal
for Synergy-like uses (input-leap supports Wayland with this portal).

This exposes a relatively simple API for a compositor to create EI seats
and devices, mirroring the `Seat` API. It also provides an `InputBackend`
that converts emulated input to Smithay input events.

Receiver contexts for the `InputCapture` portal are also a bit more
complicated to implement. Those involve capturing input once the cursor
crosses outside the display. That isn't implemented at all here yet.

We may want to change things in the future to accommodate receiver
contexts, etc. But this API is fairly minimal to use, so future breaking
changes shouldn't be too challenging for a compositor to adapt to.
This seems a bit awkward to support on other backends given how Anvil
uses `process_input_event_windowed` there...

This implementation creates a socket file and sets `LIBEI_SOCKET` to
allow sending emulated input events to Anvil.
@ids1024

ids1024 commented Jun 16, 2026

Copy link
Copy Markdown
Member Author

Merged in #2051. Any future improvements can now be done in separate PRs.

@ids1024 ids1024 closed this Jun 16, 2026
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

Successfully merging this pull request may close these issues.

3 participants