backend.input: rework libinput as a calloop source
This commit is contained in:
parent
5552c81a32
commit
8f543eb597
|
@ -14,7 +14,7 @@ use slog::Logger;
|
||||||
use smithay::backend::session::{auto::AutoSession, Session};
|
use smithay::backend::session::{auto::AutoSession, Session};
|
||||||
use smithay::{
|
use smithay::{
|
||||||
backend::input::{
|
backend::input::{
|
||||||
self, Event, InputBackend, InputHandler, KeyState, KeyboardKeyEvent, PointerAxisEvent,
|
self, Event, InputBackend, InputEvent, KeyState, KeyboardKeyEvent, PointerAxisEvent,
|
||||||
PointerButtonEvent, PointerMotionAbsoluteEvent, PointerMotionEvent,
|
PointerButtonEvent, PointerMotionAbsoluteEvent, PointerMotionEvent,
|
||||||
},
|
},
|
||||||
reexports::wayland_server::protocol::wl_pointer,
|
reexports::wayland_server::protocol::wl_pointer,
|
||||||
|
@ -77,20 +77,21 @@ impl AnvilInputHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B: InputBackend> InputHandler<B> for AnvilInputHandler {
|
impl AnvilInputHandler {
|
||||||
fn on_seat_created(&mut self, _: &input::Seat) {
|
pub fn process_event<B: InputBackend>(&mut self, event: InputEvent<B>) {
|
||||||
/* currently we just create a single static one */
|
match event {
|
||||||
|
InputEvent::Keyboard { event, .. } => self.on_keyboard_key::<B>(event),
|
||||||
|
InputEvent::PointerMotion { event, .. } => self.on_pointer_move::<B>(event),
|
||||||
|
InputEvent::PointerMotionAbsolute { event, .. } => self.on_pointer_move_absolute::<B>(event),
|
||||||
|
InputEvent::PointerButton { event, .. } => self.on_pointer_button::<B>(event),
|
||||||
|
InputEvent::PointerAxis { event, .. } => self.on_pointer_axis::<B>(event),
|
||||||
|
_ => {
|
||||||
|
// other events are not handled in anvil (yet)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_seat_destroyed(&mut self, _: &input::Seat) {
|
fn on_keyboard_key<B: InputBackend>(&mut self, evt: B::KeyboardKeyEvent) {
|
||||||
/* currently we just create a single static one */
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_seat_changed(&mut self, _: &input::Seat) {
|
|
||||||
/* currently we just create a single static one */
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_keyboard_key(&mut self, _: &input::Seat, evt: B::KeyboardKeyEvent) {
|
|
||||||
let keycode = evt.key_code();
|
let keycode = evt.key_code();
|
||||||
let state = evt.state();
|
let state = evt.state();
|
||||||
debug!(self.log, "key"; "keycode" => keycode, "state" => format!("{:?}", state));
|
debug!(self.log, "key"; "keycode" => keycode, "state" => format!("{:?}", state));
|
||||||
|
@ -146,7 +147,7 @@ impl<B: InputBackend> InputHandler<B> for AnvilInputHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_pointer_move(&mut self, _: &input::Seat, evt: B::PointerMotionEvent) {
|
fn on_pointer_move<B: InputBackend>(&mut self, evt: B::PointerMotionEvent) {
|
||||||
let (x, y) = (evt.delta_x(), evt.delta_y());
|
let (x, y) = (evt.delta_x(), evt.delta_y());
|
||||||
let serial = SCOUNTER.next_serial();
|
let serial = SCOUNTER.next_serial();
|
||||||
let mut location = self.pointer_location.borrow_mut();
|
let mut location = self.pointer_location.borrow_mut();
|
||||||
|
@ -163,7 +164,7 @@ impl<B: InputBackend> InputHandler<B> for AnvilInputHandler {
|
||||||
self.pointer.motion(*location, under, serial, evt.time());
|
self.pointer.motion(*location, under, serial, evt.time());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_pointer_move_absolute(&mut self, _: &input::Seat, evt: B::PointerMotionAbsoluteEvent) {
|
fn on_pointer_move_absolute<B: InputBackend>(&mut self, evt: B::PointerMotionAbsoluteEvent) {
|
||||||
// different cases depending on the context:
|
// different cases depending on the context:
|
||||||
let (x, y) = {
|
let (x, y) = {
|
||||||
#[cfg(feature = "udev")]
|
#[cfg(feature = "udev")]
|
||||||
|
@ -188,7 +189,7 @@ impl<B: InputBackend> InputHandler<B> for AnvilInputHandler {
|
||||||
self.pointer.motion((x, y), under, serial, evt.time());
|
self.pointer.motion((x, y), under, serial, evt.time());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_pointer_button(&mut self, _: &input::Seat, evt: B::PointerButtonEvent) {
|
fn on_pointer_button<B: InputBackend>(&mut self, evt: B::PointerButtonEvent) {
|
||||||
let serial = SCOUNTER.next_serial();
|
let serial = SCOUNTER.next_serial();
|
||||||
let button = match evt.button() {
|
let button = match evt.button() {
|
||||||
input::MouseButton::Left => 0x110,
|
input::MouseButton::Left => 0x110,
|
||||||
|
@ -214,7 +215,7 @@ impl<B: InputBackend> InputHandler<B> for AnvilInputHandler {
|
||||||
self.pointer.button(button, state, serial, evt.time());
|
self.pointer.button(button, state, serial, evt.time());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_pointer_axis(&mut self, _: &input::Seat, evt: B::PointerAxisEvent) {
|
fn on_pointer_axis<B: InputBackend>(&mut self, evt: B::PointerAxisEvent) {
|
||||||
let source = match evt.source() {
|
let source = match evt.source() {
|
||||||
input::AxisSource::Continuous => wl_pointer::AxisSource::Continuous,
|
input::AxisSource::Continuous => wl_pointer::AxisSource::Continuous,
|
||||||
input::AxisSource::Finger => wl_pointer::AxisSource::Finger,
|
input::AxisSource::Finger => wl_pointer::AxisSource::Finger,
|
||||||
|
@ -250,25 +251,6 @@ impl<B: InputBackend> InputHandler<B> for AnvilInputHandler {
|
||||||
self.pointer.axis(frame);
|
self.pointer.axis(frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_touch_down(&mut self, _: &input::Seat, _: B::TouchDownEvent) {
|
|
||||||
/* not done in this example */
|
|
||||||
}
|
|
||||||
fn on_touch_motion(&mut self, _: &input::Seat, _: B::TouchMotionEvent) {
|
|
||||||
/* not done in this example */
|
|
||||||
}
|
|
||||||
fn on_touch_up(&mut self, _: &input::Seat, _: B::TouchUpEvent) {
|
|
||||||
/* not done in this example */
|
|
||||||
}
|
|
||||||
fn on_touch_cancel(&mut self, _: &input::Seat, _: B::TouchCancelEvent) {
|
|
||||||
/* not done in this example */
|
|
||||||
}
|
|
||||||
fn on_touch_frame(&mut self, _: &input::Seat, _: B::TouchFrameEvent) {
|
|
||||||
/* not done in this example */
|
|
||||||
}
|
|
||||||
fn on_input_config_changed(&mut self, _: &mut B::InputConfig) {
|
|
||||||
/* not done in this example */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Possible results of a keyboard action
|
/// Possible results of a keyboard action
|
||||||
|
|
|
@ -26,8 +26,7 @@ use smithay::{
|
||||||
DevPath, Device, DeviceHandler, Surface,
|
DevPath, Device, DeviceHandler, Surface,
|
||||||
},
|
},
|
||||||
graphics::CursorBackend,
|
graphics::CursorBackend,
|
||||||
input::InputBackend,
|
libinput::{LibinputInputBackend, LibinputSessionInterface},
|
||||||
libinput::{libinput_bind, LibinputInputBackend, LibinputSessionInterface},
|
|
||||||
session::{
|
session::{
|
||||||
auto::{auto_session_bind, AutoSession},
|
auto::{auto_session_bind, AutoSession},
|
||||||
notify_multiplexer, AsSessionObserver, Session, SessionNotifier,
|
notify_multiplexer, AsSessionObserver, Session, SessionNotifier,
|
||||||
|
@ -202,8 +201,8 @@ pub fn run_udev(
|
||||||
Libinput::new_with_udev::<LibinputSessionInterface<AutoSession>>(session.clone().into());
|
Libinput::new_with_udev::<LibinputSessionInterface<AutoSession>>(session.clone().into());
|
||||||
let libinput_session_id = notifier.register(libinput_context.observer());
|
let libinput_session_id = notifier.register(libinput_context.observer());
|
||||||
libinput_context.udev_assign_seat(&seat).unwrap();
|
libinput_context.udev_assign_seat(&seat).unwrap();
|
||||||
let mut libinput_backend = LibinputInputBackend::new(libinput_context, log.clone());
|
let libinput_backend = LibinputInputBackend::new(libinput_context, log.clone());
|
||||||
libinput_backend.set_handler(AnvilInputHandler::new_with_session(
|
let mut input_handler = AnvilInputHandler::new_with_session(
|
||||||
log.clone(),
|
log.clone(),
|
||||||
InputInitData {
|
InputInitData {
|
||||||
pointer,
|
pointer,
|
||||||
|
@ -214,13 +213,16 @@ pub fn run_udev(
|
||||||
pointer_location,
|
pointer_location,
|
||||||
},
|
},
|
||||||
session,
|
session,
|
||||||
));
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Bind all our objects that get driven by the event loop
|
* Bind all our objects that get driven by the event loop
|
||||||
*/
|
*/
|
||||||
let libinput_event_source = libinput_bind(libinput_backend, event_loop.handle())
|
let libinput_event_source = event_loop
|
||||||
.map_err(|e| -> IoError { e.into() })
|
.handle()
|
||||||
|
.insert_source(libinput_backend, move |event, _, _anvil_state| {
|
||||||
|
input_handler.process_event(event)
|
||||||
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let session_event_source = auto_session_bind(notifier, event_loop.handle())
|
let session_event_source = auto_session_bind(notifier, event_loop.handle())
|
||||||
.map_err(|(e, _)| e)
|
.map_err(|(e, _)| e)
|
||||||
|
|
|
@ -31,7 +31,9 @@ pub fn run_winit(
|
||||||
event_loop: &mut EventLoop<AnvilState>,
|
event_loop: &mut EventLoop<AnvilState>,
|
||||||
log: Logger,
|
log: Logger,
|
||||||
) -> Result<(), ()> {
|
) -> Result<(), ()> {
|
||||||
let (renderer, mut input) = winit::init(log.clone()).map_err(|_| ())?;
|
let (renderer, mut input) = winit::init(log.clone()).map_err(|err| {
|
||||||
|
slog::crit!(log, "Failed to initialize Winit backend: {}", err);
|
||||||
|
})?;
|
||||||
|
|
||||||
#[cfg(feature = "egl")]
|
#[cfg(feature = "egl")]
|
||||||
let egl_buffer_reader = Rc::new(RefCell::new(
|
let egl_buffer_reader = Rc::new(RefCell::new(
|
||||||
|
@ -111,7 +113,7 @@ pub fn run_winit(
|
||||||
|
|
||||||
let pointer_location = Rc::new(RefCell::new((0.0, 0.0)));
|
let pointer_location = Rc::new(RefCell::new((0.0, 0.0)));
|
||||||
|
|
||||||
input.set_handler(AnvilInputHandler::new(
|
let mut input_handler = AnvilInputHandler::new(
|
||||||
log.clone(),
|
log.clone(),
|
||||||
InputInitData {
|
InputInitData {
|
||||||
pointer,
|
pointer,
|
||||||
|
@ -121,12 +123,14 @@ pub fn run_winit(
|
||||||
running: state.running.clone(),
|
running: state.running.clone(),
|
||||||
pointer_location: pointer_location.clone(),
|
pointer_location: pointer_location.clone(),
|
||||||
},
|
},
|
||||||
));
|
);
|
||||||
|
|
||||||
info!(log, "Initialization completed, starting the main loop.");
|
info!(log, "Initialization completed, starting the main loop.");
|
||||||
|
|
||||||
while state.running.load(Ordering::SeqCst) {
|
while state.running.load(Ordering::SeqCst) {
|
||||||
input.dispatch_new_events().unwrap();
|
input
|
||||||
|
.dispatch_new_events(|event, _| input_handler.process_event(event))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// drawing logic
|
// drawing logic
|
||||||
{
|
{
|
||||||
|
|
|
@ -491,9 +491,6 @@ impl TouchFrameEvent for UnusedEvent {}
|
||||||
/// need to implement this and provide the same base guarantees about the precision of
|
/// need to implement this and provide the same base guarantees about the precision of
|
||||||
/// given events.
|
/// given events.
|
||||||
pub trait InputBackend: Sized {
|
pub trait InputBackend: Sized {
|
||||||
/// Type of input device associated with the backend
|
|
||||||
type InputConfig: ?Sized;
|
|
||||||
|
|
||||||
/// Type representing errors that may be returned when processing events
|
/// Type representing errors that may be returned when processing events
|
||||||
type EventError: Error;
|
type EventError: Error;
|
||||||
|
|
||||||
|
@ -518,168 +515,108 @@ pub trait InputBackend: Sized {
|
||||||
/// Type representing touch frame events
|
/// Type representing touch frame events
|
||||||
type TouchFrameEvent: TouchFrameEvent;
|
type TouchFrameEvent: TouchFrameEvent;
|
||||||
|
|
||||||
/// Sets a new handler for this [`InputBackend`]
|
/// Special events that are custom to this backend
|
||||||
fn set_handler<H: InputHandler<Self> + 'static>(&mut self, handler: H);
|
type SpecialEvent;
|
||||||
/// Get a reference to the currently set handler, if any
|
|
||||||
fn get_handler(&mut self) -> Option<&mut dyn InputHandler<Self>>;
|
|
||||||
/// Clears the currently handler, if one is set
|
|
||||||
fn clear_handler(&mut self);
|
|
||||||
|
|
||||||
/// Get current `InputConfig`
|
/// Backend-specific type allowing you to configure it
|
||||||
|
type InputConfig: ?Sized;
|
||||||
|
|
||||||
|
/// Get the list of currently known Seats
|
||||||
|
fn seats(&self) -> Vec<Seat>;
|
||||||
|
|
||||||
|
/// Access the input configuration interface
|
||||||
fn input_config(&mut self) -> &mut Self::InputConfig;
|
fn input_config(&mut self) -> &mut Self::InputConfig;
|
||||||
|
|
||||||
/// Processes new events of the underlying backend and drives the [`InputHandler`].
|
/// Processes new events of the underlying backend and drives the [`InputHandler`].
|
||||||
fn dispatch_new_events(&mut self) -> Result<(), Self::EventError>;
|
///
|
||||||
|
/// The callback can only assume its second argument to be usable if the event is
|
||||||
|
/// `InputEvent::ConfigChanged`.
|
||||||
|
fn dispatch_new_events<F>(&mut self, callback: F) -> Result<(), Self::EventError>
|
||||||
|
where
|
||||||
|
F: FnMut(InputEvent<Self>, &mut Self::InputConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implement to receive input events from any [`InputBackend`].
|
/// Different events that can be generated by an input backend
|
||||||
pub trait InputHandler<B: InputBackend> {
|
pub enum InputEvent<B: InputBackend> {
|
||||||
/// Called when a new [`Seat`] has been created
|
/// A new seat has been created
|
||||||
fn on_seat_created(&mut self, seat: &Seat);
|
NewSeat(Seat),
|
||||||
/// Called when an existing [`Seat`] has been destroyed.
|
/// A seat has changed
|
||||||
fn on_seat_destroyed(&mut self, seat: &Seat);
|
SeatChanged(Seat),
|
||||||
/// Called when a [`Seat`]'s properties have changed.
|
/// A seat has been removed
|
||||||
|
SeatRemoved(Seat),
|
||||||
|
/// A keyboard event occured
|
||||||
|
Keyboard {
|
||||||
|
/// Seat that generated the event
|
||||||
|
seat: Seat,
|
||||||
|
/// The keyboard event
|
||||||
|
event: B::KeyboardKeyEvent,
|
||||||
|
},
|
||||||
|
/// A relative pointer motion occured
|
||||||
|
PointerMotion {
|
||||||
|
/// Seat that generated the event
|
||||||
|
seat: Seat,
|
||||||
|
/// The pointer motion event
|
||||||
|
event: B::PointerMotionEvent,
|
||||||
|
},
|
||||||
|
/// An absolute pointer motion occures
|
||||||
|
PointerMotionAbsolute {
|
||||||
|
/// Seat that generated the event
|
||||||
|
seat: Seat,
|
||||||
|
/// The absolute pointer motion event
|
||||||
|
event: B::PointerMotionAbsoluteEvent,
|
||||||
|
},
|
||||||
|
/// A pointer button was pressed or released
|
||||||
|
PointerButton {
|
||||||
|
/// Seat that generated the event
|
||||||
|
seat: Seat,
|
||||||
|
/// The pointer button event
|
||||||
|
event: B::PointerButtonEvent,
|
||||||
|
},
|
||||||
|
/// A pointer axis was actionned
|
||||||
|
PointerAxis {
|
||||||
|
/// Seat that generated the event
|
||||||
|
seat: Seat,
|
||||||
|
/// The pointer axis event
|
||||||
|
event: B::PointerAxisEvent,
|
||||||
|
},
|
||||||
|
/// A new touchpoint appeared
|
||||||
|
TouchDown {
|
||||||
|
/// Seat that generated the event
|
||||||
|
seat: Seat,
|
||||||
|
/// The touch down event
|
||||||
|
event: B::TouchDownEvent,
|
||||||
|
},
|
||||||
|
/// A touchpoint moved
|
||||||
|
TouchMotion {
|
||||||
|
/// Seat that generated the event
|
||||||
|
seat: Seat,
|
||||||
|
/// The touch motion event
|
||||||
|
event: B::TouchMotionEvent,
|
||||||
|
},
|
||||||
|
/// A touchpoint was removed
|
||||||
|
TouchUp {
|
||||||
|
/// Seat that generated the event
|
||||||
|
seat: Seat,
|
||||||
|
/// The touch up event
|
||||||
|
event: B::TouchUpEvent,
|
||||||
|
},
|
||||||
|
/// A touch sequence was cancelled
|
||||||
|
TouchCancel {
|
||||||
|
/// Seat that generated the event
|
||||||
|
seat: Seat,
|
||||||
|
/// The touch cancel event
|
||||||
|
event: B::TouchCancelEvent,
|
||||||
|
},
|
||||||
|
/// A touch frame was emmited
|
||||||
///
|
///
|
||||||
/// ## Note:
|
/// A set of two events received on the same seat between two frames should
|
||||||
///
|
/// be interpreted as an atomic event.
|
||||||
/// It is not guaranteed that any change has actually happened.
|
TouchFrame {
|
||||||
fn on_seat_changed(&mut self, seat: &Seat);
|
/// Seat that generated the event
|
||||||
|
seat: Seat,
|
||||||
/// Called when a new keyboard event was received.
|
/// The touch frame event
|
||||||
///
|
event: B::TouchFrameEvent,
|
||||||
/// # Arguments
|
},
|
||||||
///
|
/// Special event specific of this backend
|
||||||
/// - `seat` - The [`Seat`] the event belongs to
|
Special(B::SpecialEvent),
|
||||||
/// - `event` - The keyboard event
|
|
||||||
///
|
|
||||||
fn on_keyboard_key(&mut self, seat: &Seat, event: B::KeyboardKeyEvent);
|
|
||||||
|
|
||||||
/// Called when a new pointer movement event was received.
|
|
||||||
///
|
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// - `seat` - The [`Seat`] the event belongs to
|
|
||||||
/// - `event` - The pointer movement event
|
|
||||||
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, 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, 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 guarantees about actual time passed between events.
|
|
||||||
fn on_pointer_axis(&mut self, seat: &Seat, event: B::PointerAxisEvent);
|
|
||||||
|
|
||||||
/// Called when a new touch down event was received.
|
|
||||||
///
|
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// - `seat` - The [`Seat`] the event belongs to
|
|
||||||
/// - `event` - The touch down event
|
|
||||||
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, 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, 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, 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, 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, config: &mut B::InputConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<B: InputBackend> InputHandler<B> for Box<dyn InputHandler<B>> {
|
|
||||||
fn on_seat_created(&mut self, seat: &Seat) {
|
|
||||||
(**self).on_seat_created(seat)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_seat_destroyed(&mut self, seat: &Seat) {
|
|
||||||
(**self).on_seat_destroyed(seat)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_seat_changed(&mut self, seat: &Seat) {
|
|
||||||
(**self).on_seat_changed(seat)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_keyboard_key(&mut self, seat: &Seat, event: B::KeyboardKeyEvent) {
|
|
||||||
(**self).on_keyboard_key(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, seat: &Seat, event: B::PointerMotionAbsoluteEvent) {
|
|
||||||
(**self).on_pointer_move_absolute(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, seat: &Seat, event: B::PointerAxisEvent) {
|
|
||||||
(**self).on_pointer_axis(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, seat: &Seat, event: B::TouchMotionEvent) {
|
|
||||||
(**self).on_touch_motion(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, seat: &Seat, event: B::TouchCancelEvent) {
|
|
||||||
(**self).on_touch_cancel(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, config: &mut B::InputConfig) {
|
|
||||||
(**self).on_input_config_changed(config)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
use crate::backend::input::{self as backend};
|
use crate::backend::input::{self as backend, InputEvent};
|
||||||
use input as libinput;
|
use input as libinput;
|
||||||
use input::event::{
|
use input::event::{
|
||||||
device::DeviceEvent, keyboard::KeyboardEvent, pointer::PointerEvent, touch::TouchEvent, EventTrait,
|
device::DeviceEvent, keyboard::KeyboardEvent, pointer::PointerEvent, touch::TouchEvent, EventTrait,
|
||||||
};
|
};
|
||||||
use slog::Logger;
|
use slog::Logger;
|
||||||
|
|
||||||
use super::LibinputInputBackend;
|
use super::{LibinputConfig, LibinputEvent, LibinputInputBackend};
|
||||||
use std::{
|
use std::{
|
||||||
collections::hash_map::{DefaultHasher, Entry, HashMap},
|
collections::hash_map::{DefaultHasher, Entry, HashMap},
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn on_device_event<H>(
|
pub fn on_device_event<F>(
|
||||||
handler: &mut Option<H>,
|
callback: &mut F,
|
||||||
seats: &mut HashMap<libinput::Seat, backend::Seat>,
|
seats: &mut HashMap<libinput::Seat, backend::Seat>,
|
||||||
devices: &mut Vec<libinput::Device>,
|
config: &mut LibinputConfig,
|
||||||
event: DeviceEvent,
|
event: DeviceEvent,
|
||||||
logger: &Logger,
|
logger: &Logger,
|
||||||
) where
|
) where
|
||||||
H: backend::InputHandler<LibinputInputBackend>,
|
F: FnMut(InputEvent<LibinputInputBackend>, &mut LibinputConfig),
|
||||||
{
|
{
|
||||||
match event {
|
match event {
|
||||||
DeviceEvent::Added(device_added_event) => {
|
DeviceEvent::Added(device_added_event) => {
|
||||||
|
@ -38,7 +38,7 @@ pub fn on_device_event<H>(
|
||||||
added.sysname(),
|
added.sysname(),
|
||||||
device_seat.logical_name()
|
device_seat.logical_name()
|
||||||
);
|
);
|
||||||
devices.push(added);
|
config.devices.push(added.clone());
|
||||||
|
|
||||||
match seats.entry(device_seat.clone()) {
|
match seats.entry(device_seat.clone()) {
|
||||||
Entry::Occupied(mut seat_entry) => {
|
Entry::Occupied(mut seat_entry) => {
|
||||||
|
@ -49,10 +49,7 @@ pub fn on_device_event<H>(
|
||||||
caps.keyboard = new_caps.keyboard || caps.keyboard;
|
caps.keyboard = new_caps.keyboard || caps.keyboard;
|
||||||
caps.touch = new_caps.touch || caps.touch;
|
caps.touch = new_caps.touch || caps.touch;
|
||||||
}
|
}
|
||||||
if let Some(ref mut handler) = handler {
|
callback(InputEvent::SeatChanged(old_seat.clone()), config);
|
||||||
trace!(logger, "Calling on_seat_changed with {:?}", old_seat);
|
|
||||||
handler.on_seat_changed(old_seat);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Entry::Vacant(seat_entry) => {
|
Entry::Vacant(seat_entry) => {
|
||||||
let mut hasher = DefaultHasher::default();
|
let mut hasher = DefaultHasher::default();
|
||||||
|
@ -62,18 +59,17 @@ pub fn on_device_event<H>(
|
||||||
format!("{}:{}", device_seat.physical_name(), device_seat.logical_name()),
|
format!("{}:{}", device_seat.physical_name(), device_seat.logical_name()),
|
||||||
new_caps,
|
new_caps,
|
||||||
));
|
));
|
||||||
if let Some(ref mut handler) = handler {
|
callback(InputEvent::NewSeat(seat.clone()), config);
|
||||||
trace!(logger, "Calling on_seat_created with {:?}", seat);
|
|
||||||
handler.on_seat_created(seat);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
callback(InputEvent::Special(LibinputEvent::NewDevice(added)), config);
|
||||||
}
|
}
|
||||||
DeviceEvent::Removed(device_removed_event) => {
|
DeviceEvent::Removed(device_removed_event) => {
|
||||||
let removed = device_removed_event.device();
|
let removed = device_removed_event.device();
|
||||||
|
|
||||||
// remove device
|
// remove device
|
||||||
devices.retain(|dev| *dev != removed);
|
config.devices.retain(|dev| *dev != removed);
|
||||||
|
|
||||||
let device_seat = removed.seat();
|
let device_seat = removed.seat();
|
||||||
info!(
|
info!(
|
||||||
|
@ -86,15 +82,18 @@ pub fn on_device_event<H>(
|
||||||
// update capabilities, so they appear correctly on `on_seat_changed` and `on_seat_destroyed`.
|
// update capabilities, so they appear correctly on `on_seat_changed` and `on_seat_destroyed`.
|
||||||
if let Some(seat) = seats.get_mut(&device_seat) {
|
if let Some(seat) = seats.get_mut(&device_seat) {
|
||||||
let caps = seat.capabilities_mut();
|
let caps = seat.capabilities_mut();
|
||||||
caps.pointer = devices
|
caps.pointer = config
|
||||||
|
.devices
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|x| x.seat() == device_seat)
|
.filter(|x| x.seat() == device_seat)
|
||||||
.any(|x| x.has_capability(libinput::DeviceCapability::Pointer));
|
.any(|x| x.has_capability(libinput::DeviceCapability::Pointer));
|
||||||
caps.keyboard = devices
|
caps.keyboard = config
|
||||||
|
.devices
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|x| x.seat() == device_seat)
|
.filter(|x| x.seat() == device_seat)
|
||||||
.any(|x| x.has_capability(libinput::DeviceCapability::Keyboard));
|
.any(|x| x.has_capability(libinput::DeviceCapability::Keyboard));
|
||||||
caps.touch = devices
|
caps.touch = config
|
||||||
|
.devices
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|x| x.seat() == device_seat)
|
.filter(|x| x.seat() == device_seat)
|
||||||
.any(|x| x.has_capability(libinput::DeviceCapability::Touch));
|
.any(|x| x.has_capability(libinput::DeviceCapability::Touch));
|
||||||
|
@ -104,7 +103,7 @@ pub fn on_device_event<H>(
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the seat has any other devices
|
// check if the seat has any other devices
|
||||||
if !devices.iter().any(|x| x.seat() == device_seat) {
|
if !config.devices.iter().any(|x| x.seat() == device_seat) {
|
||||||
// it has not, lets destroy it
|
// it has not, lets destroy it
|
||||||
if let Some(seat) = seats.remove(&device_seat) {
|
if let Some(seat) = seats.remove(&device_seat) {
|
||||||
info!(
|
info!(
|
||||||
|
@ -112,133 +111,167 @@ pub fn on_device_event<H>(
|
||||||
"Removing seat {} which no longer has any device",
|
"Removing seat {} which no longer has any device",
|
||||||
device_seat.logical_name()
|
device_seat.logical_name()
|
||||||
);
|
);
|
||||||
if let Some(ref mut handler) = handler {
|
callback(InputEvent::SeatRemoved(seat), config);
|
||||||
trace!(logger, "Calling on_seat_destroyed with {:?}", seat);
|
|
||||||
handler.on_seat_destroyed(&seat);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
warn!(logger, "Seat destroyed that was never created");
|
warn!(logger, "Seat destroyed that was never created");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// it has, notify about updates
|
// it has, notify about updates
|
||||||
} else if let Some(ref mut handler) = handler {
|
} else if let Some(seat) = seats.get(&device_seat) {
|
||||||
if let Some(seat) = seats.get(&device_seat) {
|
callback(InputEvent::SeatChanged(seat.clone()), config);
|
||||||
trace!(logger, "Calling on_seat_changed with {:?}", seat);
|
|
||||||
handler.on_seat_changed(&seat);
|
|
||||||
} else {
|
} else {
|
||||||
warn!(logger, "Seat changed that was never created");
|
warn!(logger, "Seat changed that was never created");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
callback(InputEvent::Special(LibinputEvent::RemovedDevice(removed)), config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if let Some(ref mut handler) = handler {
|
|
||||||
handler.on_input_config_changed(devices);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn on_touch_event<H>(
|
pub fn on_touch_event<F>(
|
||||||
handler: &mut Option<H>,
|
callback: &mut F,
|
||||||
seats: &HashMap<libinput::Seat, backend::Seat>,
|
seats: &HashMap<libinput::Seat, backend::Seat>,
|
||||||
|
config: &mut LibinputConfig,
|
||||||
event: TouchEvent,
|
event: TouchEvent,
|
||||||
logger: &Logger,
|
logger: &Logger,
|
||||||
) where
|
) where
|
||||||
H: backend::InputHandler<LibinputInputBackend>,
|
F: FnMut(InputEvent<LibinputInputBackend>, &mut LibinputConfig),
|
||||||
{
|
{
|
||||||
if let Some(ref mut handler) = handler {
|
|
||||||
let device_seat = event.device().seat();
|
let device_seat = event.device().seat();
|
||||||
if let Some(ref seat) = seats.get(&device_seat) {
|
if let Some(seat) = seats.get(&device_seat).cloned() {
|
||||||
match event {
|
match event {
|
||||||
TouchEvent::Down(down_event) => {
|
TouchEvent::Down(down_event) => {
|
||||||
trace!(logger, "Calling on_touch_down with {:?}", down_event);
|
callback(
|
||||||
handler.on_touch_down(seat, down_event)
|
InputEvent::TouchDown {
|
||||||
|
seat,
|
||||||
|
event: down_event,
|
||||||
|
},
|
||||||
|
config,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
TouchEvent::Motion(motion_event) => {
|
TouchEvent::Motion(motion_event) => {
|
||||||
trace!(logger, "Calling on_touch_motion with {:?}", motion_event);
|
callback(
|
||||||
handler.on_touch_motion(seat, motion_event)
|
InputEvent::TouchMotion {
|
||||||
|
seat,
|
||||||
|
event: motion_event,
|
||||||
|
},
|
||||||
|
config,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
TouchEvent::Up(up_event) => {
|
TouchEvent::Up(up_event) => {
|
||||||
trace!(logger, "Calling on_touch_up with {:?}", up_event);
|
callback(
|
||||||
handler.on_touch_up(seat, up_event)
|
InputEvent::TouchUp {
|
||||||
|
seat,
|
||||||
|
event: up_event,
|
||||||
|
},
|
||||||
|
config,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
TouchEvent::Cancel(cancel_event) => {
|
TouchEvent::Cancel(cancel_event) => {
|
||||||
trace!(logger, "Calling on_touch_cancel with {:?}", cancel_event);
|
callback(
|
||||||
handler.on_touch_cancel(seat, cancel_event)
|
InputEvent::TouchCancel {
|
||||||
|
seat,
|
||||||
|
event: cancel_event,
|
||||||
|
},
|
||||||
|
config,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
TouchEvent::Frame(frame_event) => {
|
TouchEvent::Frame(frame_event) => {
|
||||||
trace!(logger, "Calling on_touch_frame with {:?}", frame_event);
|
callback(
|
||||||
handler.on_touch_frame(seat, frame_event)
|
InputEvent::TouchFrame {
|
||||||
|
seat,
|
||||||
|
event: frame_event,
|
||||||
|
},
|
||||||
|
config,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
warn!(logger, "Received touch event of non existing Seat");
|
warn!(logger, "Received touch event of non existing Seat");
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn on_keyboard_event<H>(
|
pub fn on_keyboard_event<F>(
|
||||||
handler: &mut Option<H>,
|
callback: &mut F,
|
||||||
seats: &HashMap<libinput::Seat, backend::Seat>,
|
seats: &HashMap<libinput::Seat, backend::Seat>,
|
||||||
|
config: &mut LibinputConfig,
|
||||||
event: KeyboardEvent,
|
event: KeyboardEvent,
|
||||||
logger: &Logger,
|
logger: &Logger,
|
||||||
) where
|
) where
|
||||||
H: backend::InputHandler<LibinputInputBackend>,
|
F: FnMut(InputEvent<LibinputInputBackend>, &mut LibinputConfig),
|
||||||
{
|
{
|
||||||
match event {
|
match event {
|
||||||
KeyboardEvent::Key(key_event) => {
|
KeyboardEvent::Key(key_event) => {
|
||||||
if let Some(ref mut handler) = handler {
|
|
||||||
let device_seat = key_event.device().seat();
|
let device_seat = key_event.device().seat();
|
||||||
if let Some(ref seat) = seats.get(&device_seat) {
|
if let Some(seat) = seats.get(&device_seat).cloned() {
|
||||||
trace!(logger, "Calling on_keyboard_key with {:?}", key_event);
|
callback(
|
||||||
handler.on_keyboard_key(seat, key_event);
|
InputEvent::Keyboard {
|
||||||
|
seat,
|
||||||
|
event: key_event,
|
||||||
|
},
|
||||||
|
config,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
warn!(logger, "Received key event of non existing Seat");
|
warn!(logger, "Received key event of non existing Seat");
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn on_pointer_event<H>(
|
pub fn on_pointer_event<F>(
|
||||||
handler: &mut Option<H>,
|
callback: &mut F,
|
||||||
seats: &HashMap<libinput::Seat, backend::Seat>,
|
seats: &HashMap<libinput::Seat, backend::Seat>,
|
||||||
|
config: &mut LibinputConfig,
|
||||||
event: PointerEvent,
|
event: PointerEvent,
|
||||||
logger: &Logger,
|
logger: &Logger,
|
||||||
) where
|
) where
|
||||||
H: backend::InputHandler<LibinputInputBackend>,
|
F: FnMut(InputEvent<LibinputInputBackend>, &mut LibinputConfig),
|
||||||
{
|
{
|
||||||
if let Some(ref mut handler) = handler {
|
|
||||||
let device_seat = event.device().seat();
|
let device_seat = event.device().seat();
|
||||||
if let Some(ref seat) = seats.get(&device_seat) {
|
if let Some(seat) = seats.get(&device_seat).cloned() {
|
||||||
match event {
|
match event {
|
||||||
PointerEvent::Motion(motion_event) => {
|
PointerEvent::Motion(motion_event) => {
|
||||||
trace!(logger, "Calling on_pointer_move with {:?}", motion_event);
|
callback(
|
||||||
handler.on_pointer_move(seat, motion_event);
|
InputEvent::PointerMotion {
|
||||||
|
seat,
|
||||||
|
event: motion_event,
|
||||||
|
},
|
||||||
|
config,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
PointerEvent::MotionAbsolute(motion_abs_event) => {
|
PointerEvent::MotionAbsolute(motion_abs_event) => {
|
||||||
trace!(
|
callback(
|
||||||
logger,
|
InputEvent::PointerMotionAbsolute {
|
||||||
"Calling on_pointer_move_absolute with {:?}",
|
seat,
|
||||||
motion_abs_event
|
event: motion_abs_event,
|
||||||
|
},
|
||||||
|
config,
|
||||||
);
|
);
|
||||||
handler.on_pointer_move_absolute(seat, motion_abs_event);
|
|
||||||
}
|
}
|
||||||
PointerEvent::Axis(axis_event) => {
|
PointerEvent::Axis(axis_event) => {
|
||||||
trace!(logger, "Calling on_pointer_axis with {:?}", axis_event);
|
callback(
|
||||||
handler.on_pointer_axis(seat, axis_event);
|
InputEvent::PointerAxis {
|
||||||
|
seat,
|
||||||
|
event: axis_event,
|
||||||
|
},
|
||||||
|
config,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
PointerEvent::Button(button_event) => {
|
PointerEvent::Button(button_event) => {
|
||||||
trace!(logger, "Calling on_pointer_button with {:?}", button_event);
|
callback(
|
||||||
handler.on_pointer_button(seat, button_event);
|
InputEvent::PointerButton {
|
||||||
|
seat,
|
||||||
|
event: button_event,
|
||||||
|
},
|
||||||
|
config,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
warn!(logger, "Received pointer event of non existing Seat");
|
warn!(logger, "Received pointer event of non existing Seat");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
mod helpers;
|
mod helpers;
|
||||||
use helpers::{on_device_event, on_keyboard_event, on_pointer_event, on_touch_event};
|
use helpers::{on_device_event, on_keyboard_event, on_pointer_event, on_touch_event};
|
||||||
|
|
||||||
use crate::backend::input::{self as backend, Axis, InputBackend};
|
use crate::backend::input::{self as backend, Axis, InputBackend, InputEvent};
|
||||||
#[cfg(feature = "backend_session")]
|
#[cfg(feature = "backend_session")]
|
||||||
use crate::backend::session::{AsErrno, Session, SessionObserver};
|
use crate::backend::session::{AsErrno, Session, SessionObserver};
|
||||||
use input as libinput;
|
use input as libinput;
|
||||||
|
@ -17,7 +17,7 @@ use std::{
|
||||||
os::unix::io::{AsRawFd, RawFd},
|
os::unix::io::{AsRawFd, RawFd},
|
||||||
};
|
};
|
||||||
|
|
||||||
use calloop::{generic::Generic, InsertError, LoopHandle, Source};
|
use calloop::{EventSource, Interest, Mode, Poll, Readiness, Token};
|
||||||
|
|
||||||
// No idea if this is the same across unix platforms
|
// No idea if this is the same across unix platforms
|
||||||
// Lets make this linux exclusive for now, once someone tries to build it for
|
// Lets make this linux exclusive for now, once someone tries to build it for
|
||||||
|
@ -31,9 +31,8 @@ const INPUT_MAJOR: u32 = 13;
|
||||||
/// context.
|
/// context.
|
||||||
pub struct LibinputInputBackend {
|
pub struct LibinputInputBackend {
|
||||||
context: libinput::Libinput,
|
context: libinput::Libinput,
|
||||||
devices: Vec<libinput::Device>,
|
config: LibinputConfig,
|
||||||
seats: HashMap<libinput::Seat, backend::Seat>,
|
seats: HashMap<libinput::Seat, backend::Seat>,
|
||||||
handler: Option<Box<dyn backend::InputHandler<LibinputInputBackend> + 'static>>,
|
|
||||||
logger: ::slog::Logger,
|
logger: ::slog::Logger,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,9 +47,8 @@ impl LibinputInputBackend {
|
||||||
info!(log, "Initializing a libinput backend");
|
info!(log, "Initializing a libinput backend");
|
||||||
LibinputInputBackend {
|
LibinputInputBackend {
|
||||||
context,
|
context,
|
||||||
devices: Vec::new(),
|
config: LibinputConfig { devices: Vec::new() },
|
||||||
seats: HashMap::new(),
|
seats: HashMap::new(),
|
||||||
handler: None,
|
|
||||||
logger: log,
|
logger: log,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -246,8 +244,30 @@ impl backend::Event for event::touch::TouchFrameEvent {
|
||||||
|
|
||||||
impl backend::TouchFrameEvent for event::touch::TouchFrameEvent {}
|
impl backend::TouchFrameEvent for event::touch::TouchFrameEvent {}
|
||||||
|
|
||||||
|
/// Special events generated by Libinput
|
||||||
|
pub enum LibinputEvent {
|
||||||
|
/// A new device was plugged in
|
||||||
|
NewDevice(libinput::Device),
|
||||||
|
/// A device was plugged out
|
||||||
|
RemovedDevice(libinput::Device),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configuration handle for libinput
|
||||||
|
///
|
||||||
|
/// This type allows you to access the list of know devices to configure them
|
||||||
|
/// if relevant
|
||||||
|
pub struct LibinputConfig {
|
||||||
|
devices: Vec<libinput::Device>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LibinputConfig {
|
||||||
|
/// Access the list of current devices
|
||||||
|
pub fn devices(&mut self) -> &mut [libinput::Device] {
|
||||||
|
&mut self.devices
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl InputBackend for LibinputInputBackend {
|
impl InputBackend for LibinputInputBackend {
|
||||||
type InputConfig = [libinput::Device];
|
|
||||||
type EventError = IoError;
|
type EventError = IoError;
|
||||||
|
|
||||||
type KeyboardKeyEvent = event::keyboard::KeyboardKeyEvent;
|
type KeyboardKeyEvent = event::keyboard::KeyboardKeyEvent;
|
||||||
|
@ -261,60 +281,60 @@ impl InputBackend for LibinputInputBackend {
|
||||||
type TouchCancelEvent = event::touch::TouchCancelEvent;
|
type TouchCancelEvent = event::touch::TouchCancelEvent;
|
||||||
type TouchFrameEvent = event::touch::TouchFrameEvent;
|
type TouchFrameEvent = event::touch::TouchFrameEvent;
|
||||||
|
|
||||||
fn set_handler<H: backend::InputHandler<Self> + 'static>(&mut self, mut handler: H) {
|
type SpecialEvent = LibinputEvent;
|
||||||
if self.handler.is_some() {
|
type InputConfig = LibinputConfig;
|
||||||
self.clear_handler();
|
|
||||||
}
|
|
||||||
info!(self.logger, "New input handler set");
|
|
||||||
for seat in self.seats.values() {
|
|
||||||
trace!(self.logger, "Calling on_seat_created with {:?}", seat);
|
|
||||||
handler.on_seat_created(seat);
|
|
||||||
}
|
|
||||||
self.handler = Some(Box::new(handler));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_handler(&mut self) -> Option<&mut dyn backend::InputHandler<Self>> {
|
fn seats(&self) -> Vec<backend::Seat> {
|
||||||
self.handler
|
self.seats.values().cloned().collect()
|
||||||
.as_mut()
|
|
||||||
.map(|handler| handler as &mut dyn backend::InputHandler<Self>)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clear_handler(&mut self) {
|
|
||||||
if let Some(mut handler) = self.handler.take() {
|
|
||||||
for seat in self.seats.values() {
|
|
||||||
trace!(self.logger, "Calling on_seat_destroyed with {:?}", seat);
|
|
||||||
handler.on_seat_destroyed(seat);
|
|
||||||
}
|
|
||||||
info!(self.logger, "Removing input handler");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn input_config(&mut self) -> &mut Self::InputConfig {
|
fn input_config(&mut self) -> &mut Self::InputConfig {
|
||||||
&mut self.devices
|
&mut self.config
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dispatch_new_events(&mut self) -> Result<(), IoError> {
|
fn dispatch_new_events<F>(&mut self, mut callback: F) -> Result<(), IoError>
|
||||||
|
where
|
||||||
|
F: FnMut(InputEvent<Self>, &mut LibinputConfig),
|
||||||
|
{
|
||||||
self.context.dispatch()?;
|
self.context.dispatch()?;
|
||||||
|
|
||||||
for event in &mut self.context {
|
for event in &mut self.context {
|
||||||
match event {
|
match event {
|
||||||
libinput::Event::Device(device_event) => {
|
libinput::Event::Device(device_event) => {
|
||||||
on_device_event(
|
on_device_event(
|
||||||
&mut self.handler,
|
&mut callback,
|
||||||
&mut self.seats,
|
&mut self.seats,
|
||||||
&mut self.devices,
|
&mut self.config,
|
||||||
device_event,
|
device_event,
|
||||||
&self.logger,
|
&self.logger,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
libinput::Event::Touch(touch_event) => {
|
libinput::Event::Touch(touch_event) => {
|
||||||
on_touch_event(&mut self.handler, &self.seats, touch_event, &self.logger);
|
on_touch_event(
|
||||||
|
&mut callback,
|
||||||
|
&self.seats,
|
||||||
|
&mut self.config,
|
||||||
|
touch_event,
|
||||||
|
&self.logger,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
libinput::Event::Keyboard(keyboard_event) => {
|
libinput::Event::Keyboard(keyboard_event) => {
|
||||||
on_keyboard_event(&mut self.handler, &self.seats, keyboard_event, &self.logger);
|
on_keyboard_event(
|
||||||
|
&mut callback,
|
||||||
|
&self.seats,
|
||||||
|
&mut self.config,
|
||||||
|
keyboard_event,
|
||||||
|
&self.logger,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
libinput::Event::Pointer(pointer_event) => {
|
libinput::Event::Pointer(pointer_event) => {
|
||||||
on_pointer_event(&mut self.handler, &self.seats, pointer_event, &self.logger);
|
on_pointer_event(
|
||||||
|
&mut callback,
|
||||||
|
&self.seats,
|
||||||
|
&mut self.config,
|
||||||
|
pointer_event,
|
||||||
|
&self.logger,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
_ => {} //FIXME: What to do with the rest.
|
_ => {} //FIXME: What to do with the rest.
|
||||||
}
|
}
|
||||||
|
@ -421,24 +441,27 @@ impl AsRawFd for LibinputInputBackend {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// calloop source associated with the libinput backend
|
impl EventSource for LibinputInputBackend {
|
||||||
pub type LibinputSource = Generic<LibinputInputBackend>;
|
type Event = InputEvent<LibinputInputBackend>;
|
||||||
|
type Metadata = LibinputConfig;
|
||||||
|
type Ret = ();
|
||||||
|
|
||||||
/// Binds a [`LibinputInputBackend`] to a given [`LoopHandle`].
|
fn process_events<F>(&mut self, _: Readiness, _: Token, callback: F) -> std::io::Result<()>
|
||||||
///
|
where
|
||||||
/// Automatically feeds the backend with incoming events without any manual calls to
|
F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
|
||||||
/// [`dispatch_new_events`](InputBackend::dispatch_new_events). Should be used to achieve the smallest possible latency.
|
{
|
||||||
pub fn libinput_bind<Data: 'static>(
|
self.dispatch_new_events(callback)
|
||||||
backend: LibinputInputBackend,
|
}
|
||||||
handle: LoopHandle<Data>,
|
|
||||||
) -> Result<Source<LibinputSource>, InsertError<LibinputSource>> {
|
fn register(&mut self, poll: &mut Poll, token: Token) -> std::io::Result<()> {
|
||||||
let source = Generic::new(backend, calloop::Interest::Readable, calloop::Mode::Level);
|
poll.register(self.as_raw_fd(), Interest::Readable, Mode::Level, token)
|
||||||
|
}
|
||||||
handle.insert_source(source, move |_, backend, _| {
|
|
||||||
if let Err(error) = backend.dispatch_new_events() {
|
fn reregister(&mut self, poll: &mut Poll, token: Token) -> std::io::Result<()> {
|
||||||
warn!(backend.logger, "Libinput errored: {}", error);
|
poll.reregister(self.as_raw_fd(), Interest::Readable, Mode::Level, token)
|
||||||
return Err(std::io::Error::new(std::io::ErrorKind::Other, Box::new(error)));
|
}
|
||||||
|
|
||||||
|
fn unregister(&mut self, poll: &mut Poll) -> std::io::Result<()> {
|
||||||
|
poll.unregister(self.as_raw_fd())
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use crate::backend::{
|
||||||
egl::{context::GlAttributes, native, EGLContext, EGLSurface, Error as EGLError, SurfaceCreationError},
|
egl::{context::GlAttributes, native, EGLContext, EGLSurface, Error as EGLError, SurfaceCreationError},
|
||||||
graphics::{gl::GLGraphicsBackend, CursorBackend, PixelFormat, SwapBuffersError},
|
graphics::{gl::GLGraphicsBackend, CursorBackend, PixelFormat, SwapBuffersError},
|
||||||
input::{
|
input::{
|
||||||
Axis, AxisSource, Event as BackendEvent, InputBackend, InputHandler, KeyState, KeyboardKeyEvent,
|
Axis, AxisSource, Event as BackendEvent, InputBackend, InputEvent, KeyState, KeyboardKeyEvent,
|
||||||
MouseButton, MouseButtonState, PointerAxisEvent, PointerButtonEvent, PointerMotionAbsoluteEvent,
|
MouseButton, MouseButtonState, PointerAxisEvent, PointerButtonEvent, PointerMotionAbsoluteEvent,
|
||||||
Seat, SeatCapabilities, TouchCancelEvent, TouchDownEvent, TouchMotionEvent, TouchSlot, TouchUpEvent,
|
Seat, SeatCapabilities, TouchCancelEvent, TouchDownEvent, TouchMotionEvent, TouchSlot, TouchUpEvent,
|
||||||
UnusedEvent,
|
UnusedEvent,
|
||||||
|
@ -94,13 +94,10 @@ pub struct WinitGraphicsBackend {
|
||||||
/// periodically to receive any events.
|
/// periodically to receive any events.
|
||||||
pub struct WinitInputBackend {
|
pub struct WinitInputBackend {
|
||||||
events_loop: EventLoop<()>,
|
events_loop: EventLoop<()>,
|
||||||
events_handler: Option<Box<dyn WinitEventsHandler>>,
|
|
||||||
window: Rc<Window>,
|
window: Rc<Window>,
|
||||||
time: Instant,
|
time: Instant,
|
||||||
key_counter: u32,
|
key_counter: u32,
|
||||||
seat: Seat,
|
seat: Seat,
|
||||||
input_config: (),
|
|
||||||
handler: Option<Box<dyn InputHandler<WinitInputBackend> + 'static>>,
|
|
||||||
logger: ::slog::Logger,
|
logger: ::slog::Logger,
|
||||||
size: Rc<RefCell<WindowSize>>,
|
size: Rc<RefCell<WindowSize>>,
|
||||||
}
|
}
|
||||||
|
@ -211,7 +208,6 @@ where
|
||||||
},
|
},
|
||||||
WinitInputBackend {
|
WinitInputBackend {
|
||||||
events_loop,
|
events_loop,
|
||||||
events_handler: None,
|
|
||||||
window,
|
window,
|
||||||
time: Instant::now(),
|
time: Instant::now(),
|
||||||
key_counter: 0,
|
key_counter: 0,
|
||||||
|
@ -224,24 +220,25 @@ where
|
||||||
touch: true,
|
touch: true,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
input_config: (),
|
|
||||||
handler: None,
|
|
||||||
logger: log.new(o!("smithay_winit_component" => "input")),
|
logger: log.new(o!("smithay_winit_component" => "input")),
|
||||||
size,
|
size,
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handler trait to receive window-related events to provide a better *nested* experience.
|
/// Specific events generated by Winit
|
||||||
pub trait WinitEventsHandler {
|
pub enum WinitEvent {
|
||||||
/// The window was resized, can be used to adjust the associated [`Output`](::wayland::output::Output)s mode.
|
/// The window has been resized
|
||||||
///
|
Resized {
|
||||||
/// Here are provided the new size (in physical pixels) and the new scale factor provided by `winit`.
|
/// The new physical size (in pixels)
|
||||||
fn resized(&mut self, size: (f64, f64), scale: f64);
|
size: (f64, f64),
|
||||||
/// The window gained or lost focus
|
/// The new scale factor
|
||||||
fn focus_changed(&mut self, focused: bool);
|
scale_factor: f64,
|
||||||
/// The window needs to be redrawn
|
},
|
||||||
fn refresh(&mut self);
|
/// The focus state of the window changed
|
||||||
|
Focus(bool),
|
||||||
|
/// A redraw was requested
|
||||||
|
Refresh,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WinitGraphicsBackend {
|
impl WinitGraphicsBackend {
|
||||||
|
@ -611,29 +608,12 @@ impl TouchCancelEvent for WinitTouchCancelledEvent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WinitInputBackend {
|
/// Input config for Winit
|
||||||
/// Set the events handler
|
///
|
||||||
pub fn set_events_handler<H: WinitEventsHandler + 'static>(&mut self, handler: H) {
|
/// This backend does not allow any input configuration, so this type does nothing.
|
||||||
self.events_handler = Some(Box::new(handler));
|
pub struct WinitInputConfig;
|
||||||
info!(self.logger, "New events handler set.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get a reference to the set events handler, if any
|
|
||||||
pub fn get_events_handler(&mut self) -> Option<&mut dyn WinitEventsHandler> {
|
|
||||||
self.events_handler
|
|
||||||
.as_mut()
|
|
||||||
.map(|handler| &mut **handler as &mut dyn WinitEventsHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Clear out the currently set events handler
|
|
||||||
pub fn clear_events_handler(&mut self) {
|
|
||||||
self.events_handler = None;
|
|
||||||
info!(self.logger, "Events handler unset.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InputBackend for WinitInputBackend {
|
impl InputBackend for WinitInputBackend {
|
||||||
type InputConfig = ();
|
|
||||||
type EventError = WinitInputError;
|
type EventError = WinitInputError;
|
||||||
|
|
||||||
type KeyboardKeyEvent = WinitKeyboardInputEvent;
|
type KeyboardKeyEvent = WinitKeyboardInputEvent;
|
||||||
|
@ -647,32 +627,17 @@ impl InputBackend for WinitInputBackend {
|
||||||
type TouchCancelEvent = WinitTouchCancelledEvent;
|
type TouchCancelEvent = WinitTouchCancelledEvent;
|
||||||
type TouchFrameEvent = UnusedEvent;
|
type TouchFrameEvent = UnusedEvent;
|
||||||
|
|
||||||
fn set_handler<H: InputHandler<Self> + 'static>(&mut self, mut handler: H) {
|
type SpecialEvent = WinitEvent;
|
||||||
if self.handler.is_some() {
|
type InputConfig = WinitInputConfig;
|
||||||
self.clear_handler();
|
|
||||||
}
|
|
||||||
info!(self.logger, "New input handler set.");
|
|
||||||
trace!(self.logger, "Calling on_seat_created with {:?}", self.seat);
|
|
||||||
handler.on_seat_created(&self.seat);
|
|
||||||
self.handler = Some(Box::new(handler));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_handler(&mut self) -> Option<&mut dyn InputHandler<Self>> {
|
fn seats(&self) -> Vec<Seat> {
|
||||||
self.handler
|
vec![self.seat.clone()]
|
||||||
.as_mut()
|
|
||||||
.map(|handler| handler as &mut dyn InputHandler<Self>)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clear_handler(&mut self) {
|
|
||||||
if let Some(mut handler) = self.handler.take() {
|
|
||||||
trace!(self.logger, "Calling on_seat_destroyed with {:?}", self.seat);
|
|
||||||
handler.on_seat_destroyed(&self.seat);
|
|
||||||
}
|
|
||||||
info!(self.logger, "Removing input handler");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn input_config(&mut self) -> &mut Self::InputConfig {
|
fn input_config(&mut self) -> &mut Self::InputConfig {
|
||||||
&mut self.input_config
|
/// So much effort to return a useless singleton!
|
||||||
|
static mut CONFIG: WinitInputConfig = WinitInputConfig;
|
||||||
|
unsafe { &mut CONFIG }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Processes new events of the underlying event loop to drive the set [`InputHandler`].
|
/// Processes new events of the underlying event loop to drive the set [`InputHandler`].
|
||||||
|
@ -687,7 +652,10 @@ impl InputBackend for WinitInputBackend {
|
||||||
///
|
///
|
||||||
/// The linked [`WinitGraphicsBackend`] will error with a lost context and should
|
/// The linked [`WinitGraphicsBackend`] will error with a lost context and should
|
||||||
/// not be used anymore as well.
|
/// not be used anymore as well.
|
||||||
fn dispatch_new_events(&mut self) -> ::std::result::Result<(), WinitInputError> {
|
fn dispatch_new_events<F>(&mut self, mut callback: F) -> ::std::result::Result<(), WinitInputError>
|
||||||
|
where
|
||||||
|
F: FnMut(InputEvent<Self>, &mut WinitInputConfig),
|
||||||
|
{
|
||||||
let mut closed = false;
|
let mut closed = false;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -701,10 +669,9 @@ impl InputBackend for WinitInputBackend {
|
||||||
let time = &self.time;
|
let time = &self.time;
|
||||||
let seat = &self.seat;
|
let seat = &self.seat;
|
||||||
let window = &self.window;
|
let window = &self.window;
|
||||||
let mut handler = self.handler.as_mut();
|
|
||||||
let mut events_handler = self.events_handler.as_mut();
|
|
||||||
let logger = &self.logger;
|
let logger = &self.logger;
|
||||||
let window_size = &self.size;
|
let window_size = &self.size;
|
||||||
|
let mut callback = move |event| callback(event, &mut WinitInputConfig);
|
||||||
|
|
||||||
self.events_loop
|
self.events_loop
|
||||||
.run_return(move |event, _target, control_flow| match event {
|
.run_return(move |event, _target, control_flow| match event {
|
||||||
|
@ -712,16 +679,14 @@ impl InputBackend for WinitInputBackend {
|
||||||
*control_flow = ControlFlow::Exit;
|
*control_flow = ControlFlow::Exit;
|
||||||
}
|
}
|
||||||
Event::RedrawRequested(_id) => {
|
Event::RedrawRequested(_id) => {
|
||||||
if let Some(events_handler) = events_handler.as_mut() {
|
callback(InputEvent::Special(WinitEvent::Refresh));
|
||||||
events_handler.refresh();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Event::WindowEvent { event, .. } => {
|
Event::WindowEvent { event, .. } => {
|
||||||
let duration = Instant::now().duration_since(*time);
|
let duration = Instant::now().duration_since(*time);
|
||||||
let nanos = duration.subsec_nanos() as u64;
|
let nanos = duration.subsec_nanos() as u64;
|
||||||
let time = ((1000 * duration.as_secs()) + (nanos / 1_000_000)) as u32;
|
let time = ((1000 * duration.as_secs()) + (nanos / 1_000_000)) as u32;
|
||||||
match (event, handler.as_mut(), events_handler.as_mut()) {
|
match event {
|
||||||
(WindowEvent::Resized(psize), _, events_handler) => {
|
WindowEvent::Resized(psize) => {
|
||||||
trace!(logger, "Resizing window to {:?}", psize);
|
trace!(logger, "Resizing window to {:?}", psize);
|
||||||
let scale_factor = window.window().scale_factor();
|
let scale_factor = window.window().scale_factor();
|
||||||
let mut wsize = window_size.borrow_mut();
|
let mut wsize = window_size.borrow_mut();
|
||||||
|
@ -730,156 +695,140 @@ impl InputBackend for WinitInputBackend {
|
||||||
if let Window::Wayland { ref surface, .. } = **window {
|
if let Window::Wayland { ref surface, .. } = **window {
|
||||||
surface.resize(psize.width as i32, psize.height as i32, 0, 0);
|
surface.resize(psize.width as i32, psize.height as i32, 0, 0);
|
||||||
}
|
}
|
||||||
if let Some(events_handler) = events_handler {
|
callback(InputEvent::Special(WinitEvent::Resized {
|
||||||
events_handler.resized(psize.into(), scale_factor);
|
size: psize.into(),
|
||||||
|
scale_factor,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
WindowEvent::Focused(focus) => {
|
||||||
|
callback(InputEvent::Special(WinitEvent::Focus(focus)));
|
||||||
}
|
}
|
||||||
(WindowEvent::Focused(focus), _, Some(events_handler)) => {
|
|
||||||
events_handler.focus_changed(focus)
|
|
||||||
}
|
|
||||||
(
|
|
||||||
WindowEvent::ScaleFactorChanged {
|
WindowEvent::ScaleFactorChanged {
|
||||||
scale_factor,
|
scale_factor,
|
||||||
new_inner_size: new_psize,
|
new_inner_size: new_psize,
|
||||||
},
|
} => {
|
||||||
_,
|
|
||||||
events_handler,
|
|
||||||
) => {
|
|
||||||
let mut wsize = window_size.borrow_mut();
|
let mut wsize = window_size.borrow_mut();
|
||||||
wsize.scale_factor = scale_factor;
|
wsize.scale_factor = scale_factor;
|
||||||
if let Window::Wayland { ref surface, .. } = **window {
|
if let Window::Wayland { ref surface, .. } = **window {
|
||||||
surface.resize(new_psize.width as i32, new_psize.height as i32, 0, 0);
|
surface.resize(new_psize.width as i32, new_psize.height as i32, 0, 0);
|
||||||
}
|
}
|
||||||
if let Some(events_handler) = events_handler {
|
let psize_f64: (f64, f64) = (new_psize.width.into(), new_psize.height.into());
|
||||||
let psize_f64: (f64, f64) =
|
callback(InputEvent::Special(WinitEvent::Resized {
|
||||||
(new_psize.width.into(), new_psize.height.into());
|
size: psize_f64,
|
||||||
events_handler.resized(psize_f64, wsize.scale_factor);
|
scale_factor: wsize.scale_factor,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
(
|
|
||||||
WindowEvent::KeyboardInput {
|
WindowEvent::KeyboardInput {
|
||||||
input: KeyboardInput { scancode, state, .. },
|
input: KeyboardInput { scancode, state, .. },
|
||||||
..
|
..
|
||||||
},
|
} => {
|
||||||
Some(handler),
|
|
||||||
_,
|
|
||||||
) => {
|
|
||||||
match state {
|
match state {
|
||||||
ElementState::Pressed => *key_counter += 1,
|
ElementState::Pressed => *key_counter += 1,
|
||||||
ElementState::Released => {
|
ElementState::Released => {
|
||||||
*key_counter = key_counter.checked_sub(1).unwrap_or(0)
|
*key_counter = key_counter.checked_sub(1).unwrap_or(0)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
trace!(logger, "Calling on_keyboard_key with {:?}", (scancode, state));
|
callback(InputEvent::Keyboard {
|
||||||
handler.on_keyboard_key(
|
seat: seat.clone(),
|
||||||
seat,
|
event: WinitKeyboardInputEvent {
|
||||||
WinitKeyboardInputEvent {
|
|
||||||
time,
|
time,
|
||||||
key: scancode,
|
key: scancode,
|
||||||
count: *key_counter,
|
count: *key_counter,
|
||||||
state,
|
state,
|
||||||
},
|
},
|
||||||
)
|
});
|
||||||
}
|
}
|
||||||
(WindowEvent::CursorMoved { position, .. }, Some(handler), _) => {
|
WindowEvent::CursorMoved { position, .. } => {
|
||||||
trace!(logger, "Calling on_pointer_move_absolute with {:?}", position);
|
|
||||||
let lpos = position.to_logical(window_size.borrow().scale_factor);
|
let lpos = position.to_logical(window_size.borrow().scale_factor);
|
||||||
handler.on_pointer_move_absolute(
|
callback(InputEvent::PointerMotionAbsolute {
|
||||||
seat,
|
seat: seat.clone(),
|
||||||
WinitMouseMovedEvent {
|
event: WinitMouseMovedEvent {
|
||||||
size: window_size.clone(),
|
size: window_size.clone(),
|
||||||
time,
|
time,
|
||||||
logical_position: lpos,
|
logical_position: lpos,
|
||||||
},
|
},
|
||||||
)
|
});
|
||||||
}
|
}
|
||||||
(WindowEvent::MouseWheel { delta, .. }, Some(handler), _) => {
|
WindowEvent::MouseWheel { delta, .. } => {
|
||||||
let event = WinitMouseWheelEvent { time, delta };
|
let event = WinitMouseWheelEvent { time, delta };
|
||||||
trace!(logger, "Calling on_pointer_axis with {:?}", delta);
|
callback(InputEvent::PointerAxis {
|
||||||
handler.on_pointer_axis(seat, event);
|
seat: seat.clone(),
|
||||||
|
event,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
(WindowEvent::MouseInput { state, button, .. }, Some(handler), _) => {
|
WindowEvent::MouseInput { state, button, .. } => {
|
||||||
trace!(logger, "Calling on_pointer_button with {:?}", (button, state));
|
callback(InputEvent::PointerButton {
|
||||||
handler.on_pointer_button(seat, WinitMouseInputEvent { time, button, state })
|
seat: seat.clone(),
|
||||||
|
event: WinitMouseInputEvent { time, button, state },
|
||||||
|
});
|
||||||
}
|
}
|
||||||
(
|
|
||||||
WindowEvent::Touch(Touch {
|
WindowEvent::Touch(Touch {
|
||||||
phase: TouchPhase::Started,
|
phase: TouchPhase::Started,
|
||||||
location,
|
location,
|
||||||
id,
|
id,
|
||||||
..
|
..
|
||||||
}),
|
}) => {
|
||||||
Some(handler),
|
callback(InputEvent::TouchDown {
|
||||||
_,
|
seat: seat.clone(),
|
||||||
) => {
|
event: WinitTouchStartedEvent {
|
||||||
trace!(logger, "Calling on_touch_down at {:?}", location);
|
|
||||||
handler.on_touch_down(
|
|
||||||
seat,
|
|
||||||
WinitTouchStartedEvent {
|
|
||||||
size: window_size.clone(),
|
size: window_size.clone(),
|
||||||
time,
|
time,
|
||||||
location: location.into(),
|
location: location.into(),
|
||||||
id,
|
id,
|
||||||
},
|
},
|
||||||
)
|
});
|
||||||
}
|
}
|
||||||
(
|
|
||||||
WindowEvent::Touch(Touch {
|
WindowEvent::Touch(Touch {
|
||||||
phase: TouchPhase::Moved,
|
phase: TouchPhase::Moved,
|
||||||
location,
|
location,
|
||||||
id,
|
id,
|
||||||
..
|
..
|
||||||
}),
|
}) => {
|
||||||
Some(handler),
|
callback(InputEvent::TouchMotion {
|
||||||
_,
|
seat: seat.clone(),
|
||||||
) => {
|
event: WinitTouchMovedEvent {
|
||||||
trace!(logger, "Calling on_touch_motion at {:?}", location);
|
|
||||||
handler.on_touch_motion(
|
|
||||||
seat,
|
|
||||||
WinitTouchMovedEvent {
|
|
||||||
size: window_size.clone(),
|
size: window_size.clone(),
|
||||||
time,
|
time,
|
||||||
location: location.into(),
|
location: location.into(),
|
||||||
id,
|
id,
|
||||||
},
|
},
|
||||||
)
|
});
|
||||||
}
|
}
|
||||||
(
|
|
||||||
WindowEvent::Touch(Touch {
|
WindowEvent::Touch(Touch {
|
||||||
phase: TouchPhase::Ended,
|
phase: TouchPhase::Ended,
|
||||||
location,
|
location,
|
||||||
id,
|
id,
|
||||||
..
|
..
|
||||||
}),
|
}) => {
|
||||||
Some(handler),
|
callback(InputEvent::TouchMotion {
|
||||||
_,
|
seat: seat.clone(),
|
||||||
) => {
|
event: WinitTouchMovedEvent {
|
||||||
trace!(logger, "Calling on_touch_motion at {:?}", location);
|
|
||||||
handler.on_touch_motion(
|
|
||||||
seat,
|
|
||||||
WinitTouchMovedEvent {
|
|
||||||
size: window_size.clone(),
|
size: window_size.clone(),
|
||||||
time,
|
time,
|
||||||
location: location.into(),
|
location: location.into(),
|
||||||
id,
|
id,
|
||||||
},
|
},
|
||||||
);
|
});
|
||||||
trace!(logger, "Calling on_touch_up");
|
callback(InputEvent::TouchUp {
|
||||||
handler.on_touch_up(seat, WinitTouchEndedEvent { time, id });
|
seat: seat.clone(),
|
||||||
|
event: WinitTouchEndedEvent { time, id },
|
||||||
|
})
|
||||||
}
|
}
|
||||||
(
|
|
||||||
WindowEvent::Touch(Touch {
|
WindowEvent::Touch(Touch {
|
||||||
phase: TouchPhase::Cancelled,
|
phase: TouchPhase::Cancelled,
|
||||||
id,
|
id,
|
||||||
..
|
..
|
||||||
}),
|
}) => {
|
||||||
Some(handler),
|
callback(InputEvent::TouchCancel {
|
||||||
_,
|
seat: seat.clone(),
|
||||||
) => {
|
event: WinitTouchCancelledEvent { time, id },
|
||||||
trace!(logger, "Calling on_touch_cancel");
|
});
|
||||||
handler.on_touch_cancel(seat, WinitTouchCancelledEvent { time, id })
|
|
||||||
}
|
}
|
||||||
(WindowEvent::CloseRequested, _, _) | (WindowEvent::Destroyed, _, _) => {
|
WindowEvent::CloseRequested | WindowEvent::Destroyed => {
|
||||||
warn!(logger, "Window closed");
|
warn!(logger, "Window closed");
|
||||||
*closed_ptr = true;
|
*closed_ptr = true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue