seat: user data mechanism for Seat
This commit is contained in:
parent
5e9ad96b0f
commit
f1251a31e6
|
@ -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"
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 {
|
||||||
log: log.new(o!("smithay_module" => "seat_handler", "seat_name" => name.clone())),
|
inner: Mutex::new(Inner {
|
||||||
name,
|
|
||||||
pointer: None,
|
pointer: None,
|
||||||
keyboard: None,
|
keyboard: None,
|
||||||
known_seats: Vec::new(),
|
known_seats: Vec::new(),
|
||||||
}));
|
}),
|
||||||
let seat = Seat { inner: inner.clone() };
|
log: log.new(o!("smithay_module" => "seat_handler", "seat_name" => name.clone())),
|
||||||
|
name,
|
||||||
|
user_data: UserDataMap::new(),
|
||||||
|
});
|
||||||
|
let seat = Seat { arc: arc.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,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue