Skip to content

Commit

Permalink
Libei Input Capture (#94)
Browse files Browse the repository at this point in the history
  • Loading branch information
feschber authored Mar 20, 2024
1 parent f7c59e4 commit 9afe7da
Show file tree
Hide file tree
Showing 10 changed files with 986 additions and 502 deletions.
787 changes: 360 additions & 427 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ gtk = { package = "gtk4", version = "0.7.2", features = ["v4_2"], optional = tru
adw = { package = "libadwaita", version = "0.5.2", features = ["v1_1"], optional = true }
async-channel = { version = "2.1.1", optional = true }
keycode = "0.4.0"
once_cell = "1.19.0"

[target.'cfg(unix)'.dependencies]
libc = "0.2.148"
Expand All @@ -41,7 +42,7 @@ wayland-protocols = { version="0.31.0", features=["client", "staging", "unstable
wayland-protocols-wlr = { version="0.2.0", features=["client"], optional = true }
wayland-protocols-misc = { version="0.2.0", features=["client"], optional = true }
x11 = { version = "2.21.0", features = ["xlib", "xtest"], optional = true }
ashpd = { version = "0.6.2", default-features = false, features = ["tokio"], optional = true }
ashpd = { version = "0.8", default-features = false, features = ["tokio"], optional = true }
reis = { git = "https://github.com/ids1024/reis", features = [ "tokio" ], optional = true }

[target.'cfg(target_os="macos")'.dependencies]
Expand Down
2 changes: 1 addition & 1 deletion nix/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ rustPlatform.buildRustPackage {
cargoLock.lockFile = ../Cargo.lock;

cargoLock.outputHashes = {
"reis-0.1.0" = "sha256-sRZqm6QdmgqfkTjEENV8erQd+0RL5z1+qjdmY18W3bA=";
"reis-0.1.0" = "sha256-QhsRIkzW3wgOlcHpkx3axjS8Vfed00Uf36av9ossPwQ=";
};

# Set Environment Variables
Expand Down
62 changes: 34 additions & 28 deletions src/backend/consumer/libei.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
use std::{
collections::HashMap,
io,
os::{
fd::{FromRawFd, RawFd},
unix::net::UnixStream,
},
os::{fd::OwnedFd, unix::net::UnixStream},
time::{SystemTime, UNIX_EPOCH},
};

use anyhow::{anyhow, Result};
use ashpd::desktop::remote_desktop::{DeviceType, RemoteDesktop};
use ashpd::{
desktop::{
remote_desktop::{DeviceType, RemoteDesktop},
ResponseError,
},
WindowIdentifier,
};
use async_trait::async_trait;
use futures::StreamExt;

Expand Down Expand Up @@ -43,38 +45,42 @@ pub struct LibeiConsumer {
serial: u32,
}

async fn get_ei_fd() -> Result<RawFd, ashpd::Error> {
async fn get_ei_fd() -> Result<OwnedFd, ashpd::Error> {
let proxy = RemoteDesktop::new().await?;
let session = proxy.create_session().await?;

// I HATE EVERYTHING, THIS TOOK 8 HOURS OF DEBUGGING
proxy
.select_devices(
&session,
DeviceType::Pointer | DeviceType::Keyboard | DeviceType::Touchscreen,
)
.await?;
// retry when user presses the cancel button
let (session, _) = loop {
log::debug!("creating session ...");
let session = proxy.create_session().await?;

log::debug!("selecting devices ...");
proxy
.select_devices(&session, DeviceType::Keyboard | DeviceType::Pointer)
.await?;

log::info!("requesting permission for input emulation");
match proxy
.start(&session, &WindowIdentifier::default())
.await?
.response()
{
Ok(d) => break (session, d),
Err(ashpd::Error::Response(ResponseError::Cancelled)) => {
log::warn!("request cancelled!");
continue;
}
e => e?,
};
};

proxy
.start(&session, &ashpd::WindowIdentifier::default())
.await?
.response()?;
proxy.connect_to_eis(&session).await
}

impl LibeiConsumer {
pub async fn new() -> Result<Self> {
// fd is owned by the message, so we need to dup it
let eifd = get_ei_fd().await?;
let eifd = unsafe {
let ret = libc::dup(eifd);
if ret < 0 {
Err(io::Error::last_os_error())
} else {
Ok(ret)
}
}?;
let stream = unsafe { UnixStream::from_raw_fd(eifd) };
let stream = UnixStream::from(eifd);
// let stream = UnixStream::connect("/run/user/1000/eis-0")?;
stream.set_nonblocking(true)?;
let context = ei::Context::new(stream)?;
Expand Down
37 changes: 26 additions & 11 deletions src/backend/consumer/xdg_desktop_portal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use anyhow::Result;
use ashpd::{
desktop::{
remote_desktop::{Axis, DeviceType, KeyState, RemoteDesktop},
Session,
ResponseError, Session,
},
WindowIdentifier,
};
Expand All @@ -26,17 +26,32 @@ impl<'a> DesktopPortalConsumer<'a> {
pub async fn new() -> Result<DesktopPortalConsumer<'a>> {
log::debug!("connecting to org.freedesktop.portal.RemoteDesktop portal ...");
let proxy = RemoteDesktop::new().await?;
log::debug!("creating session ...");
let session = proxy.create_session().await?;
log::debug!("selecting devices ...");
proxy
.select_devices(&session, DeviceType::Keyboard | DeviceType::Pointer)
.await?;

let _ = proxy
.start(&session, &WindowIdentifier::default())
.await?
.response()?;
// retry when user presses the cancel button
let (session, _) = loop {
log::debug!("creating session ...");
let session = proxy.create_session().await?;

log::debug!("selecting devices ...");
proxy
.select_devices(&session, DeviceType::Keyboard | DeviceType::Pointer)
.await?;

log::info!("requesting permission for input emulation");
match proxy
.start(&session, &WindowIdentifier::default())
.await?
.response()
{
Ok(d) => break (session, d),
Err(ashpd::Error::Response(ResponseError::Cancelled)) => {
log::warn!("request cancelled!");
continue;
}
e => e?,
};
};

log::debug!("started session");

Ok(Self { proxy, session })
Expand Down
Loading

0 comments on commit 9afe7da

Please sign in to comment.