mirror of
https://github.com/feschber/lan-mouse.git
synced 2026-03-07 11:59:59 +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
|
||||
* 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
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
@@ -79,14 +79,15 @@ static INTERFACES: Lazy<HashMap<&'static str, u32>> = Lazy::new(|| {
|
||||
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());
|
||||
let (width, height) = (r.width() as i32, r.height() as i32);
|
||||
let (w, h) = (r.width() as i32, r.height() as i32);
|
||||
match pos {
|
||||
Position::Left => (x, y, x, y + height - 1), // start pos, end pos, inclusive
|
||||
Position::Right => (x + width, y, x + width, y + height - 1),
|
||||
Position::Top => (x, y, x + width - 1, y),
|
||||
Position::Bottom => (x, y + height, x + width - 1, y + height),
|
||||
Position::Left => (x, y, x, y + h - 1),
|
||||
Position::Right => (x + w, y, x + w, y + h - 1),
|
||||
Position::Top => (x, y, x + w - 1, y),
|
||||
Position::Bottom => (x, y + h, x + w - 1, y + h),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -487,6 +488,15 @@ async fn release_capture(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
static ALL_CAPABILITIES: &[DeviceCapability] = &[
|
||||
DeviceCapability::Pointer,
|
||||
DeviceCapability::PointerAbsolute,
|
||||
DeviceCapability::Keyboard,
|
||||
DeviceCapability::Touch,
|
||||
DeviceCapability::Scroll,
|
||||
DeviceCapability::Button,
|
||||
];
|
||||
|
||||
async fn handle_ei_event(
|
||||
ei_event: EiEvent,
|
||||
current_client: Option<CaptureHandle>,
|
||||
@@ -496,14 +506,7 @@ async fn handle_ei_event(
|
||||
) -> Result<(), CaptureError> {
|
||||
match ei_event {
|
||||
EiEvent::SeatAdded(s) => {
|
||||
s.seat.bind_capabilities(&[
|
||||
DeviceCapability::Pointer,
|
||||
DeviceCapability::PointerAbsolute,
|
||||
DeviceCapability::Keyboard,
|
||||
DeviceCapability::Touch,
|
||||
DeviceCapability::Scroll,
|
||||
DeviceCapability::Button,
|
||||
]);
|
||||
s.seat.bind_capabilities(ALL_CAPABILITIES);
|
||||
context.flush().map_err(|e| io::Error::new(e.kind(), e))?;
|
||||
}
|
||||
EiEvent::SeatRemoved(_) | /* EiEvent::DeviceAdded(_) | */ EiEvent::DeviceRemoved(_) => {
|
||||
|
||||
@@ -15,7 +15,7 @@ use tokio::task::JoinHandle;
|
||||
use ashpd::{
|
||||
desktop::{
|
||||
remote_desktop::{DeviceType, RemoteDesktop},
|
||||
ResponseError,
|
||||
ResponseError, Session,
|
||||
},
|
||||
WindowIdentifier,
|
||||
};
|
||||
@@ -60,30 +60,32 @@ struct Devices {
|
||||
keyboard: Arc<RwLock<Option<(ei::Device, ei::Keyboard)>>>,
|
||||
}
|
||||
|
||||
pub struct LibeiEmulation {
|
||||
pub struct LibeiEmulation<'a> {
|
||||
context: ei::Context,
|
||||
devices: Devices,
|
||||
ei_task: JoinHandle<()>,
|
||||
error: Arc<Mutex<Option<EmulationError>>>,
|
||||
libei_error: Arc<AtomicBool>,
|
||||
serial: AtomicU32,
|
||||
_remote_desktop: RemoteDesktop<'a>,
|
||||
session: Session<'a>,
|
||||
}
|
||||
|
||||
async fn get_ei_fd() -> Result<OwnedFd, ashpd::Error> {
|
||||
let proxy = RemoteDesktop::new().await?;
|
||||
async fn get_ei_fd<'a>() -> Result<(RemoteDesktop<'a>, Session<'a>, OwnedFd), ashpd::Error> {
|
||||
let remote_desktop = RemoteDesktop::new().await?;
|
||||
|
||||
// retry when user presses the cancel button
|
||||
let (session, _) = loop {
|
||||
log::debug!("creating session ...");
|
||||
let session = proxy.create_session().await?;
|
||||
let session = remote_desktop.create_session().await?;
|
||||
|
||||
log::debug!("selecting devices ...");
|
||||
proxy
|
||||
remote_desktop
|
||||
.select_devices(&session, DeviceType::Keyboard | DeviceType::Pointer)
|
||||
.await?;
|
||||
|
||||
log::info!("requesting permission for input emulation");
|
||||
match proxy
|
||||
match remote_desktop
|
||||
.start(&session, &WindowIdentifier::default())
|
||||
.await?
|
||||
.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> {
|
||||
let eifd = get_ei_fd().await?;
|
||||
let (remote_desktop, session, eifd) = get_ei_fd().await?;
|
||||
let stream = UnixStream::from(eifd);
|
||||
stream.set_nonblocking(true)?;
|
||||
let context = ei::Context::new(stream)?;
|
||||
@@ -136,18 +139,20 @@ impl LibeiEmulation {
|
||||
error,
|
||||
libei_error,
|
||||
serial,
|
||||
remote_desktop,
|
||||
session,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for LibeiEmulation {
|
||||
impl<'a> Drop for LibeiEmulation<'a> {
|
||||
fn drop(&mut self) {
|
||||
self.ei_task.abort();
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl InputEmulation for LibeiEmulation {
|
||||
impl<'a> InputEmulation for LibeiEmulation<'a> {
|
||||
async fn consume(
|
||||
&mut self,
|
||||
event: Event,
|
||||
@@ -247,8 +252,21 @@ impl InputEmulation for LibeiEmulation {
|
||||
async fn destroy(&mut self, _: EmulationHandle) {}
|
||||
|
||||
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();
|
||||
/* FIXME */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user