seat: user data mechanism for Seat

This commit is contained in:
Victor Berger 2018-11-18 18:08:37 +01:00
parent 5e9ad96b0f
commit f1251a31e6
3 changed files with 51 additions and 31 deletions

View File

@ -12,6 +12,7 @@ members = [ "anvil" ]
[dependencies] [dependencies]
wayland-server = "0.21.1" wayland-server = "0.21.1"
wayland-sys = "0.21.1" wayland-sys = "0.21.1"
wayland-commons = "0.21.1"
nix = "0.11" nix = "0.11"
xkbcommon = "0.2.1" xkbcommon = "0.2.1"
tempfile = "2.1.5" tempfile = "2.1.5"

View File

@ -11,6 +11,7 @@ pub extern crate image;
#[cfg_attr(feature = "backend_session", macro_use)] #[cfg_attr(feature = "backend_session", macro_use)]
extern crate nix; extern crate nix;
extern crate tempfile; extern crate tempfile;
pub extern crate wayland_commons;
pub extern crate wayland_protocols; pub extern crate wayland_protocols;
pub extern crate wayland_server; pub extern crate wayland_server;
extern crate wayland_sys; extern crate wayland_sys;

View File

@ -64,19 +64,26 @@ pub use self::{
pointer::{AxisFrame, PointerGrab, PointerHandle, PointerInnerHandle}, pointer::{AxisFrame, PointerGrab, PointerHandle, PointerInnerHandle},
}; };
use wayland_commons::utils::UserDataMap;
use wayland_server::{ use wayland_server::{
protocol::{wl_seat, wl_surface}, protocol::{wl_seat, wl_surface},
Display, Global, NewResource, Resource, Display, Global, NewResource, Resource,
}; };
struct Inner { struct Inner {
log: ::slog::Logger,
name: String,
pointer: Option<PointerHandle>, pointer: Option<PointerHandle>,
keyboard: Option<KeyboardHandle>, keyboard: Option<KeyboardHandle>,
known_seats: Vec<Resource<wl_seat::WlSeat>>, known_seats: Vec<Resource<wl_seat::WlSeat>>,
} }
struct SeatArc {
inner: Mutex<Inner>,
user_data: UserDataMap,
log: ::slog::Logger,
name: String,
}
impl Inner { impl Inner {
fn compute_caps(&self) -> wl_seat::Capability { fn compute_caps(&self) -> wl_seat::Capability {
let mut caps = wl_seat::Capability::empty(); let mut caps = wl_seat::Capability::empty();
@ -110,7 +117,7 @@ impl Inner {
/// See module-level documentation for details of use. /// See module-level documentation for details of use.
#[derive(Clone)] #[derive(Clone)]
pub struct Seat { pub struct Seat {
inner: Arc<Mutex<Inner>>, arc: Arc<SeatArc>,
} }
impl Seat { impl Seat {
@ -127,20 +134,23 @@ impl Seat {
L: Into<Option<::slog::Logger>>, L: Into<Option<::slog::Logger>>,
{ {
let log = ::slog_or_stdlog(logger); let log = ::slog_or_stdlog(logger);
let inner = Arc::new(Mutex::new(Inner { let arc = Arc::new(SeatArc {
inner: Mutex::new(Inner {
pointer: None,
keyboard: None,
known_seats: Vec::new(),
}),
log: log.new(o!("smithay_module" => "seat_handler", "seat_name" => name.clone())), log: log.new(o!("smithay_module" => "seat_handler", "seat_name" => name.clone())),
name, name,
pointer: None, user_data: UserDataMap::new(),
keyboard: None, });
known_seats: Vec::new(), let seat = Seat { arc: arc.clone() };
}));
let seat = Seat { inner: inner.clone() };
let global = display.create_global(5, move |new_seat, _version| { let global = display.create_global(5, move |new_seat, _version| {
let seat = implement_seat(new_seat, inner.clone()); let seat = implement_seat(new_seat, arc.clone());
let mut inner = inner.lock().unwrap(); let mut inner = arc.inner.lock().unwrap();
if seat.version() >= 2 { if seat.version() >= 2 {
seat.send(wl_seat::Event::Name { seat.send(wl_seat::Event::Name {
name: inner.name.clone(), name: arc.name.clone(),
}); });
} }
seat.send(wl_seat::Event::Capabilities { seat.send(wl_seat::Event::Capabilities {
@ -153,9 +163,12 @@ impl Seat {
/// Attempt to retrieve a `Seat` from an existing resource /// Attempt to retrieve a `Seat` from an existing resource
pub fn from_resource(seat: &Resource<wl_seat::WlSeat>) -> Option<Seat> { pub fn from_resource(seat: &Resource<wl_seat::WlSeat>) -> Option<Seat> {
seat.user_data::<Arc<Mutex<Inner>>>() seat.user_data::<Arc<SeatArc>>().cloned().map(|arc| Seat { arc })
.cloned() }
.map(|inner| Seat { inner })
/// Acces the `UserDataMap` associated with this `Seat`
pub fn user_data(&self) -> &UserDataMap {
&self.arc.user_data
} }
/// Adds the pointer capability to this seat /// Adds the pointer capability to this seat
@ -167,7 +180,7 @@ impl Seat {
/// will overwrite it, and will be seen by the clients as if the /// will overwrite it, and will be seen by the clients as if the
/// mouse was unplugged and a new one was plugged. /// mouse was unplugged and a new one was plugged.
pub fn add_pointer(&mut self) -> PointerHandle { pub fn add_pointer(&mut self) -> PointerHandle {
let mut inner = self.inner.lock().unwrap(); let mut inner = self.arc.inner.lock().unwrap();
let pointer = self::pointer::create_pointer_handler(); let pointer = self::pointer::create_pointer_handler();
if inner.pointer.is_some() { if inner.pointer.is_some() {
// there is already a pointer, remove it and notify the clients // there is already a pointer, remove it and notify the clients
@ -182,14 +195,14 @@ impl Seat {
/// Access the pointer of this seat if any /// Access the pointer of this seat if any
pub fn get_pointer(&self) -> Option<PointerHandle> { pub fn get_pointer(&self) -> Option<PointerHandle> {
self.inner.lock().unwrap().pointer.clone() self.arc.inner.lock().unwrap().pointer.clone()
} }
/// Remove the pointer capability from this seat /// Remove the pointer capability from this seat
/// ///
/// Clients will be appropriately notified. /// Clients will be appropriately notified.
pub fn remove_pointer(&mut self) { pub fn remove_pointer(&mut self) {
let mut inner = self.inner.lock().unwrap(); let mut inner = self.arc.inner.lock().unwrap();
if inner.pointer.is_some() { if inner.pointer.is_some() {
inner.pointer = None; inner.pointer = None;
inner.send_all_caps(); inner.send_all_caps();
@ -242,12 +255,12 @@ impl Seat {
F: FnMut(&Seat, Option<&Resource<wl_surface::WlSurface>>) + 'static, F: FnMut(&Seat, Option<&Resource<wl_surface::WlSurface>>) + 'static,
{ {
let me = self.clone(); let me = self.clone();
let mut inner = self.inner.lock().unwrap(); let mut inner = self.arc.inner.lock().unwrap();
let keyboard = self::keyboard::create_keyboard_handler( let keyboard = self::keyboard::create_keyboard_handler(
xkb_config, xkb_config,
repeat_delay, repeat_delay,
repeat_rate, repeat_rate,
&inner.log, &self.arc.log,
move |focus| focus_hook(&me, focus), move |focus| focus_hook(&me, focus),
)?; )?;
if inner.keyboard.is_some() { if inner.keyboard.is_some() {
@ -263,14 +276,14 @@ impl Seat {
/// Access the keyboard of this seat if any /// Access the keyboard of this seat if any
pub fn get_keyboard(&self) -> Option<KeyboardHandle> { pub fn get_keyboard(&self) -> Option<KeyboardHandle> {
self.inner.lock().unwrap().keyboard.clone() self.arc.inner.lock().unwrap().keyboard.clone()
} }
/// Remove the keyboard capability from this seat /// Remove the keyboard capability from this seat
/// ///
/// Clients will be appropriately notified. /// Clients will be appropriately notified.
pub fn remove_keyboard(&mut self) { pub fn remove_keyboard(&mut self) {
let mut inner = self.inner.lock().unwrap(); let mut inner = self.arc.inner.lock().unwrap();
if inner.keyboard.is_some() { if inner.keyboard.is_some() {
inner.keyboard = None; inner.keyboard = None;
inner.send_all_caps(); inner.send_all_caps();
@ -279,19 +292,23 @@ impl Seat {
/// Checks whether a given `WlSeat` is associated with this `Seat` /// Checks whether a given `WlSeat` is associated with this `Seat`
pub fn owns(&self, seat: &Resource<wl_seat::WlSeat>) -> bool { pub fn owns(&self, seat: &Resource<wl_seat::WlSeat>) -> bool {
let inner = self.inner.lock().unwrap(); let inner = self.arc.inner.lock().unwrap();
inner.known_seats.iter().any(|s| s.equals(seat)) inner.known_seats.iter().any(|s| s.equals(seat))
} }
} }
fn implement_seat( impl ::std::cmp::PartialEq for Seat {
new_seat: NewResource<wl_seat::WlSeat>, fn eq(&self, other: &Seat) -> bool {
inner: Arc<Mutex<Inner>>, Arc::ptr_eq(&self.arc, &other.arc)
) -> Resource<wl_seat::WlSeat> { }
let dest_inner = inner.clone(); }
fn implement_seat(new_seat: NewResource<wl_seat::WlSeat>, arc: Arc<SeatArc>) -> Resource<wl_seat::WlSeat> {
let dest_arc = arc.clone();
new_seat.implement( new_seat.implement(
move |request, seat| { move |request, seat| {
let inner = seat.user_data::<Arc<Mutex<Inner>>>().unwrap().lock().unwrap(); let arc = seat.user_data::<Arc<SeatArc>>().unwrap();
let inner = arc.inner.lock().unwrap();
match request { match request {
wl_seat::Request::GetPointer { id } => { wl_seat::Request::GetPointer { id } => {
let pointer = self::pointer::implement_pointer(id, inner.pointer.as_ref()); let pointer = self::pointer::implement_pointer(id, inner.pointer.as_ref());
@ -319,12 +336,13 @@ fn implement_seat(
} }
}, },
Some(move |seat| { Some(move |seat| {
dest_inner dest_arc
.inner
.lock() .lock()
.unwrap() .unwrap()
.known_seats .known_seats
.retain(|s| !s.equals(&seat)); .retain(|s| !s.equals(&seat));
}), }),
inner, arc,
) )
} }