impl session close

This commit is contained in:
Ferdinand Schober
2024-07-12 11:35:21 +02:00
parent 621d9eac59
commit 8de738e597
2 changed files with 48 additions and 27 deletions

View File

@@ -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(_) => {

View File

@@ -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 */
}
}