mirror of
https://github.com/feschber/lan-mouse.git
synced 2026-03-07 11:59:59 +03:00
upgrade ashpd + reis (#226)
This commit is contained in:
committed by
GitHub
parent
9d28fe6c7b
commit
1d25dfbe50
@@ -40,10 +40,10 @@ wayland-protocols-wlr = { version = "0.3.1", features = [
|
||||
"client",
|
||||
], optional = true }
|
||||
x11 = { version = "2.21.0", features = ["xlib", "xtest"], optional = true }
|
||||
ashpd = { version = "0.9", default-features = false, features = [
|
||||
ashpd = { version = "0.10", default-features = false, features = [
|
||||
"tokio",
|
||||
], optional = true }
|
||||
reis = { version = "0.2", features = ["tokio"], optional = true }
|
||||
reis = { version = "0.4", features = ["tokio"], optional = true }
|
||||
|
||||
[target.'cfg(target_os="macos")'.dependencies]
|
||||
core-graphics = { version = "0.23", features = ["highsierra"] }
|
||||
|
||||
@@ -19,26 +19,10 @@ use wayland_client::{
|
||||
|
||||
#[cfg(all(unix, feature = "libei", not(target_os = "macos")))]
|
||||
use ashpd::desktop::ResponseError;
|
||||
#[cfg(all(unix, feature = "libei", not(target_os = "macos")))]
|
||||
use reis::tokio::{EiConvertEventStreamError, HandshakeError};
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
use core_graphics::base::CGError;
|
||||
|
||||
#[cfg(all(unix, feature = "libei", not(target_os = "macos")))]
|
||||
#[derive(Debug, Error)]
|
||||
#[error("error in libei stream: {inner:?}")]
|
||||
pub struct ReisConvertEventStreamError {
|
||||
inner: EiConvertEventStreamError,
|
||||
}
|
||||
|
||||
#[cfg(all(unix, feature = "libei", not(target_os = "macos")))]
|
||||
impl From<EiConvertEventStreamError> for ReisConvertEventStreamError {
|
||||
fn from(e: EiConvertEventStreamError) -> Self {
|
||||
Self { inner: e }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum CaptureError {
|
||||
#[error("activation stream closed unexpectedly")]
|
||||
@@ -48,11 +32,8 @@ pub enum CaptureError {
|
||||
#[error("io error: `{0}`")]
|
||||
Io(#[from] std::io::Error),
|
||||
#[cfg(all(unix, feature = "libei", not(target_os = "macos")))]
|
||||
#[error("error in libei stream: `{0}`")]
|
||||
Reis(#[from] ReisConvertEventStreamError),
|
||||
#[cfg(all(unix, feature = "libei", not(target_os = "macos")))]
|
||||
#[error("libei handshake failed: `{0}`")]
|
||||
Handshake(#[from] HandshakeError),
|
||||
#[error("libei error: `{0}`")]
|
||||
Reis(#[from] reis::Error),
|
||||
#[cfg(all(unix, feature = "libei", not(target_os = "macos")))]
|
||||
#[error(transparent)]
|
||||
Portal(#[from] ashpd::Error),
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
use ashpd::{
|
||||
desktop::{
|
||||
input_capture::{Activated, Barrier, BarrierID, Capabilities, InputCapture, Region, Zones},
|
||||
input_capture::{
|
||||
Activated, ActivatedBarrier, Barrier, BarrierID, Capabilities, InputCapture, Region,
|
||||
Zones,
|
||||
},
|
||||
Session,
|
||||
},
|
||||
enumflags2::BitFlags,
|
||||
@@ -8,14 +11,15 @@ use ashpd::{
|
||||
use async_trait::async_trait;
|
||||
use futures::{FutureExt, StreamExt};
|
||||
use reis::{
|
||||
ei,
|
||||
event::{DeviceCapability, EiEvent},
|
||||
tokio::{EiConvertEventStream, EiEventStream},
|
||||
ei::{self, handshake::ContextType},
|
||||
event::{Connection, DeviceCapability, EiEvent},
|
||||
tokio::EiConvertEventStream,
|
||||
};
|
||||
use std::{
|
||||
cell::Cell,
|
||||
collections::HashMap,
|
||||
io,
|
||||
num::NonZeroU32,
|
||||
os::unix::net::UnixStream,
|
||||
pin::Pin,
|
||||
rc::Rc,
|
||||
@@ -32,14 +36,13 @@ use tokio::{
|
||||
use tokio_util::sync::CancellationToken;
|
||||
|
||||
use futures_core::Stream;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
use input_event::Event;
|
||||
|
||||
use crate::CaptureEvent;
|
||||
|
||||
use super::{
|
||||
error::{CaptureError, LibeiCaptureCreationError, ReisConvertEventStreamError},
|
||||
error::{CaptureError, LibeiCaptureCreationError},
|
||||
Capture as LanMouseInputCapture, Position,
|
||||
};
|
||||
|
||||
@@ -65,22 +68,6 @@ pub struct LibeiInputCapture<'a> {
|
||||
terminated: bool,
|
||||
}
|
||||
|
||||
static INTERFACES: Lazy<HashMap<&'static str, u32>> = Lazy::new(|| {
|
||||
let mut m = HashMap::new();
|
||||
m.insert("ei_connection", 1);
|
||||
m.insert("ei_callback", 1);
|
||||
m.insert("ei_pingpong", 1);
|
||||
m.insert("ei_seat", 1);
|
||||
m.insert("ei_device", 2);
|
||||
m.insert("ei_pointer", 1);
|
||||
m.insert("ei_pointer_absolute", 1);
|
||||
m.insert("ei_scroll", 1);
|
||||
m.insert("ei_button", 1);
|
||||
m.insert("ei_keyboard", 1);
|
||||
m.insert("ei_touchscreen", 1);
|
||||
m
|
||||
});
|
||||
|
||||
/// returns (start pos, end pos), inclusive
|
||||
fn pos_to_barrier(r: &Region, pos: Position) -> (i32, i32, i32, i32) {
|
||||
let (x, y) = (r.x_offset(), r.y_offset());
|
||||
@@ -118,7 +105,7 @@ impl From<ICBarrier> for Barrier {
|
||||
fn select_barriers(
|
||||
zones: &Zones,
|
||||
clients: &[Position],
|
||||
next_barrier_id: &mut u32,
|
||||
next_barrier_id: &mut NonZeroU32,
|
||||
) -> (Vec<ICBarrier>, HashMap<BarrierID, Position>) {
|
||||
let mut pos_for_barrier = HashMap::new();
|
||||
let mut barriers: Vec<ICBarrier> = vec![];
|
||||
@@ -129,7 +116,9 @@ fn select_barriers(
|
||||
.iter()
|
||||
.map(|r| {
|
||||
let id = *next_barrier_id;
|
||||
*next_barrier_id = id + 1;
|
||||
*next_barrier_id = next_barrier_id
|
||||
.checked_add(1)
|
||||
.expect("barrier id out of range");
|
||||
let position = pos_to_barrier(r, *pos);
|
||||
pos_for_barrier.insert(id, *pos);
|
||||
ICBarrier::new(id, position)
|
||||
@@ -144,7 +133,7 @@ async fn update_barriers(
|
||||
input_capture: &InputCapture<'_>,
|
||||
session: &Session<'_, InputCapture<'_>>,
|
||||
active_clients: &[Position],
|
||||
next_barrier_id: &mut u32,
|
||||
next_barrier_id: &mut NonZeroU32,
|
||||
) -> Result<(Vec<ICBarrier>, HashMap<BarrierID, Position>), ashpd::Error> {
|
||||
let zones = input_capture.zones(session).await?.response()?;
|
||||
log::debug!("zones: {zones:?}");
|
||||
@@ -168,7 +157,7 @@ async fn create_session<'a>(
|
||||
log::debug!("creating input capture session");
|
||||
input_capture
|
||||
.create_session(
|
||||
&ashpd::WindowIdentifier::default(),
|
||||
None,
|
||||
Capabilities::Keyboard | Capabilities::Pointer | Capabilities::Touchscreen,
|
||||
)
|
||||
.await
|
||||
@@ -177,7 +166,7 @@ async fn create_session<'a>(
|
||||
async fn connect_to_eis(
|
||||
input_capture: &InputCapture<'_>,
|
||||
session: &Session<'_, InputCapture<'_>>,
|
||||
) -> Result<(ei::Context, EiConvertEventStream), CaptureError> {
|
||||
) -> Result<(ei::Context, Connection, EiConvertEventStream), CaptureError> {
|
||||
log::debug!("connect_to_eis");
|
||||
let fd = input_capture.connect_to_eis(session).await?;
|
||||
|
||||
@@ -187,17 +176,11 @@ async fn connect_to_eis(
|
||||
|
||||
// create ei context
|
||||
let context = ei::Context::new(stream)?;
|
||||
let mut event_stream = EiEventStream::new(context.clone())?;
|
||||
let response = reis::tokio::ei_handshake(
|
||||
&mut event_stream,
|
||||
"de.feschber.LanMouse",
|
||||
ei::handshake::ContextType::Receiver,
|
||||
&INTERFACES,
|
||||
)
|
||||
.await?;
|
||||
let event_stream = EiConvertEventStream::new(event_stream, response.serial);
|
||||
let (conn, event_stream) = context
|
||||
.handshake_tokio("de.feschber.LanMouse", ContextType::Receiver)
|
||||
.await?;
|
||||
|
||||
Ok((context, event_stream))
|
||||
Ok((context, conn, event_stream))
|
||||
}
|
||||
|
||||
async fn libei_event_handler(
|
||||
@@ -211,8 +194,7 @@ async fn libei_event_handler(
|
||||
let ei_event = ei_event_stream
|
||||
.next()
|
||||
.await
|
||||
.ok_or(CaptureError::EndOfStream)?
|
||||
.map_err(ReisConvertEventStreamError::from)?;
|
||||
.ok_or(CaptureError::EndOfStream)??;
|
||||
log::trace!("from ei: {ei_event:?}");
|
||||
let client = current_pos.get();
|
||||
handle_ei_event(ei_event, client, &context, &event_tx, &release_session).await?;
|
||||
@@ -268,7 +250,7 @@ async fn do_capture(
|
||||
/* safety: libei_task does not outlive Self */
|
||||
let input_capture = unsafe { &*input_capture };
|
||||
let mut active_clients: Vec<Position> = vec![];
|
||||
let mut next_barrier_id = 1u32;
|
||||
let mut next_barrier_id = NonZeroU32::new(1).expect("id must be non-zero");
|
||||
|
||||
let mut zones_changed = input_capture.receive_zones_changed().await?;
|
||||
|
||||
@@ -358,7 +340,7 @@ async fn do_capture_session(
|
||||
session: &mut Session<'_, InputCapture<'_>>,
|
||||
event_tx: &Sender<(Position, CaptureEvent)>,
|
||||
active_clients: &[Position],
|
||||
next_barrier_id: &mut u32,
|
||||
next_barrier_id: &mut NonZeroU32,
|
||||
notify_release: &Notify,
|
||||
cancel: (CancellationToken, CancellationToken),
|
||||
) -> Result<(), CaptureError> {
|
||||
@@ -367,7 +349,7 @@ async fn do_capture_session(
|
||||
let current_pos = Rc::new(Cell::new(None));
|
||||
|
||||
// connect to eis server
|
||||
let (context, ei_event_stream) = connect_to_eis(input_capture, session).await?;
|
||||
let (context, _conn, ei_event_stream) = connect_to_eis(input_capture, session).await?;
|
||||
|
||||
// set barriers
|
||||
let (barriers, pos_for_barrier_id) =
|
||||
@@ -415,9 +397,9 @@ async fn do_capture_session(
|
||||
|
||||
// get barrier id from activation
|
||||
let barrier_id = match activated.barrier_id() {
|
||||
Some(bid) => bid,
|
||||
Some(ActivatedBarrier::Barrier(id)) => id,
|
||||
// workaround for KDE plasma not reporting barrier ids
|
||||
None => find_corresponding_client(&barriers, activated.cursor_position().expect("no cursor position reported by compositor")),
|
||||
Some(ActivatedBarrier::UnknownBarrier) | None => find_corresponding_client(&barriers, activated.cursor_position().expect("no cursor position reported by compositor")),
|
||||
};
|
||||
|
||||
// find client corresponding to barrier
|
||||
|
||||
Reference in New Issue
Block a user