mirror of
https://github.com/feschber/lan-mouse.git
synced 2026-04-13 22:51:26 +03:00
impl session close
This commit is contained in:
@@ -44,7 +44,7 @@ use super::{
|
|||||||
|
|
||||||
/* there is a bug in xdg-remote-desktop-portal-gnome / mutter that
|
/* there is a bug in xdg-remote-desktop-portal-gnome / mutter that
|
||||||
* prevents receiving further events after a session has been disabled once.
|
* prevents receiving further events after a session has been disabled once.
|
||||||
* Therefore the session needs to recreated when the barriers are updated */
|
* Therefore the session needs to be recreated when the barriers are updated */
|
||||||
|
|
||||||
/// events that necessitate restarting the capture session
|
/// events that necessitate restarting the capture session
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
@@ -79,14 +79,15 @@ static INTERFACES: Lazy<HashMap<&'static str, u32>> = Lazy::new(|| {
|
|||||||
m
|
m
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/// returns (start pos, end pos), inclusive
|
||||||
fn pos_to_barrier(r: &Region, pos: Position) -> (i32, i32, i32, i32) {
|
fn pos_to_barrier(r: &Region, pos: Position) -> (i32, i32, i32, i32) {
|
||||||
let (x, y) = (r.x_offset(), r.y_offset());
|
let (x, y) = (r.x_offset(), r.y_offset());
|
||||||
let (width, height) = (r.width() as i32, r.height() as i32);
|
let (w, h) = (r.width() as i32, r.height() as i32);
|
||||||
match pos {
|
match pos {
|
||||||
Position::Left => (x, y, x, y + height - 1), // start pos, end pos, inclusive
|
Position::Left => (x, y, x, y + h - 1),
|
||||||
Position::Right => (x + width, y, x + width, y + height - 1),
|
Position::Right => (x + w, y, x + w, y + h - 1),
|
||||||
Position::Top => (x, y, x + width - 1, y),
|
Position::Top => (x, y, x + w - 1, y),
|
||||||
Position::Bottom => (x, y + height, x + width - 1, y + height),
|
Position::Bottom => (x, y + h, x + w - 1, y + h),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -487,6 +488,15 @@ async fn release_capture(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ALL_CAPABILITIES: &[DeviceCapability] = &[
|
||||||
|
DeviceCapability::Pointer,
|
||||||
|
DeviceCapability::PointerAbsolute,
|
||||||
|
DeviceCapability::Keyboard,
|
||||||
|
DeviceCapability::Touch,
|
||||||
|
DeviceCapability::Scroll,
|
||||||
|
DeviceCapability::Button,
|
||||||
|
];
|
||||||
|
|
||||||
async fn handle_ei_event(
|
async fn handle_ei_event(
|
||||||
ei_event: EiEvent,
|
ei_event: EiEvent,
|
||||||
current_client: Option<CaptureHandle>,
|
current_client: Option<CaptureHandle>,
|
||||||
@@ -496,14 +506,7 @@ async fn handle_ei_event(
|
|||||||
) -> Result<(), CaptureError> {
|
) -> Result<(), CaptureError> {
|
||||||
match ei_event {
|
match ei_event {
|
||||||
EiEvent::SeatAdded(s) => {
|
EiEvent::SeatAdded(s) => {
|
||||||
s.seat.bind_capabilities(&[
|
s.seat.bind_capabilities(ALL_CAPABILITIES);
|
||||||
DeviceCapability::Pointer,
|
|
||||||
DeviceCapability::PointerAbsolute,
|
|
||||||
DeviceCapability::Keyboard,
|
|
||||||
DeviceCapability::Touch,
|
|
||||||
DeviceCapability::Scroll,
|
|
||||||
DeviceCapability::Button,
|
|
||||||
]);
|
|
||||||
context.flush().map_err(|e| io::Error::new(e.kind(), e))?;
|
context.flush().map_err(|e| io::Error::new(e.kind(), e))?;
|
||||||
}
|
}
|
||||||
EiEvent::SeatRemoved(_) | /* EiEvent::DeviceAdded(_) | */ EiEvent::DeviceRemoved(_) => {
|
EiEvent::SeatRemoved(_) | /* EiEvent::DeviceAdded(_) | */ EiEvent::DeviceRemoved(_) => {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use tokio::task::JoinHandle;
|
|||||||
use ashpd::{
|
use ashpd::{
|
||||||
desktop::{
|
desktop::{
|
||||||
remote_desktop::{DeviceType, RemoteDesktop},
|
remote_desktop::{DeviceType, RemoteDesktop},
|
||||||
ResponseError,
|
ResponseError, Session,
|
||||||
},
|
},
|
||||||
WindowIdentifier,
|
WindowIdentifier,
|
||||||
};
|
};
|
||||||
@@ -60,30 +60,32 @@ struct Devices {
|
|||||||
keyboard: Arc<RwLock<Option<(ei::Device, ei::Keyboard)>>>,
|
keyboard: Arc<RwLock<Option<(ei::Device, ei::Keyboard)>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LibeiEmulation {
|
pub struct LibeiEmulation<'a> {
|
||||||
context: ei::Context,
|
context: ei::Context,
|
||||||
devices: Devices,
|
devices: Devices,
|
||||||
ei_task: JoinHandle<()>,
|
ei_task: JoinHandle<()>,
|
||||||
error: Arc<Mutex<Option<EmulationError>>>,
|
error: Arc<Mutex<Option<EmulationError>>>,
|
||||||
libei_error: Arc<AtomicBool>,
|
libei_error: Arc<AtomicBool>,
|
||||||
serial: AtomicU32,
|
serial: AtomicU32,
|
||||||
|
_remote_desktop: RemoteDesktop<'a>,
|
||||||
|
session: Session<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_ei_fd() -> Result<OwnedFd, ashpd::Error> {
|
async fn get_ei_fd<'a>() -> Result<(RemoteDesktop<'a>, Session<'a>, OwnedFd), ashpd::Error> {
|
||||||
let proxy = RemoteDesktop::new().await?;
|
let remote_desktop = RemoteDesktop::new().await?;
|
||||||
|
|
||||||
// retry when user presses the cancel button
|
// retry when user presses the cancel button
|
||||||
let (session, _) = loop {
|
let (session, _) = loop {
|
||||||
log::debug!("creating session ...");
|
log::debug!("creating session ...");
|
||||||
let session = proxy.create_session().await?;
|
let session = remote_desktop.create_session().await?;
|
||||||
|
|
||||||
log::debug!("selecting devices ...");
|
log::debug!("selecting devices ...");
|
||||||
proxy
|
remote_desktop
|
||||||
.select_devices(&session, DeviceType::Keyboard | DeviceType::Pointer)
|
.select_devices(&session, DeviceType::Keyboard | DeviceType::Pointer)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
log::info!("requesting permission for input emulation");
|
log::info!("requesting permission for input emulation");
|
||||||
match proxy
|
match remote_desktop
|
||||||
.start(&session, &WindowIdentifier::default())
|
.start(&session, &WindowIdentifier::default())
|
||||||
.await?
|
.await?
|
||||||
.response()
|
.response()
|
||||||
@@ -97,12 +99,13 @@ async fn get_ei_fd() -> Result<OwnedFd, ashpd::Error> {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
proxy.connect_to_eis(&session).await
|
let fd = remote_desktop.connect_to_eis(&session).await?;
|
||||||
|
Ok((remote_desktop, session, fd))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LibeiEmulation {
|
impl<'a> LibeiEmulation<'a> {
|
||||||
pub async fn new() -> Result<Self, LibeiEmulationCreationError> {
|
pub async fn new() -> Result<Self, LibeiEmulationCreationError> {
|
||||||
let eifd = get_ei_fd().await?;
|
let (remote_desktop, session, eifd) = get_ei_fd().await?;
|
||||||
let stream = UnixStream::from(eifd);
|
let stream = UnixStream::from(eifd);
|
||||||
stream.set_nonblocking(true)?;
|
stream.set_nonblocking(true)?;
|
||||||
let context = ei::Context::new(stream)?;
|
let context = ei::Context::new(stream)?;
|
||||||
@@ -136,18 +139,20 @@ impl LibeiEmulation {
|
|||||||
error,
|
error,
|
||||||
libei_error,
|
libei_error,
|
||||||
serial,
|
serial,
|
||||||
|
remote_desktop,
|
||||||
|
session,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for LibeiEmulation {
|
impl<'a> Drop for LibeiEmulation<'a> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.ei_task.abort();
|
self.ei_task.abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl InputEmulation for LibeiEmulation {
|
impl<'a> InputEmulation for LibeiEmulation<'a> {
|
||||||
async fn consume(
|
async fn consume(
|
||||||
&mut self,
|
&mut self,
|
||||||
event: Event,
|
event: Event,
|
||||||
@@ -247,8 +252,21 @@ impl InputEmulation for LibeiEmulation {
|
|||||||
async fn destroy(&mut self, _: EmulationHandle) {}
|
async fn destroy(&mut self, _: EmulationHandle) {}
|
||||||
|
|
||||||
async fn terminate(&mut self) {
|
async fn terminate(&mut self) {
|
||||||
|
if let Err(e) = self.session.close().await {
|
||||||
|
log::warn!("session.close(): {e}");
|
||||||
|
};
|
||||||
|
match self
|
||||||
|
.session
|
||||||
|
.receive_closed()
|
||||||
|
.await
|
||||||
|
.expect("could not receive closed")
|
||||||
|
.next()
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Some(c) => log::info!("session closed: {c:?}"),
|
||||||
|
None => log::warn!("session.receive_closed(): Unexpected EOF"),
|
||||||
|
};
|
||||||
self.ei_task.abort();
|
self.ei_task.abort();
|
||||||
/* FIXME */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user