wayland.seat: migrate to wayland_rs-0.20
This commit is contained in:
parent
93050e2683
commit
e44b0e596e
|
@ -2,7 +2,6 @@
|
|||
|
||||
use std::error::Error;
|
||||
use std::string::ToString;
|
||||
use wayland_server::EventLoopHandle;
|
||||
|
||||
/// A seat describes a group of input devices and at least one
|
||||
/// graphics device belonging together.
|
||||
|
@ -521,31 +520,31 @@ pub trait InputBackend: Sized {
|
|||
type TouchFrameEvent: TouchFrameEvent;
|
||||
|
||||
/// Sets a new handler for this `InputBackend`
|
||||
fn set_handler<H: InputHandler<Self> + 'static>(&mut self, evlh: &mut EventLoopHandle, handler: H);
|
||||
fn set_handler<H: InputHandler<Self> + 'static>(&mut self, handler: H);
|
||||
/// Get a reference to the currently set handler, if any
|
||||
fn get_handler(&mut self) -> Option<&mut InputHandler<Self>>;
|
||||
/// Clears the currently handler, if one is set
|
||||
fn clear_handler(&mut self, evlh: &mut EventLoopHandle);
|
||||
fn clear_handler(&mut self);
|
||||
|
||||
/// Get current `InputConfig`
|
||||
fn input_config(&mut self) -> &mut Self::InputConfig;
|
||||
|
||||
/// Processes new events of the underlying backend and drives the `InputHandler`.
|
||||
fn dispatch_new_events(&mut self, evlh: &mut EventLoopHandle) -> Result<(), Self::EventError>;
|
||||
fn dispatch_new_events(&mut self) -> Result<(), Self::EventError>;
|
||||
}
|
||||
|
||||
/// Implement to receive input events from any `InputBackend`.
|
||||
pub trait InputHandler<B: InputBackend> {
|
||||
/// Called when a new `Seat` has been created
|
||||
fn on_seat_created(&mut self, evlh: &mut EventLoopHandle, seat: &Seat);
|
||||
fn on_seat_created(&mut self, seat: &Seat);
|
||||
/// Called when an existing `Seat` has been destroyed.
|
||||
fn on_seat_destroyed(&mut self, evlh: &mut EventLoopHandle, seat: &Seat);
|
||||
fn on_seat_destroyed(&mut self, seat: &Seat);
|
||||
/// Called when a `Seat`'s properties have changed.
|
||||
///
|
||||
/// ## Note:
|
||||
///
|
||||
/// It is not guaranteed that any change has actually happened.
|
||||
fn on_seat_changed(&mut self, evlh: &mut EventLoopHandle, seat: &Seat);
|
||||
fn on_seat_changed(&mut self, seat: &Seat);
|
||||
|
||||
/// Called when a new keyboard event was received.
|
||||
///
|
||||
|
@ -554,7 +553,7 @@ pub trait InputHandler<B: InputBackend> {
|
|||
/// - `seat` - The `Seat` the event belongs to
|
||||
/// - `event` - The keyboard event
|
||||
///
|
||||
fn on_keyboard_key(&mut self, evlh: &mut EventLoopHandle, seat: &Seat, event: B::KeyboardKeyEvent);
|
||||
fn on_keyboard_key(&mut self, seat: &Seat, event: B::KeyboardKeyEvent);
|
||||
|
||||
/// Called when a new pointer movement event was received.
|
||||
///
|
||||
|
@ -562,30 +561,28 @@ pub trait InputHandler<B: InputBackend> {
|
|||
///
|
||||
/// - `seat` - The `Seat` the event belongs to
|
||||
/// - `event` - The pointer movement event
|
||||
fn on_pointer_move(&mut self, evlh: &mut EventLoopHandle, seat: &Seat, event: B::PointerMotionEvent);
|
||||
fn on_pointer_move(&mut self, seat: &Seat, event: B::PointerMotionEvent);
|
||||
/// Called when a new pointer absolute movement event was received.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `seat` - The `Seat` the event belongs to
|
||||
/// - `event` - The pointer absolute movement event
|
||||
fn on_pointer_move_absolute(
|
||||
&mut self, evlh: &mut EventLoopHandle, seat: &Seat, event: B::PointerMotionAbsoluteEvent
|
||||
);
|
||||
fn on_pointer_move_absolute(&mut self, seat: &Seat, event: B::PointerMotionAbsoluteEvent);
|
||||
/// Called when a new pointer button event was received.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `seat` - The `Seat` the event belongs to
|
||||
/// - `event` - The pointer button event
|
||||
fn on_pointer_button(&mut self, evlh: &mut EventLoopHandle, seat: &Seat, event: B::PointerButtonEvent);
|
||||
fn on_pointer_button(&mut self, seat: &Seat, event: B::PointerButtonEvent);
|
||||
/// Called when a new pointer scroll event was received.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `seat` - The `Seat` the event belongs to
|
||||
/// - `event` - A upward counting variable useful for event ordering. Makes no gurantees about actual time passed between events.
|
||||
fn on_pointer_axis(&mut self, evlh: &mut EventLoopHandle, seat: &Seat, event: B::PointerAxisEvent);
|
||||
fn on_pointer_axis(&mut self, seat: &Seat, event: B::PointerAxisEvent);
|
||||
|
||||
/// Called when a new touch down event was received.
|
||||
///
|
||||
|
@ -593,99 +590,97 @@ pub trait InputHandler<B: InputBackend> {
|
|||
///
|
||||
/// - `seat` - The `Seat` the event belongs to
|
||||
/// - `event` - The touch down event
|
||||
fn on_touch_down(&mut self, evlh: &mut EventLoopHandle, seat: &Seat, event: B::TouchDownEvent);
|
||||
fn on_touch_down(&mut self, seat: &Seat, event: B::TouchDownEvent);
|
||||
/// Called when a new touch motion event was received.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `seat` - The `Seat` the event belongs to
|
||||
/// - `event` - The touch motion event.
|
||||
fn on_touch_motion(&mut self, evlh: &mut EventLoopHandle, seat: &Seat, event: B::TouchMotionEvent);
|
||||
fn on_touch_motion(&mut self, seat: &Seat, event: B::TouchMotionEvent);
|
||||
/// Called when a new touch up event was received.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `seat` - The `Seat` the event belongs to
|
||||
/// - `event` - The touch up event.
|
||||
fn on_touch_up(&mut self, evlh: &mut EventLoopHandle, seat: &Seat, event: B::TouchUpEvent);
|
||||
fn on_touch_up(&mut self, seat: &Seat, event: B::TouchUpEvent);
|
||||
/// Called when a new touch cancel event was received.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `seat` - The `Seat` the event belongs to
|
||||
/// - `event` - The touch cancel event.
|
||||
fn on_touch_cancel(&mut self, evlh: &mut EventLoopHandle, seat: &Seat, event: B::TouchCancelEvent);
|
||||
fn on_touch_cancel(&mut self, seat: &Seat, event: B::TouchCancelEvent);
|
||||
/// Called when a new touch frame event was received.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `seat` - The `Seat` the event belongs to
|
||||
/// - `event` - The touch frame event.
|
||||
fn on_touch_frame(&mut self, evlh: &mut EventLoopHandle, seat: &Seat, event: B::TouchFrameEvent);
|
||||
fn on_touch_frame(&mut self, seat: &Seat, event: B::TouchFrameEvent);
|
||||
|
||||
/// Called when the `InputConfig` was changed through an external event.
|
||||
///
|
||||
/// What kind of events can trigger this call is completely backend dependent.
|
||||
/// E.g. an input devices was attached/detached or changed it's own configuration.
|
||||
fn on_input_config_changed(&mut self, evlh: &mut EventLoopHandle, config: &mut B::InputConfig);
|
||||
fn on_input_config_changed(&mut self, config: &mut B::InputConfig);
|
||||
}
|
||||
|
||||
impl<B: InputBackend> InputHandler<B> for Box<InputHandler<B>> {
|
||||
fn on_seat_created(&mut self, evlh: &mut EventLoopHandle, seat: &Seat) {
|
||||
(**self).on_seat_created(evlh, seat)
|
||||
fn on_seat_created(&mut self, seat: &Seat) {
|
||||
(**self).on_seat_created(seat)
|
||||
}
|
||||
|
||||
fn on_seat_destroyed(&mut self, evlh: &mut EventLoopHandle, seat: &Seat) {
|
||||
(**self).on_seat_destroyed(evlh, seat)
|
||||
fn on_seat_destroyed(&mut self, seat: &Seat) {
|
||||
(**self).on_seat_destroyed(seat)
|
||||
}
|
||||
|
||||
fn on_seat_changed(&mut self, evlh: &mut EventLoopHandle, seat: &Seat) {
|
||||
(**self).on_seat_changed(evlh, seat)
|
||||
fn on_seat_changed(&mut self, seat: &Seat) {
|
||||
(**self).on_seat_changed(seat)
|
||||
}
|
||||
|
||||
fn on_keyboard_key(&mut self, evlh: &mut EventLoopHandle, seat: &Seat, event: B::KeyboardKeyEvent) {
|
||||
(**self).on_keyboard_key(evlh, seat, event)
|
||||
fn on_keyboard_key(&mut self, seat: &Seat, event: B::KeyboardKeyEvent) {
|
||||
(**self).on_keyboard_key(seat, event)
|
||||
}
|
||||
|
||||
fn on_pointer_move(&mut self, evlh: &mut EventLoopHandle, seat: &Seat, event: B::PointerMotionEvent) {
|
||||
(**self).on_pointer_move(evlh, seat, event)
|
||||
fn on_pointer_move(&mut self, seat: &Seat, event: B::PointerMotionEvent) {
|
||||
(**self).on_pointer_move(seat, event)
|
||||
}
|
||||
|
||||
fn on_pointer_move_absolute(
|
||||
&mut self, evlh: &mut EventLoopHandle, seat: &Seat, event: B::PointerMotionAbsoluteEvent
|
||||
) {
|
||||
(**self).on_pointer_move_absolute(evlh, seat, event)
|
||||
fn on_pointer_move_absolute(&mut self, seat: &Seat, event: B::PointerMotionAbsoluteEvent) {
|
||||
(**self).on_pointer_move_absolute(seat, event)
|
||||
}
|
||||
|
||||
fn on_pointer_button(&mut self, evlh: &mut EventLoopHandle, seat: &Seat, event: B::PointerButtonEvent) {
|
||||
(**self).on_pointer_button(evlh, seat, event)
|
||||
fn on_pointer_button(&mut self, seat: &Seat, event: B::PointerButtonEvent) {
|
||||
(**self).on_pointer_button(seat, event)
|
||||
}
|
||||
|
||||
fn on_pointer_axis(&mut self, evlh: &mut EventLoopHandle, seat: &Seat, event: B::PointerAxisEvent) {
|
||||
(**self).on_pointer_axis(evlh, seat, event)
|
||||
fn on_pointer_axis(&mut self, seat: &Seat, event: B::PointerAxisEvent) {
|
||||
(**self).on_pointer_axis(seat, event)
|
||||
}
|
||||
|
||||
fn on_touch_down(&mut self, evlh: &mut EventLoopHandle, seat: &Seat, event: B::TouchDownEvent) {
|
||||
(**self).on_touch_down(evlh, seat, event)
|
||||
fn on_touch_down(&mut self, seat: &Seat, event: B::TouchDownEvent) {
|
||||
(**self).on_touch_down(seat, event)
|
||||
}
|
||||
|
||||
fn on_touch_motion(&mut self, evlh: &mut EventLoopHandle, seat: &Seat, event: B::TouchMotionEvent) {
|
||||
(**self).on_touch_motion(evlh, seat, event)
|
||||
fn on_touch_motion(&mut self, seat: &Seat, event: B::TouchMotionEvent) {
|
||||
(**self).on_touch_motion(seat, event)
|
||||
}
|
||||
|
||||
fn on_touch_up(&mut self, evlh: &mut EventLoopHandle, seat: &Seat, event: B::TouchUpEvent) {
|
||||
(**self).on_touch_up(evlh, seat, event)
|
||||
fn on_touch_up(&mut self, seat: &Seat, event: B::TouchUpEvent) {
|
||||
(**self).on_touch_up(seat, event)
|
||||
}
|
||||
|
||||
fn on_touch_cancel(&mut self, evlh: &mut EventLoopHandle, seat: &Seat, event: B::TouchCancelEvent) {
|
||||
(**self).on_touch_cancel(evlh, seat, event)
|
||||
fn on_touch_cancel(&mut self, seat: &Seat, event: B::TouchCancelEvent) {
|
||||
(**self).on_touch_cancel(seat, event)
|
||||
}
|
||||
|
||||
fn on_touch_frame(&mut self, evlh: &mut EventLoopHandle, seat: &Seat, event: B::TouchFrameEvent) {
|
||||
(**self).on_touch_frame(evlh, seat, event)
|
||||
fn on_touch_frame(&mut self, seat: &Seat, event: B::TouchFrameEvent) {
|
||||
(**self).on_touch_frame(seat, event)
|
||||
}
|
||||
|
||||
fn on_input_config_changed(&mut self, evlh: &mut EventLoopHandle, config: &mut B::InputConfig) {
|
||||
(**self).on_input_config_changed(evlh, config)
|
||||
fn on_input_config_changed(&mut self, config: &mut B::InputConfig) {
|
||||
(**self).on_input_config_changed(config)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,15 +15,15 @@
|
|||
//! - libinput
|
||||
|
||||
pub mod input;
|
||||
pub mod graphics;
|
||||
//pub mod graphics;
|
||||
|
||||
#[cfg(feature = "backend_winit")]
|
||||
pub mod winit;
|
||||
#[cfg(feature = "backend_drm")]
|
||||
pub mod drm;
|
||||
#[cfg(feature = "backend_libinput")]
|
||||
pub mod libinput;
|
||||
#[cfg(feature = "backend_session")]
|
||||
pub mod session;
|
||||
#[cfg(feature = "backend_udev")]
|
||||
pub mod udev;
|
||||
//#[cfg(feature = "backend_winit")]
|
||||
//pub mod winit;
|
||||
//#[cfg(feature = "backend_drm")]
|
||||
//pub mod drm;
|
||||
//#[cfg(feature = "backend_libinput")]
|
||||
//pub mod libinput;
|
||||
//#[cfg(feature = "backend_session")]
|
||||
//pub mod session;
|
||||
//#[cfg(feature = "backend_udev")]
|
||||
//pub mod udev;
|
||||
|
|
|
@ -48,7 +48,7 @@ extern crate error_chain;
|
|||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
||||
//pub mod backend;
|
||||
pub mod backend;
|
||||
pub mod wayland;
|
||||
pub mod utils;
|
||||
|
||||
|
|
|
@ -20,6 +20,6 @@
|
|||
|
||||
//pub mod compositor;
|
||||
pub mod output;
|
||||
//pub mod seat;
|
||||
pub mod seat;
|
||||
pub mod shm;
|
||||
//pub mod shell;
|
||||
|
|
|
@ -3,8 +3,9 @@ use std::io::{Error as IoError, Write};
|
|||
use std::os::unix::io::AsRawFd;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use tempfile::tempfile;
|
||||
use wayland_server::{Liveness, Resource};
|
||||
use wayland_server::protocol::{wl_keyboard, wl_surface};
|
||||
use wayland_server::{NewResource, Resource};
|
||||
use wayland_server::protocol::wl_surface::WlSurface;
|
||||
use wayland_server::protocol::wl_keyboard::{Event, KeyState as WlKeyState, KeymapFormat, Request, WlKeyboard};
|
||||
use xkbcommon::xkb;
|
||||
pub use xkbcommon::xkb::{keysyms, Keysym};
|
||||
|
||||
|
@ -55,8 +56,8 @@ impl ModifiersState {
|
|||
}
|
||||
|
||||
struct KbdInternal {
|
||||
known_kbds: Vec<wl_keyboard::WlKeyboard>,
|
||||
focus: Option<wl_surface::WlSurface>,
|
||||
known_kbds: Vec<Resource<WlKeyboard>>,
|
||||
focus: Option<Resource<WlSurface>>,
|
||||
pressed_keys: Vec<u32>,
|
||||
mods_state: ModifiersState,
|
||||
keymap: xkb::Keymap,
|
||||
|
@ -65,9 +66,18 @@ struct KbdInternal {
|
|||
repeat_delay: i32,
|
||||
}
|
||||
|
||||
// This is OK because all parts of `xkb` will remain on the
|
||||
// same thread
|
||||
unsafe impl Send for KbdInternal {}
|
||||
|
||||
impl KbdInternal {
|
||||
fn new(
|
||||
rules: &str, model: &str, layout: &str, variant: &str, options: Option<String>, repeat_rate: i32,
|
||||
rules: &str,
|
||||
model: &str,
|
||||
layout: &str,
|
||||
variant: &str,
|
||||
options: Option<String>,
|
||||
repeat_rate: i32,
|
||||
repeat_delay: i32,
|
||||
) -> Result<KbdInternal, ()> {
|
||||
// we create a new contex for each keyboard because libxkbcommon is actually NOT threadsafe
|
||||
|
@ -147,7 +157,7 @@ impl KbdInternal {
|
|||
|
||||
fn with_focused_kbds<F>(&self, mut f: F)
|
||||
where
|
||||
F: FnMut(&wl_keyboard::WlKeyboard, &wl_surface::WlSurface),
|
||||
F: FnMut(&Resource<WlKeyboard>, &Resource<WlSurface>),
|
||||
{
|
||||
if let Some(ref surface) = self.focus {
|
||||
for kbd in &self.known_kbds {
|
||||
|
@ -170,8 +180,14 @@ pub enum Error {
|
|||
|
||||
/// Create a keyboard handler from a set of RMLVO rules
|
||||
pub(crate) fn create_keyboard_handler(
|
||||
rules: &str, model: &str, layout: &str, variant: &str, options: Option<String>, repeat_delay: i32,
|
||||
repeat_rate: i32, logger: &::slog::Logger,
|
||||
rules: &str,
|
||||
model: &str,
|
||||
layout: &str,
|
||||
variant: &str,
|
||||
options: Option<String>,
|
||||
repeat_delay: i32,
|
||||
repeat_rate: i32,
|
||||
logger: &::slog::Logger,
|
||||
) -> Result<KeyboardHandle, Error> {
|
||||
let log = logger.new(o!("smithay_module" => "xkbcommon_handler"));
|
||||
info!(log, "Initializing a xkbcommon handler with keymap query";
|
||||
|
@ -252,7 +268,7 @@ impl KeyboardHandle {
|
|||
///
|
||||
/// The module `smithay::keyboard::keysyms` exposes definitions of all possible keysyms
|
||||
/// to be compared against. This includes non-characted keysyms, such as XF86 special keys.
|
||||
pub fn input<F>(&self, keycode: u32, state: KeyState, serial: u32, filter: F)
|
||||
pub fn input<F>(&self, keycode: u32, state: KeyState, serial: u32, time: u32, filter: F)
|
||||
where
|
||||
F: FnOnce(&ModifiersState, Keysym) -> bool,
|
||||
{
|
||||
|
@ -282,14 +298,25 @@ impl KeyboardHandle {
|
|||
None
|
||||
};
|
||||
let wl_state = match state {
|
||||
KeyState::Pressed => wl_keyboard::KeyState::Pressed,
|
||||
KeyState::Released => wl_keyboard::KeyState::Released,
|
||||
KeyState::Pressed => WlKeyState::Pressed,
|
||||
KeyState::Released => WlKeyState::Released,
|
||||
};
|
||||
guard.with_focused_kbds(|kbd, _| {
|
||||
if let Some((dep, la, lo, gr)) = modifiers {
|
||||
kbd.modifiers(serial, dep, la, lo, gr);
|
||||
kbd.send(Event::Modifiers {
|
||||
serial,
|
||||
mods_depressed: dep,
|
||||
mods_latched: la,
|
||||
mods_locked: lo,
|
||||
group: gr,
|
||||
});
|
||||
}
|
||||
kbd.key(serial, 0, keycode, wl_state);
|
||||
kbd.send(Event::Key {
|
||||
serial,
|
||||
time,
|
||||
key: keycode,
|
||||
state: wl_state,
|
||||
});
|
||||
});
|
||||
if guard.focus.is_some() {
|
||||
trace!(self.arc.logger, "Input forwarded to client");
|
||||
|
@ -303,7 +330,7 @@ impl KeyboardHandle {
|
|||
/// If the ne focus is different from the previous one, any previous focus
|
||||
/// will be sent a `wl_keyboard::leave` event, and if the new focus is not `None`,
|
||||
/// a `wl_keyboard::enter` event will be sent.
|
||||
pub fn set_focus(&self, focus: Option<&wl_surface::WlSurface>, serial: u32) {
|
||||
pub fn set_focus(&self, focus: Option<&Resource<WlSurface>>, serial: u32) {
|
||||
let mut guard = self.arc.internal.lock().unwrap();
|
||||
|
||||
let same = guard
|
||||
|
@ -315,16 +342,29 @@ impl KeyboardHandle {
|
|||
if !same {
|
||||
// unset old focus
|
||||
guard.with_focused_kbds(|kbd, s| {
|
||||
kbd.leave(serial, s);
|
||||
kbd.send(Event::Leave {
|
||||
serial,
|
||||
surface: s.clone(),
|
||||
});
|
||||
});
|
||||
|
||||
// set new focus
|
||||
guard.focus = focus.and_then(|s| s.clone());
|
||||
guard.focus = focus.map(|s| s.clone());
|
||||
let (dep, la, lo, gr) = guard.serialize_modifiers();
|
||||
let keys = guard.serialize_pressed_keys();
|
||||
guard.with_focused_kbds(|kbd, s| {
|
||||
kbd.modifiers(serial, dep, la, lo, gr);
|
||||
kbd.enter(serial, s, keys.clone());
|
||||
guard.with_focused_kbds(|kbd, surface| {
|
||||
kbd.send(Event::Modifiers {
|
||||
serial,
|
||||
mods_depressed: dep,
|
||||
mods_latched: la,
|
||||
mods_locked: lo,
|
||||
group: gr,
|
||||
});
|
||||
kbd.send(Event::Enter {
|
||||
serial,
|
||||
surface: surface.clone(),
|
||||
keys: keys.clone(),
|
||||
});
|
||||
});
|
||||
if guard.focus.is_some() {
|
||||
trace!(self.arc.logger, "Focus set to new surface");
|
||||
|
@ -341,16 +381,19 @@ impl KeyboardHandle {
|
|||
/// The keymap will automatically be sent to it
|
||||
///
|
||||
/// This should be done first, before anything else is done with this keyboard.
|
||||
pub(crate) fn new_kbd(&self, kbd: wl_keyboard::WlKeyboard) {
|
||||
pub(crate) fn new_kbd(&self, kbd: Resource<WlKeyboard>) {
|
||||
trace!(self.arc.logger, "Sending keymap to client");
|
||||
kbd.keymap(
|
||||
wl_keyboard::KeymapFormat::XkbV1,
|
||||
self.arc.keymap_file.as_raw_fd(),
|
||||
self.arc.keymap_len,
|
||||
);
|
||||
kbd.send(Event::Keymap {
|
||||
format: KeymapFormat::XkbV1,
|
||||
fd: self.arc.keymap_file.as_raw_fd(),
|
||||
size: self.arc.keymap_len,
|
||||
});
|
||||
let mut guard = self.arc.internal.lock().unwrap();
|
||||
if kbd.version() >= 4 {
|
||||
kbd.repeat_info(guard.repeat_rate, guard.repeat_delay);
|
||||
kbd.send(Event::RepeatInfo {
|
||||
rate: guard.repeat_rate,
|
||||
delay: guard.repeat_delay,
|
||||
});
|
||||
}
|
||||
guard.known_kbds.push(kbd);
|
||||
}
|
||||
|
@ -361,17 +404,36 @@ impl KeyboardHandle {
|
|||
guard.repeat_delay = delay;
|
||||
guard.repeat_rate = rate;
|
||||
for kbd in &guard.known_kbds {
|
||||
kbd.repeat_info(rate, delay);
|
||||
kbd.send(Event::RepeatInfo { rate, delay });
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs an internal cleanup of known kbds
|
||||
///
|
||||
/// Drops any wl_keyboard that is no longer alive
|
||||
pub(crate) fn cleanup_old_kbds(&self) {
|
||||
let mut guard = self.arc.internal.lock().unwrap();
|
||||
guard
|
||||
.known_kbds
|
||||
.retain(|kbd| kbd.status() != Liveness::Dead);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn implement_keyboard(
|
||||
new_keyboard: NewResource<WlKeyboard>,
|
||||
handle: Option<&KeyboardHandle>,
|
||||
) -> Resource<WlKeyboard> {
|
||||
let destructor = match handle {
|
||||
Some(h) => {
|
||||
let arc = h.arc.clone();
|
||||
Some(move |keyboard: Resource<_>, _| {
|
||||
arc.internal
|
||||
.lock()
|
||||
.unwrap()
|
||||
.known_kbds
|
||||
.retain(|k| !k.equals(&keyboard))
|
||||
})
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
new_keyboard.implement(
|
||||
|request, _keyboard| {
|
||||
match request {
|
||||
Request::Release => {
|
||||
// Our destructors already handle it
|
||||
}
|
||||
}
|
||||
},
|
||||
destructor,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -10,14 +10,14 @@
|
|||
//! ```
|
||||
//! # extern crate wayland_server;
|
||||
//! # #[macro_use] extern crate smithay;
|
||||
//!
|
||||
//! use smithay::wayland::seat::Seat;
|
||||
//!
|
||||
//! # fn main(){
|
||||
//! # let (_display, mut event_loop) = wayland_server::create_display();
|
||||
//! # let (mut display, event_loop) = wayland_server::Display::new();
|
||||
//! // insert the seat:
|
||||
//! let (seat_state_token, seat_global) = Seat::new(
|
||||
//! &mut event_loop,
|
||||
//! let (seat, seat_global) = Seat::new(
|
||||
//! &mut display, // the display
|
||||
//! event_loop.token(), // a LoopToken
|
||||
//! "seat-0".into(), // the name of the seat, will be advertize to clients
|
||||
//! None /* insert a logger here*/
|
||||
//! );
|
||||
|
@ -31,8 +31,7 @@
|
|||
//! Currently, only pointer and keyboard capabilities are supported by
|
||||
//! smithay.
|
||||
//!
|
||||
//! You can add these capabilities via methods of the `Seat` struct that was
|
||||
//! inserted in the event loop, that you can retreive via its token:
|
||||
//! You can add these capabilities via methods of the `Seat` struct:
|
||||
//!
|
||||
//! ```
|
||||
//! # extern crate wayland_server;
|
||||
|
@ -41,28 +40,59 @@
|
|||
//! # use smithay::wayland::seat::Seat;
|
||||
//! #
|
||||
//! # fn main(){
|
||||
//! # let (_display, mut event_loop) = wayland_server::create_display();
|
||||
//! # let (seat_state_token, seat_global) = Seat::new(
|
||||
//! # &mut event_loop,
|
||||
//! # let (mut display, event_loop) = wayland_server::Display::new();
|
||||
//! # let (mut seat, seat_global) = Seat::new(
|
||||
//! # &mut display,
|
||||
//! # event_loop.token(),
|
||||
//! # "seat-0".into(), // the name of the seat, will be advertize to clients
|
||||
//! # None /* insert a logger here*/
|
||||
//! # );
|
||||
//! let pointer_handle = event_loop.state().get_mut(&seat_state_token).add_pointer();
|
||||
//! let pointer_handle = seat.add_pointer();
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! These handles can be cloned and sent accross thread, so you can keep one around
|
||||
//! in your event-handling code to forward inputs to your clients.
|
||||
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
mod keyboard;
|
||||
mod pointer;
|
||||
|
||||
pub use self::keyboard::{Error as KeyboardError, KeyboardHandle, ModifiersState};
|
||||
pub use self::pointer::{PointerAxisHandle, PointerHandle};
|
||||
use wayland_server::{Client, EventLoopHandle, Global, Liveness, Resource, StateToken};
|
||||
use wayland_server::protocol::{wl_keyboard, wl_pointer, wl_seat};
|
||||
use wayland_server::{Display, Global, LoopToken, NewResource, Resource};
|
||||
use wayland_server::protocol::wl_seat;
|
||||
|
||||
/// Internal data of a seat global
|
||||
struct Inner {
|
||||
log: ::slog::Logger,
|
||||
name: String,
|
||||
pointer: Option<PointerHandle>,
|
||||
keyboard: Option<KeyboardHandle>,
|
||||
known_seats: Vec<Resource<wl_seat::WlSeat>>,
|
||||
}
|
||||
|
||||
impl Inner {
|
||||
fn compute_caps(&self) -> wl_seat::Capability {
|
||||
let mut caps = wl_seat::Capability::empty();
|
||||
if self.pointer.is_some() {
|
||||
caps |= wl_seat::Capability::Pointer;
|
||||
}
|
||||
if self.keyboard.is_some() {
|
||||
caps |= wl_seat::Capability::Keyboard;
|
||||
}
|
||||
caps
|
||||
}
|
||||
|
||||
fn send_all_caps(&self) {
|
||||
let capabilities = self.compute_caps();
|
||||
for seat in &self.known_seats {
|
||||
seat.send(wl_seat::Event::Capabilities { capabilities });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A Seat handle
|
||||
///
|
||||
/// This struct gives you access to the control of the
|
||||
/// capabilities of the associated seat.
|
||||
|
@ -71,11 +101,7 @@ use wayland_server::protocol::{wl_keyboard, wl_pointer, wl_seat};
|
|||
///
|
||||
/// See module-level documentation for details of use.
|
||||
pub struct Seat {
|
||||
log: ::slog::Logger,
|
||||
name: String,
|
||||
pointer: Option<PointerHandle>,
|
||||
keyboard: Option<KeyboardHandle>,
|
||||
known_seats: Vec<wl_seat::WlSeat>,
|
||||
inner: Arc<Mutex<Inner>>,
|
||||
}
|
||||
|
||||
impl Seat {
|
||||
|
@ -88,22 +114,39 @@ impl Seat {
|
|||
/// you to add or remove capabilities from it), and the global handle,
|
||||
/// in case you want to remove it.
|
||||
pub fn new<L>(
|
||||
evlh: &mut EventLoopHandle, name: String, logger: L
|
||||
) -> (StateToken<Seat>, Global<wl_seat::WlSeat, StateToken<Seat>>)
|
||||
display: &mut Display,
|
||||
token: LoopToken,
|
||||
name: String,
|
||||
logger: L,
|
||||
) -> (Seat, Global<wl_seat::WlSeat>)
|
||||
where
|
||||
L: Into<Option<::slog::Logger>>,
|
||||
{
|
||||
let log = ::slog_or_stdlog(logger);
|
||||
let seat = Seat {
|
||||
let inner = Arc::new(Mutex::new(Inner {
|
||||
log: log.new(o!("smithay_module" => "seat_handler", "seat_name" => name.clone())),
|
||||
name: name,
|
||||
pointer: None,
|
||||
keyboard: None,
|
||||
known_seats: Vec::new(),
|
||||
}));
|
||||
let seat = Seat {
|
||||
inner: inner.clone(),
|
||||
};
|
||||
let token = evlh.state().insert(seat);
|
||||
let global = evlh.register_global(5, seat_global_bind, token.clone());
|
||||
(token, global)
|
||||
let global = display.create_global(&token, 5, move |_version, new_seat| {
|
||||
let seat = implement_seat(new_seat, inner.clone());
|
||||
let mut inner = inner.lock().unwrap();
|
||||
if seat.version() >= 2 {
|
||||
seat.send(wl_seat::Event::Name {
|
||||
name: inner.name.clone(),
|
||||
});
|
||||
}
|
||||
seat.send(wl_seat::Event::Capabilities {
|
||||
capabilities: inner.compute_caps(),
|
||||
});
|
||||
inner.known_seats.push(seat);
|
||||
});
|
||||
(seat, global)
|
||||
}
|
||||
|
||||
/// Adds the pointer capability to this seat
|
||||
|
@ -115,21 +158,16 @@ impl Seat {
|
|||
/// will overwrite it, and will be seen by the clients as if the
|
||||
/// mouse was unplugged and a new one was plugged.
|
||||
pub fn add_pointer(&mut self) -> PointerHandle {
|
||||
let mut inner = self.inner.lock().unwrap();
|
||||
let pointer = self::pointer::create_pointer_handler();
|
||||
if self.pointer.is_some() {
|
||||
if inner.pointer.is_some() {
|
||||
// there is already a pointer, remove it and notify the clients
|
||||
// of the change
|
||||
self.pointer = None;
|
||||
let caps = self.compute_caps();
|
||||
for seat in &self.known_seats {
|
||||
seat.capabilities(caps);
|
||||
}
|
||||
}
|
||||
self.pointer = Some(pointer.clone());
|
||||
let caps = self.compute_caps();
|
||||
for seat in &self.known_seats {
|
||||
seat.capabilities(caps);
|
||||
inner.pointer = None;
|
||||
inner.send_all_caps();
|
||||
}
|
||||
inner.pointer = Some(pointer.clone());
|
||||
inner.send_all_caps();
|
||||
pointer
|
||||
}
|
||||
|
||||
|
@ -137,12 +175,10 @@ impl Seat {
|
|||
///
|
||||
/// Clients will be appropriately notified.
|
||||
pub fn remove_pointer(&mut self) {
|
||||
if self.pointer.is_some() {
|
||||
self.pointer = None;
|
||||
let caps = self.compute_caps();
|
||||
for seat in &self.known_seats {
|
||||
seat.capabilities(caps);
|
||||
}
|
||||
let mut inner = self.inner.lock().unwrap();
|
||||
if inner.pointer.is_some() {
|
||||
inner.pointer = None;
|
||||
inner.send_all_caps();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,9 +195,15 @@ impl Seat {
|
|||
/// will overwrite it, and will be seen by the clients as if the
|
||||
/// keyboard was unplugged and a new one was plugged.
|
||||
pub fn add_keyboard(
|
||||
&mut self, model: &str, layout: &str, variant: &str, options: Option<String>, repeat_delay: i32,
|
||||
&mut self,
|
||||
model: &str,
|
||||
layout: &str,
|
||||
variant: &str,
|
||||
options: Option<String>,
|
||||
repeat_delay: i32,
|
||||
repeat_rate: i32,
|
||||
) -> Result<KeyboardHandle, KeyboardError> {
|
||||
let mut inner = self.inner.lock().unwrap();
|
||||
let keyboard = self::keyboard::create_keyboard_handler(
|
||||
"evdev", // we need this one
|
||||
model,
|
||||
|
@ -170,22 +212,16 @@ impl Seat {
|
|||
options,
|
||||
repeat_delay,
|
||||
repeat_rate,
|
||||
&self.log,
|
||||
&inner.log,
|
||||
)?;
|
||||
if self.keyboard.is_some() {
|
||||
if inner.keyboard.is_some() {
|
||||
// there is already a keyboard, remove it and notify the clients
|
||||
// of the change
|
||||
self.keyboard = None;
|
||||
let caps = self.compute_caps();
|
||||
for seat in &self.known_seats {
|
||||
seat.capabilities(caps);
|
||||
}
|
||||
}
|
||||
self.keyboard = Some(keyboard.clone());
|
||||
let caps = self.compute_caps();
|
||||
for seat in &self.known_seats {
|
||||
seat.capabilities(caps);
|
||||
inner.keyboard = None;
|
||||
inner.send_all_caps();
|
||||
}
|
||||
inner.keyboard = Some(keyboard.clone());
|
||||
inner.send_all_caps();
|
||||
Ok(keyboard)
|
||||
}
|
||||
|
||||
|
@ -193,95 +229,60 @@ impl Seat {
|
|||
///
|
||||
/// Clients will be appropriately notified.
|
||||
pub fn remove_keyboard(&mut self) {
|
||||
if self.keyboard.is_some() {
|
||||
self.keyboard = None;
|
||||
let caps = self.compute_caps();
|
||||
for seat in &self.known_seats {
|
||||
seat.capabilities(caps);
|
||||
}
|
||||
let mut inner = self.inner.lock().unwrap();
|
||||
if inner.keyboard.is_some() {
|
||||
inner.keyboard = None;
|
||||
inner.send_all_caps();
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks wether a given `WlSeat` is associated with this `Seat`
|
||||
pub fn owns(&self, seat: &wl_seat::WlSeat) -> bool {
|
||||
self.known_seats.iter().any(|s| s.equals(seat))
|
||||
}
|
||||
|
||||
/// Cleanup internal states from old resources
|
||||
///
|
||||
/// Deletes all remnnant of ressources from clients that
|
||||
/// are now disconnected.
|
||||
///
|
||||
/// It can be wise to run this from time to time.
|
||||
pub fn cleanup(&mut self) {
|
||||
if let Some(ref pointer) = self.pointer {
|
||||
pointer.cleanup_old_pointers();
|
||||
}
|
||||
if let Some(ref kbd) = self.keyboard {
|
||||
kbd.cleanup_old_kbds();
|
||||
}
|
||||
self.known_seats.retain(|s| s.status() == Liveness::Alive);
|
||||
}
|
||||
|
||||
fn compute_caps(&self) -> wl_seat::Capability {
|
||||
let mut caps = wl_seat::Capability::empty();
|
||||
if self.pointer.is_some() {
|
||||
caps |= wl_seat::Capability::Pointer;
|
||||
}
|
||||
if self.keyboard.is_some() {
|
||||
caps |= wl_seat::Capability::Keyboard;
|
||||
}
|
||||
caps
|
||||
pub fn owns(&self, seat: &Resource<wl_seat::WlSeat>) -> bool {
|
||||
let inner = self.inner.lock().unwrap();
|
||||
inner.known_seats.iter().any(|s| s.equals(seat))
|
||||
}
|
||||
}
|
||||
|
||||
fn seat_global_bind(
|
||||
evlh: &mut EventLoopHandle, token: &mut StateToken<Seat>, _: &Client, seat: wl_seat::WlSeat
|
||||
) {
|
||||
evlh.register(&seat, seat_implementation(), token.clone(), None);
|
||||
let seat_mgr = evlh.state().get_mut(token);
|
||||
if seat.version() >= 2 {
|
||||
seat.name(seat_mgr.name.clone());
|
||||
}
|
||||
seat.capabilities(seat_mgr.compute_caps());
|
||||
seat_mgr.known_seats.push(seat);
|
||||
}
|
||||
|
||||
fn seat_implementation() -> wl_seat::Implementation<StateToken<Seat>> {
|
||||
wl_seat::Implementation {
|
||||
get_pointer: |evlh, token, _, _, pointer| {
|
||||
evlh.register(&pointer, pointer_implementation(), (), None);
|
||||
if let Some(ref ptr_handle) = evlh.state().get(token).pointer {
|
||||
fn implement_seat(
|
||||
new_seat: NewResource<wl_seat::WlSeat>,
|
||||
inner: Arc<Mutex<Inner>>,
|
||||
) -> Resource<wl_seat::WlSeat> {
|
||||
let dest_inner = inner.clone();
|
||||
new_seat.implement(
|
||||
move |request, _seat| {
|
||||
let inner = inner.lock().unwrap();
|
||||
match request {
|
||||
wl_seat::Request::GetPointer { id } => {
|
||||
let pointer = self::pointer::implement_pointer(id, inner.pointer.as_ref());
|
||||
if let Some(ref ptr_handle) = inner.pointer {
|
||||
ptr_handle.new_pointer(pointer);
|
||||
} else {
|
||||
// we should send a protocol error... but the protocol does not allow
|
||||
// us, so this pointer will just remain inactive ¯\_(ツ)_/¯
|
||||
}
|
||||
},
|
||||
get_keyboard: |evlh, token, _, _, keyboard| {
|
||||
evlh.register(&keyboard, keyboard_implementation(), (), None);
|
||||
if let Some(ref kbd_handle) = evlh.state().get(token).keyboard {
|
||||
}
|
||||
wl_seat::Request::GetKeyboard { id } => {
|
||||
let keyboard = self::keyboard::implement_keyboard(id, inner.keyboard.as_ref());
|
||||
if let Some(ref kbd_handle) = inner.keyboard {
|
||||
kbd_handle.new_kbd(keyboard);
|
||||
} else {
|
||||
// same, should error but cant
|
||||
// same as pointer, should error but cannot
|
||||
}
|
||||
},
|
||||
get_touch: |_evlh, _token, _, _, _touch| {
|
||||
}
|
||||
wl_seat::Request::GetTouch { id: _ } => {
|
||||
// TODO
|
||||
}
|
||||
wl_seat::Request::Release => {
|
||||
// Our destructors already handle it
|
||||
}
|
||||
}
|
||||
},
|
||||
release: |_, _, _, _| {},
|
||||
}
|
||||
}
|
||||
|
||||
fn pointer_implementation() -> wl_pointer::Implementation<()> {
|
||||
wl_pointer::Implementation {
|
||||
set_cursor: |_, _, _, _, _, _, _, _| {},
|
||||
release: |_, _, _, _| {},
|
||||
}
|
||||
}
|
||||
|
||||
fn keyboard_implementation() -> wl_keyboard::Implementation<()> {
|
||||
wl_keyboard::Implementation {
|
||||
release: |_, _, _, _| {},
|
||||
}
|
||||
Some(move |seat, _| {
|
||||
dest_inner
|
||||
.lock()
|
||||
.unwrap()
|
||||
.known_seats
|
||||
.retain(|s| !s.equals(&seat));
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
use std::sync::{Arc, Mutex, MutexGuard};
|
||||
use wayland_server::{Liveness, Resource};
|
||||
use wayland_server::protocol::{wl_pointer, wl_surface};
|
||||
use wayland_server::{NewResource, Resource};
|
||||
use wayland_server::protocol::wl_surface::WlSurface;
|
||||
use wayland_server::protocol::wl_pointer::{Axis, AxisSource, ButtonState, Event, Request, WlPointer};
|
||||
|
||||
// TODO: handle pointer surface role
|
||||
|
||||
struct PointerInternal {
|
||||
known_pointers: Vec<wl_pointer::WlPointer>,
|
||||
focus: Option<wl_surface::WlSurface>,
|
||||
known_pointers: Vec<Resource<WlPointer>>,
|
||||
focus: Option<Resource<WlSurface>>,
|
||||
}
|
||||
|
||||
impl PointerInternal {
|
||||
|
@ -19,7 +20,7 @@ impl PointerInternal {
|
|||
|
||||
fn with_focused_pointers<F>(&self, mut f: F)
|
||||
where
|
||||
F: FnMut(&wl_pointer::WlPointer, &wl_surface::WlSurface),
|
||||
F: FnMut(&Resource<WlPointer>, &Resource<WlSurface>),
|
||||
{
|
||||
if let Some(ref focus) = self.focus {
|
||||
for ptr in &self.known_pointers {
|
||||
|
@ -44,7 +45,7 @@ pub struct PointerHandle {
|
|||
}
|
||||
|
||||
impl PointerHandle {
|
||||
pub(crate) fn new_pointer(&self, pointer: wl_pointer::WlPointer) {
|
||||
pub(crate) fn new_pointer(&self, pointer: Resource<WlPointer>) {
|
||||
let mut guard = self.inner.lock().unwrap();
|
||||
guard.known_pointers.push(pointer);
|
||||
}
|
||||
|
@ -59,7 +60,7 @@ impl PointerHandle {
|
|||
///
|
||||
/// This will internally take care of notifying the appropriate client objects
|
||||
/// of enter/motion/leave events.
|
||||
pub fn motion(&self, location: Option<(&wl_surface::WlSurface, f64, f64)>, serial: u32, time: u32) {
|
||||
pub fn motion(&self, location: Option<(&Resource<WlSurface>, f64, f64)>, serial: u32, time: u32) {
|
||||
let mut guard = self.inner.lock().unwrap();
|
||||
// do we leave a surface ?
|
||||
let mut leave = true;
|
||||
|
@ -72,9 +73,12 @@ impl PointerHandle {
|
|||
}
|
||||
if leave {
|
||||
guard.with_focused_pointers(|pointer, surface| {
|
||||
pointer.leave(serial, surface);
|
||||
pointer.send(Event::Leave {
|
||||
serial,
|
||||
surface: surface.clone(),
|
||||
});
|
||||
if pointer.version() >= 5 {
|
||||
pointer.frame();
|
||||
pointer.send(Event::Frame);
|
||||
}
|
||||
});
|
||||
guard.focus = None;
|
||||
|
@ -83,19 +87,28 @@ impl PointerHandle {
|
|||
// do we enter one ?
|
||||
if let Some((surface, x, y)) = location {
|
||||
if guard.focus.is_none() {
|
||||
guard.focus = surface.clone();
|
||||
guard.focus = Some(surface.clone());
|
||||
guard.with_focused_pointers(|pointer, surface| {
|
||||
pointer.enter(serial, surface, x, y);
|
||||
pointer.send(Event::Enter {
|
||||
serial,
|
||||
surface: surface.clone(),
|
||||
surface_x: x,
|
||||
surface_y: y,
|
||||
});
|
||||
if pointer.version() >= 5 {
|
||||
pointer.frame();
|
||||
pointer.send(Event::Frame);
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// we were on top of a surface and remained on it
|
||||
guard.with_focused_pointers(|pointer, _| {
|
||||
pointer.motion(time, x, y);
|
||||
pointer.send(Event::Motion {
|
||||
time,
|
||||
surface_x: x,
|
||||
surface_y: y,
|
||||
});
|
||||
if pointer.version() >= 5 {
|
||||
pointer.frame();
|
||||
pointer.send(Event::Frame);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -106,12 +119,17 @@ impl PointerHandle {
|
|||
///
|
||||
/// This will internally send the appropriate button event to the client
|
||||
/// objects matching with the currently focused surface.
|
||||
pub fn button(&self, button: u32, state: wl_pointer::ButtonState, serial: u32, time: u32) {
|
||||
pub fn button(&self, button: u32, state: ButtonState, serial: u32, time: u32) {
|
||||
let guard = self.inner.lock().unwrap();
|
||||
guard.with_focused_pointers(|pointer, _| {
|
||||
pointer.button(serial, time, button, state);
|
||||
pointer.send(Event::Button {
|
||||
serial,
|
||||
time,
|
||||
button,
|
||||
state,
|
||||
});
|
||||
if pointer.version() >= 5 {
|
||||
pointer.frame();
|
||||
pointer.send(Event::Frame);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -125,18 +143,12 @@ impl PointerHandle {
|
|||
inner: self.inner.lock().unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn cleanup_old_pointers(&self) {
|
||||
let mut guard = self.inner.lock().unwrap();
|
||||
guard
|
||||
.known_pointers
|
||||
.retain(|p| p.status() != Liveness::Dead);
|
||||
}
|
||||
}
|
||||
|
||||
/// A frame of pointer axis events.
|
||||
///
|
||||
/// Can be used with the builder pattern, e.g.:
|
||||
///
|
||||
/// ```ignore
|
||||
/// pointer.axis()
|
||||
/// .source(AxisSource::Wheel)
|
||||
|
@ -156,10 +168,12 @@ impl<'a> PointerAxisHandle<'a> {
|
|||
///
|
||||
/// Using the `AxisSource::Finger` requires a stop event to be send,
|
||||
/// when the user lifts off the finger (not necessarily in the same frame).
|
||||
pub fn source(&mut self, source: wl_pointer::AxisSource) -> &mut Self {
|
||||
pub fn source(&mut self, source: AxisSource) -> &mut Self {
|
||||
self.inner.with_focused_pointers(|pointer, _| {
|
||||
if pointer.version() >= 5 {
|
||||
pointer.axis_source(source);
|
||||
pointer.send(Event::AxisSource {
|
||||
axis_source: source,
|
||||
});
|
||||
}
|
||||
});
|
||||
self
|
||||
|
@ -170,10 +184,13 @@ impl<'a> PointerAxisHandle<'a> {
|
|||
/// This event is optional and gives the client additional information about
|
||||
/// the nature of the axis event. E.g. a scroll wheel might issue separate steps,
|
||||
/// while a touchpad may never issue this event as it has no steps.
|
||||
pub fn discrete(&mut self, axis: wl_pointer::Axis, steps: i32) -> &mut Self {
|
||||
pub fn discrete(&mut self, axis: Axis, steps: i32) -> &mut Self {
|
||||
self.inner.with_focused_pointers(|pointer, _| {
|
||||
if pointer.version() >= 5 {
|
||||
pointer.axis_discrete(axis, steps);
|
||||
pointer.send(Event::AxisDiscrete {
|
||||
axis,
|
||||
discrete: steps,
|
||||
});
|
||||
}
|
||||
});
|
||||
self
|
||||
|
@ -181,9 +198,9 @@ impl<'a> PointerAxisHandle<'a> {
|
|||
|
||||
/// The actual scroll value. This event is the only required one, but can also
|
||||
/// be send multiple times. The values off one frame will be accumulated by the client.
|
||||
pub fn value(&mut self, axis: wl_pointer::Axis, value: f64, time: u32) -> &mut Self {
|
||||
pub fn value(&mut self, axis: Axis, value: f64, time: u32) -> &mut Self {
|
||||
self.inner.with_focused_pointers(|pointer, _| {
|
||||
pointer.axis(time, axis, value);
|
||||
pointer.send(Event::Axis { time, axis, value });
|
||||
});
|
||||
self
|
||||
}
|
||||
|
@ -192,10 +209,10 @@ impl<'a> PointerAxisHandle<'a> {
|
|||
///
|
||||
/// This event is required for sources of the `AxisSource::Finger` type
|
||||
/// and otherwise optional.
|
||||
pub fn stop(&mut self, axis: wl_pointer::Axis, time: u32) -> &mut Self {
|
||||
pub fn stop(&mut self, axis: Axis, time: u32) -> &mut Self {
|
||||
self.inner.with_focused_pointers(|pointer, _| {
|
||||
if pointer.version() >= 5 {
|
||||
pointer.axis_stop(time, axis);
|
||||
pointer.send(Event::AxisStop { time, axis });
|
||||
}
|
||||
});
|
||||
self
|
||||
|
@ -209,7 +226,7 @@ impl<'a> PointerAxisHandle<'a> {
|
|||
pub fn done(&mut self) {
|
||||
self.inner.with_focused_pointers(|pointer, _| {
|
||||
if pointer.version() >= 5 {
|
||||
pointer.frame();
|
||||
pointer.send(Event::Frame);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -220,3 +237,35 @@ pub(crate) fn create_pointer_handler() -> PointerHandle {
|
|||
inner: Arc::new(Mutex::new(PointerInternal::new())),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn implement_pointer(
|
||||
new_pointer: NewResource<WlPointer>,
|
||||
handle: Option<&PointerHandle>,
|
||||
) -> Resource<WlPointer> {
|
||||
let destructor = match handle {
|
||||
Some(h) => {
|
||||
let inner = h.inner.clone();
|
||||
Some(move |pointer: Resource<_>, _| {
|
||||
inner
|
||||
.lock()
|
||||
.unwrap()
|
||||
.known_pointers
|
||||
.retain(|p| !p.equals(&pointer))
|
||||
})
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
new_pointer.implement(
|
||||
|request, _pointer| {
|
||||
match request {
|
||||
Request::SetCursor { .. } => {
|
||||
// TODO
|
||||
}
|
||||
Request::Release => {
|
||||
// Our destructors already handle it
|
||||
}
|
||||
}
|
||||
},
|
||||
destructor,
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue