fix(inject/mutter): GNOME input via Mutter's direct EIS, not the xdg portal
ci / rust (push) Successful in 56s
ci / web (push) Failing after 35s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 4s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 3s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 4s
ci / docs-site (push) Failing after 38s
apple / swift (push) Successful in 1m15s
ci / rust (push) Successful in 56s
ci / web (push) Failing after 35s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 4s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 3s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 4s
ci / docs-site (push) Failing after 38s
apple / swift (push) Successful in 1m15s
On a headless GNOME host the xdg-desktop-portal RemoteDesktop Start() blocks on an
interactive "Allow remote control?" approval nobody can click, so libei input timed out
("EIS setup timed out") and neither mouse nor keyboard worked — even though video worked
(it uses Mutter's direct RemoteDesktop API).
Add EiSource::MutterEis: obtain the EIS fd from
org.gnome.Mutter.RemoteDesktop.Session.ConnectToEIS (CreateSession → Start → ConnectToEIS),
no portal and no approval. Selected for GNOME/Mutter; KWin keeps the RemoteDesktop portal,
gamescope keeps its own EIS socket.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -48,7 +48,9 @@ pub fn open(backend: Backend) -> Result<Box<dyn InputInjector>> {
|
||||
Backend::Libei => {
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
Ok(Box::new(libei::LibeiInjector::open()?))
|
||||
Ok(Box::new(
|
||||
libei::LibeiInjector::open_with(libei_ei_source())?,
|
||||
))
|
||||
}
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
{
|
||||
@@ -105,6 +107,25 @@ pub fn default_backend() -> Backend {
|
||||
}
|
||||
}
|
||||
|
||||
/// How the libei backend reaches its EIS server. KWin goes through the `RemoteDesktop` *portal*
|
||||
/// (with a pre-seeded grant), but GNOME's portal `Start()` needs an interactive approval a
|
||||
/// headless host can't answer — so GNOME goes straight to Mutter's *direct* RemoteDesktop EIS
|
||||
/// (`org.gnome.Mutter.RemoteDesktop`), the same direct API the Mutter video backend uses.
|
||||
#[cfg(target_os = "linux")]
|
||||
fn libei_ei_source() -> libei::EiSource {
|
||||
let gnome = std::env::var("PUNKTFUNK_COMPOSITOR")
|
||||
.is_ok_and(|v| v.trim().eq_ignore_ascii_case("mutter"))
|
||||
|| std::env::var("XDG_CURRENT_DESKTOP")
|
||||
.unwrap_or_default()
|
||||
.to_ascii_uppercase()
|
||||
.contains("GNOME");
|
||||
if gnome {
|
||||
libei::EiSource::MutterEis
|
||||
} else {
|
||||
libei::EiSource::Portal
|
||||
}
|
||||
}
|
||||
|
||||
/// Map a Windows Virtual-Key code (as sent by Moonlight/GameStream) to a Linux evdev key code.
|
||||
pub fn vk_to_evdev(vk: u8) -> Option<u16> {
|
||||
match vk {
|
||||
|
||||
Reference in New Issue
Block a user