Add Forward/Back mouse buttons
This commit is contained in:
parent
e1400a1926
commit
3283010d2c
|
@ -10,6 +10,9 @@
|
||||||
- `XdgPositionerState` moved to `XdgPopupState` and added to `XdgRequest::NewPopup`
|
- `XdgPositionerState` moved to `XdgPopupState` and added to `XdgRequest::NewPopup`
|
||||||
- `PopupSurface::send_configure` now checks the protocol version and returns an `Result`
|
- `PopupSurface::send_configure` now checks the protocol version and returns an `Result`
|
||||||
- `KeyboardHandle::input` filter closure now receives a `KeysymHandle` instead of a `Keysym` and returns a `FilterResult`.
|
- `KeyboardHandle::input` filter closure now receives a `KeysymHandle` instead of a `Keysym` and returns a `FilterResult`.
|
||||||
|
- `PointerButtonEvent::button` now returns an `Option<MouseButton>`.
|
||||||
|
- `MouseButton` is now non-exhaustive.
|
||||||
|
- Remove `Other` and add `Forward` and `Back` variants to `MouseButton`. Use the new `PointerButtonEvent::button_code` in place of `Other`.
|
||||||
|
|
||||||
#### Backends
|
#### Backends
|
||||||
|
|
||||||
|
@ -40,6 +43,7 @@
|
||||||
- `x11rb` event source integration used in anvil's XWayland implementation is now part of smithay at `utils::x11rb`. Enabled through the `x11rb_event_source` feature.
|
- `x11rb` event source integration used in anvil's XWayland implementation is now part of smithay at `utils::x11rb`. Enabled through the `x11rb_event_source` feature.
|
||||||
- `KeyState`, `MouseButton`, `ButtonState` and `Axis` in `backend::input` now derive `Hash`.
|
- `KeyState`, `MouseButton`, `ButtonState` and `Axis` in `backend::input` now derive `Hash`.
|
||||||
- New `DrmNode` type in drm backend. This is primarily for use a backend which needs to run as client inside another session.
|
- New `DrmNode` type in drm backend. This is primarily for use a backend which needs to run as client inside another session.
|
||||||
|
- The button code for a `PointerButtonEvent` may now be obtained using `PointerButtonEvent::button_code`.
|
||||||
|
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
||||||
|
|
|
@ -86,12 +86,7 @@ impl<Backend> AnvilState<Backend> {
|
||||||
|
|
||||||
fn on_pointer_button<B: InputBackend>(&mut self, 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 = evt.button_code();
|
||||||
input::MouseButton::Left => 0x110,
|
|
||||||
input::MouseButton::Right => 0x111,
|
|
||||||
input::MouseButton::Middle => 0x112,
|
|
||||||
input::MouseButton::Other(b) => b as u32,
|
|
||||||
};
|
|
||||||
let state = match evt.state() {
|
let state = match evt.state() {
|
||||||
input::ButtonState::Pressed => {
|
input::ButtonState::Pressed => {
|
||||||
// change the keyboard focus unless the pointer is grabbed
|
// change the keyboard focus unless the pointer is grabbed
|
||||||
|
|
|
@ -117,6 +117,7 @@ impl<B: InputBackend> KeyboardKeyEvent<B> for UnusedEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A particular mouse button
|
/// A particular mouse button
|
||||||
|
#[non_exhaustive]
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
|
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
|
||||||
pub enum MouseButton {
|
pub enum MouseButton {
|
||||||
/// Left mouse button
|
/// Left mouse button
|
||||||
|
@ -125,8 +126,10 @@ pub enum MouseButton {
|
||||||
Middle,
|
Middle,
|
||||||
/// Right mouse button
|
/// Right mouse button
|
||||||
Right,
|
Right,
|
||||||
/// Other mouse button with index
|
/// Forward mouse button.
|
||||||
Other(u8),
|
Forward,
|
||||||
|
/// Back mouse button.
|
||||||
|
Back,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// State of a button on a pointer device, like mouse or tablet tool. Either pressed or released
|
/// State of a button on a pointer device, like mouse or tablet tool. Either pressed or released
|
||||||
|
@ -140,14 +143,35 @@ pub enum ButtonState {
|
||||||
|
|
||||||
/// Common methods pointer event generated by pressed buttons do implement
|
/// Common methods pointer event generated by pressed buttons do implement
|
||||||
pub trait PointerButtonEvent<B: InputBackend>: Event<B> {
|
pub trait PointerButtonEvent<B: InputBackend>: Event<B> {
|
||||||
/// Pressed button of the event
|
/// Pressed button of the event.
|
||||||
fn button(&self) -> MouseButton;
|
///
|
||||||
|
/// This may return [`None`] if the button pressed in the event is not a standard mouse button. You may
|
||||||
|
/// obtain the button code using [`PointerButtonEvent::button_code`].
|
||||||
|
fn button(&self) -> Option<MouseButton> {
|
||||||
|
match self.button_code() {
|
||||||
|
0x110 => Some(MouseButton::Left),
|
||||||
|
0x111 => Some(MouseButton::Right),
|
||||||
|
0x112 => Some(MouseButton::Middle),
|
||||||
|
0x115 => Some(MouseButton::Forward),
|
||||||
|
0x116 => Some(MouseButton::Back),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the numerical button code of the mouse button.
|
||||||
|
///
|
||||||
|
/// The value will correspond to one `BTN_` constants from the Linux [input event codes] inside
|
||||||
|
/// `input-event-codes.h`.
|
||||||
|
///
|
||||||
|
/// [input event codes]: https://gitlab.freedesktop.org/libinput/libinput/-/blob/main/include/linux/linux/input-event-codes.h
|
||||||
|
fn button_code(&self) -> u32;
|
||||||
|
|
||||||
/// State of the button
|
/// State of the button
|
||||||
fn state(&self) -> ButtonState;
|
fn state(&self) -> ButtonState;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B: InputBackend> PointerButtonEvent<B> for UnusedEvent {
|
impl<B: InputBackend> PointerButtonEvent<B> for UnusedEvent {
|
||||||
fn button(&self) -> MouseButton {
|
fn button_code(&self) -> u32 {
|
||||||
match *self {}
|
match *self {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -620,3 +644,17 @@ pub enum InputEvent<B: InputBackend> {
|
||||||
/// Special event specific of this backend
|
/// Special event specific of this backend
|
||||||
Special(B::SpecialEvent),
|
Special(B::SpecialEvent),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Converts an xorg mouse button to the format used by libinput.
|
||||||
|
///
|
||||||
|
/// Taken from https://sources.debian.org/src/xserver-xorg-input-libinput/1.1.0-1/src/xf86libinput.c/?hl=1508#L236-L252
|
||||||
|
#[cfg(any(feature = "backend_winit", feature = "backend_x11"))]
|
||||||
|
pub(crate) fn xorg_mouse_to_libinput(xorg: u32) -> u32 {
|
||||||
|
match xorg {
|
||||||
|
0 => 0,
|
||||||
|
1 => 0x110, // BTN_LEFT
|
||||||
|
2 => 0x112, // BTN_MIDDLE
|
||||||
|
3 => 0x111, // BTN_RIGHT
|
||||||
|
_ => xorg - 8 + 0x113, // BTN_SIZE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -188,13 +188,8 @@ impl backend::Event<LibinputInputBackend> for event::pointer::PointerButtonEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
impl backend::PointerButtonEvent<LibinputInputBackend> for event::pointer::PointerButtonEvent {
|
impl backend::PointerButtonEvent<LibinputInputBackend> for event::pointer::PointerButtonEvent {
|
||||||
fn button(&self) -> backend::MouseButton {
|
fn button_code(&self) -> u32 {
|
||||||
match self.button() {
|
self.button()
|
||||||
0x110 => backend::MouseButton::Left,
|
|
||||||
0x111 => backend::MouseButton::Right,
|
|
||||||
0x112 => backend::MouseButton::Middle,
|
|
||||||
x => backend::MouseButton::Other(x as u8),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn state(&self) -> backend::ButtonState {
|
fn state(&self) -> backend::ButtonState {
|
||||||
|
|
|
@ -6,9 +6,9 @@ use winit::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::backend::input::{
|
use crate::backend::input::{
|
||||||
Axis, AxisSource, ButtonState, Device, DeviceCapability, Event, InputBackend, InputEvent, KeyState,
|
self, Axis, AxisSource, ButtonState, Device, DeviceCapability, Event, InputBackend, InputEvent, KeyState,
|
||||||
KeyboardKeyEvent, MouseButton, PointerAxisEvent, PointerButtonEvent, PointerMotionAbsoluteEvent,
|
KeyboardKeyEvent, PointerAxisEvent, PointerButtonEvent, PointerMotionAbsoluteEvent, TouchCancelEvent,
|
||||||
TouchCancelEvent, TouchDownEvent, TouchMotionEvent, TouchSlot, TouchUpEvent, UnusedEvent,
|
TouchDownEvent, TouchMotionEvent, TouchSlot, TouchUpEvent, UnusedEvent,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{WindowSize, WinitError};
|
use super::{WindowSize, WinitError};
|
||||||
|
@ -170,6 +170,7 @@ pub struct WinitMouseInputEvent {
|
||||||
pub(crate) time: u32,
|
pub(crate) time: u32,
|
||||||
pub(crate) button: WinitMouseButton,
|
pub(crate) button: WinitMouseButton,
|
||||||
pub(crate) state: ElementState,
|
pub(crate) state: ElementState,
|
||||||
|
pub(crate) is_x11: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Event<WinitInput> for WinitMouseInputEvent {
|
impl Event<WinitInput> for WinitMouseInputEvent {
|
||||||
|
@ -183,8 +184,19 @@ impl Event<WinitInput> for WinitMouseInputEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PointerButtonEvent<WinitInput> for WinitMouseInputEvent {
|
impl PointerButtonEvent<WinitInput> for WinitMouseInputEvent {
|
||||||
fn button(&self) -> MouseButton {
|
fn button_code(&self) -> u32 {
|
||||||
self.button.into()
|
match self.button {
|
||||||
|
WinitMouseButton::Left => 0x110,
|
||||||
|
WinitMouseButton::Right => 0x111,
|
||||||
|
WinitMouseButton::Middle => 0x112,
|
||||||
|
WinitMouseButton::Other(b) => {
|
||||||
|
if self.is_x11 {
|
||||||
|
input::xorg_mouse_to_libinput(b as u32)
|
||||||
|
} else {
|
||||||
|
b as u32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn state(&self) -> ButtonState {
|
fn state(&self) -> ButtonState {
|
||||||
|
@ -332,17 +344,6 @@ impl TouchCancelEvent<WinitInput> for WinitTouchCancelledEvent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<WinitMouseButton> for MouseButton {
|
|
||||||
fn from(button: WinitMouseButton) -> MouseButton {
|
|
||||||
match button {
|
|
||||||
WinitMouseButton::Left => MouseButton::Left,
|
|
||||||
WinitMouseButton::Right => MouseButton::Right,
|
|
||||||
WinitMouseButton::Middle => MouseButton::Middle,
|
|
||||||
WinitMouseButton::Other(num) => MouseButton::Other(num as u8),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<ElementState> for KeyState {
|
impl From<ElementState> for KeyState {
|
||||||
fn from(state: ElementState) -> Self {
|
fn from(state: ElementState) -> Self {
|
||||||
match state {
|
match state {
|
||||||
|
|
|
@ -106,6 +106,8 @@ pub struct WinitEventLoop {
|
||||||
initialized: bool,
|
initialized: bool,
|
||||||
size: Rc<RefCell<WindowSize>>,
|
size: Rc<RefCell<WindowSize>>,
|
||||||
resize_notification: Rc<Cell<Option<Size<i32, Physical>>>>,
|
resize_notification: Rc<Cell<Option<Size<i32, Physical>>>>,
|
||||||
|
/// Whether winit is using Wayland or X11 as it's backend.
|
||||||
|
is_x11: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new [`WinitGraphicsBackend`], which implements the [`Renderer`] trait and a corresponding
|
/// Create a new [`WinitGraphicsBackend`], which implements the [`Renderer`] trait and a corresponding
|
||||||
|
@ -164,41 +166,47 @@ where
|
||||||
debug!(log, "Window created");
|
debug!(log, "Window created");
|
||||||
|
|
||||||
let reqs = Default::default();
|
let reqs = Default::default();
|
||||||
let (display, context, surface) = {
|
let (display, context, surface, is_x11) = {
|
||||||
let display = EGLDisplay::new(&winit_window, log.clone())?;
|
let display = EGLDisplay::new(&winit_window, log.clone())?;
|
||||||
let context = EGLContext::new_with_config(&display, attributes, reqs, log.clone())?;
|
let context = EGLContext::new_with_config(&display, attributes, reqs, log.clone())?;
|
||||||
|
|
||||||
let surface = if let Some(wl_surface) = winit_window.wayland_surface() {
|
let (surface, is_x11) = if let Some(wl_surface) = winit_window.wayland_surface() {
|
||||||
debug!(log, "Winit backend: Wayland");
|
debug!(log, "Winit backend: Wayland");
|
||||||
let size = winit_window.inner_size();
|
let size = winit_window.inner_size();
|
||||||
let surface = unsafe {
|
let surface = unsafe {
|
||||||
wegl::WlEglSurface::new_from_raw(wl_surface as *mut _, size.width as i32, size.height as i32)
|
wegl::WlEglSurface::new_from_raw(wl_surface as *mut _, size.width as i32, size.height as i32)
|
||||||
};
|
};
|
||||||
EGLSurface::new(
|
(
|
||||||
&display,
|
EGLSurface::new(
|
||||||
context.pixel_format().unwrap(),
|
&display,
|
||||||
context.config_id(),
|
context.pixel_format().unwrap(),
|
||||||
surface,
|
context.config_id(),
|
||||||
log.clone(),
|
surface,
|
||||||
|
log.clone(),
|
||||||
|
)
|
||||||
|
.map_err(EGLError::CreationFailed)?,
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.map_err(EGLError::CreationFailed)?
|
|
||||||
} else if let Some(xlib_window) = winit_window.xlib_window().map(native::XlibWindow) {
|
} else if let Some(xlib_window) = winit_window.xlib_window().map(native::XlibWindow) {
|
||||||
debug!(log, "Winit backend: X11");
|
debug!(log, "Winit backend: X11");
|
||||||
EGLSurface::new(
|
(
|
||||||
&display,
|
EGLSurface::new(
|
||||||
context.pixel_format().unwrap(),
|
&display,
|
||||||
context.config_id(),
|
context.pixel_format().unwrap(),
|
||||||
xlib_window,
|
context.config_id(),
|
||||||
log.clone(),
|
xlib_window,
|
||||||
|
log.clone(),
|
||||||
|
)
|
||||||
|
.map_err(EGLError::CreationFailed)?,
|
||||||
|
true,
|
||||||
)
|
)
|
||||||
.map_err(EGLError::CreationFailed)?
|
|
||||||
} else {
|
} else {
|
||||||
unreachable!("No backends for winit other then Wayland and X11 are supported")
|
unreachable!("No backends for winit other then Wayland and X11 are supported")
|
||||||
};
|
};
|
||||||
|
|
||||||
let _ = context.unbind();
|
let _ = context.unbind();
|
||||||
|
|
||||||
(display, context, surface)
|
(display, context, surface, is_x11)
|
||||||
};
|
};
|
||||||
|
|
||||||
let (w, h): (u32, u32) = winit_window.inner_size().into();
|
let (w, h): (u32, u32) = winit_window.inner_size().into();
|
||||||
|
@ -230,6 +238,7 @@ where
|
||||||
initialized: false,
|
initialized: false,
|
||||||
logger: log.new(o!("smithay_winit_component" => "event_loop")),
|
logger: log.new(o!("smithay_winit_component" => "event_loop")),
|
||||||
size,
|
size,
|
||||||
|
is_x11,
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -338,6 +347,7 @@ impl WinitEventLoop {
|
||||||
let resize_notification = &self.resize_notification;
|
let resize_notification = &self.resize_notification;
|
||||||
let logger = &self.logger;
|
let logger = &self.logger;
|
||||||
let window_size = &self.size;
|
let window_size = &self.size;
|
||||||
|
let is_x11 = self.is_x11;
|
||||||
|
|
||||||
if !self.initialized {
|
if !self.initialized {
|
||||||
callback(Input(InputEvent::DeviceAdded {
|
callback(Input(InputEvent::DeviceAdded {
|
||||||
|
@ -428,7 +438,12 @@ impl WinitEventLoop {
|
||||||
}
|
}
|
||||||
WindowEvent::MouseInput { state, button, .. } => {
|
WindowEvent::MouseInput { state, button, .. } => {
|
||||||
callback(Input(InputEvent::PointerButton {
|
callback(Input(InputEvent::PointerButton {
|
||||||
event: WinitMouseInputEvent { time, button, state },
|
event: WinitMouseInputEvent {
|
||||||
|
time,
|
||||||
|
button,
|
||||||
|
state,
|
||||||
|
is_x11,
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,7 @@ use super::X11Error;
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::input::{
|
backend::input::{
|
||||||
self, Axis, AxisSource, ButtonState, Device, DeviceCapability, InputBackend, InputEvent, KeyState,
|
self, Axis, AxisSource, ButtonState, Device, DeviceCapability, InputBackend, InputEvent, KeyState,
|
||||||
KeyboardKeyEvent, MouseButton, PointerAxisEvent, PointerButtonEvent, PointerMotionAbsoluteEvent,
|
KeyboardKeyEvent, PointerAxisEvent, PointerButtonEvent, PointerMotionAbsoluteEvent, UnusedEvent,
|
||||||
UnusedEvent,
|
|
||||||
},
|
},
|
||||||
utils::{Logical, Size},
|
utils::{Logical, Size},
|
||||||
};
|
};
|
||||||
|
@ -120,7 +119,7 @@ impl PointerAxisEvent<X11Input> for X11MouseWheelEvent {
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub struct X11MouseInputEvent {
|
pub struct X11MouseInputEvent {
|
||||||
pub(crate) time: u32,
|
pub(crate) time: u32,
|
||||||
pub(crate) button: MouseButton,
|
pub(crate) raw: u32,
|
||||||
pub(crate) state: ButtonState,
|
pub(crate) state: ButtonState,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,8 +134,8 @@ impl input::Event<X11Input> for X11MouseInputEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PointerButtonEvent<X11Input> for X11MouseInputEvent {
|
impl PointerButtonEvent<X11Input> for X11MouseInputEvent {
|
||||||
fn button(&self) -> MouseButton {
|
fn button_code(&self) -> u32 {
|
||||||
self.button
|
input::xorg_mouse_to_libinput(self.raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn state(&self) -> ButtonState {
|
fn state(&self) -> ButtonState {
|
||||||
|
|
|
@ -59,7 +59,7 @@ use crate::{
|
||||||
backend::{
|
backend::{
|
||||||
allocator::dmabuf::{AsDmabuf, Dmabuf},
|
allocator::dmabuf::{AsDmabuf, Dmabuf},
|
||||||
drm::{DrmNode, NodeType},
|
drm::{DrmNode, NodeType},
|
||||||
input::{Axis, ButtonState, InputEvent, KeyState, MouseButton},
|
input::{Axis, ButtonState, InputEvent, KeyState},
|
||||||
},
|
},
|
||||||
utils::{x11rb::X11Source, Logical, Size},
|
utils::{x11rb::X11Source, Logical, Size},
|
||||||
};
|
};
|
||||||
|
@ -625,115 +625,69 @@ impl EventSource for X11Backend {
|
||||||
// 6 => Axis::Horizontal -1.0
|
// 6 => Axis::Horizontal -1.0
|
||||||
// 7 => Axis::Horizontal +1.0
|
// 7 => Axis::Horizontal +1.0
|
||||||
// Others => ??
|
// Others => ??
|
||||||
match button_press.detail {
|
|
||||||
1..=3 => {
|
|
||||||
// Clicking a button.
|
|
||||||
callback(
|
|
||||||
Input(InputEvent::PointerButton {
|
|
||||||
event: X11MouseInputEvent {
|
|
||||||
time: button_press.time,
|
|
||||||
button: match button_press.detail {
|
|
||||||
1 => MouseButton::Left,
|
|
||||||
|
|
||||||
// Confusion: XCB docs for ButtonIndex and what plasma does don't match?
|
// Scrolling
|
||||||
2 => MouseButton::Middle,
|
if button_press.detail >= 4 && button_press.detail <= 7 {
|
||||||
|
callback(
|
||||||
|
Input(InputEvent::PointerAxis {
|
||||||
|
event: X11MouseWheelEvent {
|
||||||
|
time: button_press.time,
|
||||||
|
axis: match button_press.detail {
|
||||||
|
// Up | Down
|
||||||
|
4 | 5 => Axis::Vertical,
|
||||||
|
|
||||||
3 => MouseButton::Right,
|
// Right | Left
|
||||||
|
6 | 7 => Axis::Horizontal,
|
||||||
|
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
|
||||||
state: ButtonState::Pressed,
|
|
||||||
},
|
},
|
||||||
}),
|
amount: match button_press.detail {
|
||||||
&mut event_window,
|
// Up | Right
|
||||||
)
|
4 | 7 => 1.0,
|
||||||
}
|
|
||||||
|
|
||||||
4..=7 => {
|
// Down | Left
|
||||||
// Scrolling
|
5 | 6 => -1.0,
|
||||||
callback(
|
|
||||||
Input(InputEvent::PointerAxis {
|
|
||||||
event: X11MouseWheelEvent {
|
|
||||||
time: button_press.time,
|
|
||||||
axis: match button_press.detail {
|
|
||||||
// Up | Down
|
|
||||||
4 | 5 => Axis::Vertical,
|
|
||||||
|
|
||||||
// Right | Left
|
_ => unreachable!(),
|
||||||
6 | 7 => Axis::Horizontal,
|
|
||||||
|
|
||||||
_ => unreachable!(),
|
|
||||||
},
|
|
||||||
amount: match button_press.detail {
|
|
||||||
// Up | Right
|
|
||||||
4 | 7 => 1.0,
|
|
||||||
|
|
||||||
// Down | Left
|
|
||||||
5 | 6 => -1.0,
|
|
||||||
|
|
||||||
_ => unreachable!(),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}),
|
},
|
||||||
&mut event_window,
|
}),
|
||||||
)
|
&mut event_window,
|
||||||
}
|
)
|
||||||
|
} else {
|
||||||
// Unknown mouse button
|
callback(
|
||||||
_ => callback(
|
|
||||||
Input(InputEvent::PointerButton {
|
Input(InputEvent::PointerButton {
|
||||||
event: X11MouseInputEvent {
|
event: X11MouseInputEvent {
|
||||||
time: button_press.time,
|
time: button_press.time,
|
||||||
button: MouseButton::Other(button_press.detail),
|
raw: button_press.detail as u32,
|
||||||
state: ButtonState::Pressed,
|
state: ButtonState::Pressed,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
&mut event_window,
|
&mut event_window,
|
||||||
),
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
x11::Event::ButtonRelease(button_release) => {
|
x11::Event::ButtonRelease(button_release) => {
|
||||||
if button_release.event == window.id {
|
if button_release.event == window.id {
|
||||||
match button_release.detail {
|
// Ignore release tick because this event is always sent immediately after the press
|
||||||
1..=3 => {
|
// tick for scrolling and the backend will dispatch release event automatically during
|
||||||
// Releasing a button.
|
// the press event.
|
||||||
callback(
|
if button_release.detail >= 4 && button_release.detail <= 7 {
|
||||||
Input(InputEvent::PointerButton {
|
return;
|
||||||
event: X11MouseInputEvent {
|
|
||||||
time: button_release.time,
|
|
||||||
button: match button_release.detail {
|
|
||||||
1 => MouseButton::Left,
|
|
||||||
|
|
||||||
2 => MouseButton::Middle,
|
|
||||||
|
|
||||||
3 => MouseButton::Right,
|
|
||||||
|
|
||||||
_ => unreachable!(),
|
|
||||||
},
|
|
||||||
state: ButtonState::Released,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
&mut event_window,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// We may ignore the release tick for scrolling, as the X server will
|
|
||||||
// always emit this immediately after press.
|
|
||||||
4..=7 => (),
|
|
||||||
|
|
||||||
_ => callback(
|
|
||||||
Input(InputEvent::PointerButton {
|
|
||||||
event: X11MouseInputEvent {
|
|
||||||
time: button_release.time,
|
|
||||||
button: MouseButton::Other(button_release.detail),
|
|
||||||
state: ButtonState::Released,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
&mut event_window,
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
callback(
|
||||||
|
Input(InputEvent::PointerButton {
|
||||||
|
event: X11MouseInputEvent {
|
||||||
|
time: button_release.time,
|
||||||
|
raw: button_release.detail as u32,
|
||||||
|
state: ButtonState::Released,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
&mut event_window,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue