Return the backends to the user if binding fails.
This commit is contained in:
parent
7f8d32429b
commit
bd08f78acd
|
@ -6,11 +6,14 @@ use backend::input::Axis;
|
||||||
use backend::session::{AsErrno, Session, SessionObserver};
|
use backend::session::{AsErrno, Session, SessionObserver};
|
||||||
use input as libinput;
|
use input as libinput;
|
||||||
use input::event;
|
use input::event;
|
||||||
|
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::collections::hash_map::{DefaultHasher, Entry, HashMap};
|
use std::collections::hash_map::{DefaultHasher, Entry, HashMap};
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::io::Error as IoError;
|
use std::io::Error as IoError;
|
||||||
use std::os::unix::io::RawFd;
|
use std::os::unix::io::RawFd;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
use wayland_server::calloop::generic::{EventedRawFd, Generic};
|
use wayland_server::calloop::generic::{EventedRawFd, Generic};
|
||||||
use wayland_server::calloop::{LoopHandle, Ready, Source};
|
use wayland_server::calloop::{LoopHandle, Ready, Source};
|
||||||
|
@ -588,15 +591,24 @@ impl<S: Session> libinput::LibinputInterface for LibinputSessionInterface<S> {
|
||||||
/// Automatically feeds the backend with incoming events without any manual calls to
|
/// Automatically feeds the backend with incoming events without any manual calls to
|
||||||
/// `dispatch_new_events`. Should be used to achieve the smallest possible latency.
|
/// `dispatch_new_events`. Should be used to achieve the smallest possible latency.
|
||||||
pub fn libinput_bind<Data: 'static>(
|
pub fn libinput_bind<Data: 'static>(
|
||||||
mut backend: LibinputInputBackend,
|
backend: LibinputInputBackend,
|
||||||
handle: LoopHandle<Data>,
|
handle: LoopHandle<Data>,
|
||||||
) -> ::std::result::Result<Source<Generic<EventedRawFd>>, IoError> {
|
) -> ::std::result::Result<Source<Generic<EventedRawFd>>, (IoError, LibinputInputBackend)> {
|
||||||
let mut source = Generic::from_raw_fd(unsafe { backend.context.fd() });
|
let mut source = Generic::from_raw_fd(unsafe { backend.context.fd() });
|
||||||
source.set_interest(Ready::readable());
|
source.set_interest(Ready::readable());
|
||||||
handle.insert_source(source, move |_, _| {
|
let backend = Rc::new(RefCell::new(backend));
|
||||||
|
let fail_backend = backend.clone();
|
||||||
|
handle
|
||||||
|
.insert_source(source, move |_, _| {
|
||||||
use backend::input::InputBackend;
|
use backend::input::InputBackend;
|
||||||
if let Err(error) = backend.dispatch_new_events() {
|
if let Err(error) = backend.borrow_mut().dispatch_new_events() {
|
||||||
warn!(backend.logger, "Libinput errored: {}", error);
|
warn!(backend.borrow().logger, "Libinput errored: {}", error);
|
||||||
}
|
}
|
||||||
|
}).map_err(move |e| {
|
||||||
|
// the backend in the closure should already have been dropped
|
||||||
|
let backend = Rc::try_unwrap(fail_backend)
|
||||||
|
.unwrap_or_else(|_| unreachable!())
|
||||||
|
.into_inner();
|
||||||
|
(e, backend)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,13 +148,15 @@ impl AutoSession {
|
||||||
pub fn auto_session_bind<Data: 'static>(
|
pub fn auto_session_bind<Data: 'static>(
|
||||||
notifier: AutoSessionNotifier,
|
notifier: AutoSessionNotifier,
|
||||||
handle: &LoopHandle<Data>,
|
handle: &LoopHandle<Data>,
|
||||||
) -> ::std::result::Result<BoundAutoSession, IoError> {
|
) -> ::std::result::Result<BoundAutoSession, (IoError, AutoSessionNotifier)> {
|
||||||
Ok(match notifier {
|
Ok(match notifier {
|
||||||
#[cfg(feature = "backend_session_logind")]
|
#[cfg(feature = "backend_session_logind")]
|
||||||
AutoSessionNotifier::Logind(logind) => {
|
AutoSessionNotifier::Logind(logind) => BoundAutoSession::Logind(
|
||||||
BoundAutoSession::Logind(logind_session_bind(logind, handle).map_err(|(e, _)| e)?)
|
logind_session_bind(logind, handle).map_err(|(e, n)| (e, AutoSessionNotifier::Logind(n)))?,
|
||||||
}
|
),
|
||||||
AutoSessionNotifier::Direct(direct) => BoundAutoSession::Direct(direct_session_bind(direct, handle)?),
|
AutoSessionNotifier::Direct(direct) => BoundAutoSession::Direct(
|
||||||
|
direct_session_bind(direct, handle).map_err(|(e, n)| (e, AutoSessionNotifier::Direct(n)))?,
|
||||||
|
),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -420,12 +420,24 @@ impl BoundDirectSession {
|
||||||
pub fn direct_session_bind<Data: 'static>(
|
pub fn direct_session_bind<Data: 'static>(
|
||||||
notifier: DirectSessionNotifier,
|
notifier: DirectSessionNotifier,
|
||||||
handle: &LoopHandle<Data>,
|
handle: &LoopHandle<Data>,
|
||||||
) -> ::std::result::Result<BoundDirectSession, IoError> {
|
) -> ::std::result::Result<BoundDirectSession, (IoError, DirectSessionNotifier)> {
|
||||||
let signal = notifier.signal;
|
let signal = notifier.signal;
|
||||||
|
let source = match Signals::new(&[signal]) {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(e) => return Err((e, notifier)),
|
||||||
|
};
|
||||||
let notifier = Rc::new(RefCell::new(notifier));
|
let notifier = Rc::new(RefCell::new(notifier));
|
||||||
let source = handle.insert_source(Signals::new(&[signal])?, {
|
let fail_notifier = notifier.clone();
|
||||||
|
let source = handle
|
||||||
|
.insert_source(source, {
|
||||||
let notifier = notifier.clone();
|
let notifier = notifier.clone();
|
||||||
move |_, _| notifier.borrow_mut().signal_received()
|
move |_, _| notifier.borrow_mut().signal_received()
|
||||||
|
}).map_err(move |e| {
|
||||||
|
// the backend in the closure should already have been dropped
|
||||||
|
let notifier = Rc::try_unwrap(fail_notifier)
|
||||||
|
.unwrap_or_else(|_| unreachable!())
|
||||||
|
.into_inner();
|
||||||
|
(e, notifier)
|
||||||
})?;
|
})?;
|
||||||
Ok(BoundDirectSession { source, notifier })
|
Ok(BoundDirectSession { source, notifier })
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue