winit-core: revise MouseButton type
Unify the values of `MouseButton` and thus remove `Other` variant in limit possible buttons to 32, which was picked based on platform capabilities, where 32 is the highest. For the reference, SDL has identical limit.
This commit is contained in:
parent
779f52a21f
commit
9d9d21cfdb
8 changed files with 191 additions and 229 deletions
|
|
@ -1095,14 +1095,11 @@ fn mouse_button(event: &NSEvent) -> MouseButton {
|
|||
// For the other events, it's always set to 0.
|
||||
// MacOS only defines the left, right and middle buttons, 3..=31 are left as generic buttons,
|
||||
// but 3 and 4 are very commonly used as Back and Forward by hardware vendors and applications.
|
||||
match event.buttonNumber() {
|
||||
0 => MouseButton::Left,
|
||||
1 => MouseButton::Right,
|
||||
2 => MouseButton::Middle,
|
||||
3 => MouseButton::Back,
|
||||
4 => MouseButton::Forward,
|
||||
n => MouseButton::Other(n as u16),
|
||||
}
|
||||
let b: isize = event.buttonNumber();
|
||||
b.try_into()
|
||||
.ok()
|
||||
.and_then(MouseButton::try_from_u8)
|
||||
.expect("expected MacOS button number in the range 0..=31")
|
||||
}
|
||||
|
||||
// NOTE: to get option as alt working we need to rewrite events
|
||||
|
|
|
|||
|
|
@ -531,26 +531,22 @@ pub enum ButtonSource {
|
|||
button: TabletToolButton,
|
||||
data: TabletToolData,
|
||||
},
|
||||
/// A pointer button of unknown source.
|
||||
///
|
||||
/// Codes are undefined and may not be reproducible across platforms or winit versions.
|
||||
Unknown(u16),
|
||||
}
|
||||
|
||||
impl ButtonSource {
|
||||
/// Convert any [`ButtonSource`] to an equivalent [`MouseButton`]. If a pointer type has no
|
||||
/// Try to convert a [`ButtonSource`] to an equivalent [`MouseButton`]. If a pointer type has no
|
||||
/// special handling in an application, this method can be used to handle it like any generic
|
||||
/// mouse input.
|
||||
pub fn mouse_button(self) -> MouseButton {
|
||||
pub fn mouse_button(self) -> Option<MouseButton> {
|
||||
match self {
|
||||
ButtonSource::Mouse(mouse) => mouse,
|
||||
ButtonSource::Touch { .. } => MouseButton::Left,
|
||||
ButtonSource::Mouse(mouse) => Some(mouse),
|
||||
ButtonSource::Touch { .. } => Some(MouseButton::Left),
|
||||
ButtonSource::TabletTool { button, .. } => button.into(),
|
||||
ButtonSource::Unknown(button) => match button {
|
||||
0 => MouseButton::Left,
|
||||
1 => MouseButton::Middle,
|
||||
2 => MouseButton::Right,
|
||||
3 => MouseButton::Back,
|
||||
4 => MouseButton::Forward,
|
||||
_ => MouseButton::Other(button),
|
||||
},
|
||||
ButtonSource::Unknown(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1323,21 +1319,114 @@ impl ElementState {
|
|||
}
|
||||
}
|
||||
|
||||
/// Describes a button of a mouse controller.
|
||||
/// Identifies a button of a mouse controller.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// **macOS:** `Back` and `Forward` might not work with all hardware.
|
||||
/// **Orbital:** `Back` and `Forward` are unsupported due to orbital not supporting them.
|
||||
/// The first three buttons should be supported on all platforms.
|
||||
/// [`Self::Back`] and [`Self::Forward`] are supported on most platforms
|
||||
/// (when using a compatible mouse).
|
||||
///
|
||||
/// - **Android, iOS:** Currently not supported.
|
||||
/// - **Orbital:** Only left/right/middle buttons are supported at this time.
|
||||
/// - **Web, Windows:** Supports left/right/middle/back/forward buttons.
|
||||
/// - **Wayland:** Supports buttons 0..=15.
|
||||
/// - **macOS:** Supports all button variants.
|
||||
/// - **X11:** Technically supports further buttons than this (0..=250), these are emitted in
|
||||
/// `ButtonSource::Unknown`.
|
||||
#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[repr(u8)]
|
||||
pub enum MouseButton {
|
||||
Left,
|
||||
Right,
|
||||
Middle,
|
||||
Back,
|
||||
Forward,
|
||||
Other(u16),
|
||||
/// The primary (usually left) button
|
||||
Left = 0,
|
||||
/// The secondary (usually right) button
|
||||
Right = 1,
|
||||
/// The tertiary (usually middle) button
|
||||
Middle = 2,
|
||||
/// The first side button, frequently assigned a back function
|
||||
Back = 3,
|
||||
/// The second side button, frequently assigned a forward function
|
||||
Forward = 4,
|
||||
/// The sixth button
|
||||
Button6 = 5,
|
||||
/// The seventh button
|
||||
Button7 = 6,
|
||||
/// The eighth button
|
||||
Button8 = 7,
|
||||
/// The ninth button
|
||||
Button9 = 8,
|
||||
/// The tenth button
|
||||
Button10 = 9,
|
||||
/// The eleventh button
|
||||
Button11 = 10,
|
||||
/// The twelfth button
|
||||
Button12 = 11,
|
||||
/// The thirteenth button
|
||||
Button13 = 12,
|
||||
/// The fourteenth button
|
||||
Button14 = 13,
|
||||
/// The fifteenth button
|
||||
Button15 = 14,
|
||||
/// The sixteenth button
|
||||
Button16 = 15,
|
||||
Button17 = 16,
|
||||
Button18 = 17,
|
||||
Button19 = 18,
|
||||
Button20 = 19,
|
||||
Button21 = 20,
|
||||
Button22 = 21,
|
||||
Button23 = 22,
|
||||
Button24 = 23,
|
||||
Button25 = 24,
|
||||
Button26 = 25,
|
||||
Button27 = 26,
|
||||
Button28 = 27,
|
||||
Button29 = 28,
|
||||
Button30 = 29,
|
||||
Button31 = 30,
|
||||
Button32 = 31,
|
||||
}
|
||||
|
||||
impl MouseButton {
|
||||
/// Construct from a `u8` if within the range `0..=31`
|
||||
pub fn try_from_u8(b: u8) -> Option<MouseButton> {
|
||||
Some(match b {
|
||||
0 => MouseButton::Left,
|
||||
1 => MouseButton::Right,
|
||||
2 => MouseButton::Middle,
|
||||
3 => MouseButton::Back,
|
||||
4 => MouseButton::Forward,
|
||||
5 => MouseButton::Button6,
|
||||
6 => MouseButton::Button7,
|
||||
7 => MouseButton::Button8,
|
||||
8 => MouseButton::Button9,
|
||||
9 => MouseButton::Button10,
|
||||
10 => MouseButton::Button11,
|
||||
11 => MouseButton::Button12,
|
||||
12 => MouseButton::Button13,
|
||||
13 => MouseButton::Button14,
|
||||
14 => MouseButton::Button15,
|
||||
15 => MouseButton::Button16,
|
||||
16 => MouseButton::Button17,
|
||||
17 => MouseButton::Button18,
|
||||
18 => MouseButton::Button19,
|
||||
19 => MouseButton::Button20,
|
||||
20 => MouseButton::Button21,
|
||||
21 => MouseButton::Button22,
|
||||
22 => MouseButton::Button23,
|
||||
23 => MouseButton::Button24,
|
||||
24 => MouseButton::Button25,
|
||||
25 => MouseButton::Button26,
|
||||
26 => MouseButton::Button27,
|
||||
27 => MouseButton::Button28,
|
||||
28 => MouseButton::Button29,
|
||||
29 => MouseButton::Button30,
|
||||
30 => MouseButton::Button31,
|
||||
31 => MouseButton::Button32,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes a button of a tool, e.g. a pen.
|
||||
|
|
@ -1349,16 +1438,16 @@ pub enum TabletToolButton {
|
|||
Other(u16),
|
||||
}
|
||||
|
||||
impl From<TabletToolButton> for MouseButton {
|
||||
impl From<TabletToolButton> for Option<MouseButton> {
|
||||
fn from(tool: TabletToolButton) -> Self {
|
||||
match tool {
|
||||
Some(match tool {
|
||||
TabletToolButton::Contact => MouseButton::Left,
|
||||
TabletToolButton::Barrel => MouseButton::Right,
|
||||
TabletToolButton::Other(1) => MouseButton::Middle,
|
||||
TabletToolButton::Other(3) => MouseButton::Back,
|
||||
TabletToolButton::Other(4) => MouseButton::Forward,
|
||||
TabletToolButton::Other(other) => MouseButton::Other(other),
|
||||
}
|
||||
TabletToolButton::Other(_) => return None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1492,7 +1581,7 @@ mod tests {
|
|||
primary: true,
|
||||
state: event::ElementState::Pressed,
|
||||
position: (0, 0).into(),
|
||||
button: event::MouseButton::Other(0).into(),
|
||||
button: event::ButtonSource::Unknown(0),
|
||||
});
|
||||
with_window_event(PointerButton {
|
||||
device_id: None,
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ use sctk::seat::SeatState;
|
|||
use dpi::{LogicalPosition, PhysicalPosition};
|
||||
use winit_core::event::{
|
||||
ElementState, MouseButton, MouseScrollDelta, PointerKind, PointerSource, TouchPhase,
|
||||
WindowEvent,
|
||||
WindowEvent, ButtonSource,
|
||||
};
|
||||
|
||||
use crate::state::WinitState;
|
||||
|
|
@ -108,8 +108,8 @@ impl PointerHandler for WinitState {
|
|||
if parent_surface != surface =>
|
||||
{
|
||||
let click = match wayland_button_to_winit(button) {
|
||||
MouseButton::Left => FrameClick::Normal,
|
||||
MouseButton::Right => FrameClick::Alternate,
|
||||
ButtonSource::Mouse(MouseButton::Left) => FrameClick::Normal,
|
||||
ButtonSource::Mouse(MouseButton::Right) => FrameClick::Alternate,
|
||||
_ => continue,
|
||||
};
|
||||
let pressed = matches!(kind, PointerEventKind::Press { .. });
|
||||
|
|
@ -186,7 +186,7 @@ impl PointerHandler for WinitState {
|
|||
device_id: None,
|
||||
state,
|
||||
position,
|
||||
button: button.into(),
|
||||
button,
|
||||
},
|
||||
window_id,
|
||||
);
|
||||
|
|
@ -409,23 +409,16 @@ impl Default for WinitPointerDataInner {
|
|||
}
|
||||
|
||||
/// Convert the Wayland button into winit.
|
||||
fn wayland_button_to_winit(button: u32) -> MouseButton {
|
||||
fn wayland_button_to_winit(button: u32) -> ButtonSource {
|
||||
// These values are coming from <linux/input-event-codes.h>.
|
||||
const BTN_LEFT: u32 = 0x110;
|
||||
const BTN_RIGHT: u32 = 0x111;
|
||||
const BTN_MIDDLE: u32 = 0x112;
|
||||
const BTN_SIDE: u32 = 0x113;
|
||||
const BTN_EXTRA: u32 = 0x114;
|
||||
const BTN_FORWARD: u32 = 0x115;
|
||||
const BTN_BACK: u32 = 0x116;
|
||||
const BTN_MOUSE: u32 = 0x110;
|
||||
const BTN_JOYSTICK: u32 = 0x120;
|
||||
|
||||
match button {
|
||||
BTN_LEFT => MouseButton::Left,
|
||||
BTN_RIGHT => MouseButton::Right,
|
||||
BTN_MIDDLE => MouseButton::Middle,
|
||||
BTN_BACK | BTN_SIDE => MouseButton::Back,
|
||||
BTN_FORWARD | BTN_EXTRA => MouseButton::Forward,
|
||||
button => MouseButton::Other(button as u16),
|
||||
if (BTN_MOUSE..BTN_JOYSTICK).contains(&button) {
|
||||
// Mapping orders match
|
||||
MouseButton::try_from_u8((button - BTN_MOUSE) as u8).unwrap().into()
|
||||
} else {
|
||||
ButtonSource::Unknown(button as u16)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,43 +27,7 @@ bitflags::bitflags! {
|
|||
const BACK = 0b001000;
|
||||
const FORWARD = 0b010000;
|
||||
const ERASER = 0b100000;
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ButtonsState> for MouseButton {
|
||||
fn from(value: ButtonsState) -> Self {
|
||||
match value {
|
||||
ButtonsState::LEFT => MouseButton::Left,
|
||||
ButtonsState::RIGHT => MouseButton::Right,
|
||||
ButtonsState::MIDDLE => MouseButton::Middle,
|
||||
ButtonsState::BACK => MouseButton::Back,
|
||||
ButtonsState::FORWARD => MouseButton::Forward,
|
||||
_ => MouseButton::Other(value.bits()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ButtonSource> for ButtonsState {
|
||||
fn from(value: ButtonSource) -> Self {
|
||||
match value {
|
||||
ButtonSource::TabletTool { button, .. } => button.into(),
|
||||
other => ButtonsState::from(other.mouse_button()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MouseButton> for ButtonsState {
|
||||
fn from(value: MouseButton) -> Self {
|
||||
match value {
|
||||
MouseButton::Left => ButtonsState::LEFT,
|
||||
MouseButton::Right => ButtonsState::RIGHT,
|
||||
MouseButton::Middle => ButtonsState::MIDDLE,
|
||||
MouseButton::Back => ButtonsState::BACK,
|
||||
MouseButton::Forward => ButtonsState::FORWARD,
|
||||
MouseButton::Other(value) => ButtonsState::from_bits_retain(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
||||
impl From<TabletToolButton> for ButtonsState {
|
||||
fn from(tool: TabletToolButton) -> Self {
|
||||
|
|
@ -92,14 +56,16 @@ pub fn raw_button(event: &MouseEvent) -> Option<u16> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn mouse_button(button: u16) -> MouseButton {
|
||||
pub fn mouse_button(button: u16) -> ButtonSource {
|
||||
match button {
|
||||
0 => MouseButton::Left,
|
||||
1 => MouseButton::Middle,
|
||||
2 => MouseButton::Right,
|
||||
3 => MouseButton::Back,
|
||||
4 => MouseButton::Forward,
|
||||
other => MouseButton::Other(other),
|
||||
0 => MouseButton::Left.into(),
|
||||
1 => MouseButton::Middle.into(),
|
||||
2 => MouseButton::Right.into(),
|
||||
3 => MouseButton::Back.into(),
|
||||
4 => MouseButton::Forward.into(),
|
||||
// Codes above 4 are not observed on Firefox or Chromium. 5 is defined as an eraser,
|
||||
// which is not a mouse button. No other codes are defined.
|
||||
i => ButtonSource::Unknown(i),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,10 +7,9 @@ use winit_core::event::{ButtonSource, DeviceId, ElementState, PointerKind, Point
|
|||
use winit_core::keyboard::ModifiersState;
|
||||
|
||||
use super::canvas::Common;
|
||||
use super::event;
|
||||
use super::event::{self, ButtonsState};
|
||||
use super::event_handle::EventListenerHandle;
|
||||
use crate::event::mkdid;
|
||||
use crate::web_sys::event::ButtonsState;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub(super) struct PointerHandler {
|
||||
|
|
@ -84,7 +83,7 @@ impl PointerHandler {
|
|||
let button = event::raw_button(&event).expect("no button pressed");
|
||||
|
||||
let source = match event::pointer_source(&event, kind) {
|
||||
PointerSource::Mouse => ButtonSource::Mouse(event::mouse_button(button)),
|
||||
PointerSource::Mouse => event::mouse_button(button),
|
||||
PointerSource::Touch { finger_id, force } => {
|
||||
ButtonSource::Touch { finger_id, force }
|
||||
},
|
||||
|
|
@ -138,7 +137,7 @@ impl PointerHandler {
|
|||
// care if it fails.
|
||||
let _e = canvas.set_pointer_capture(pointer_id);
|
||||
|
||||
ButtonSource::Mouse(event::mouse_button(button))
|
||||
event::mouse_button(button)
|
||||
},
|
||||
PointerSource::Touch { finger_id, force } => {
|
||||
ButtonSource::Touch { finger_id, force }
|
||||
|
|
@ -217,7 +216,7 @@ impl PointerHandler {
|
|||
};
|
||||
|
||||
let button = match event::pointer_source(&event, kind) {
|
||||
PointerSource::Mouse => ButtonSource::Mouse(event::mouse_button(button)),
|
||||
PointerSource::Mouse => event::mouse_button(button),
|
||||
PointerSource::Touch { finger_id, force } => {
|
||||
if button != 0 {
|
||||
tracing::error!("unexpected touch button id: {button}");
|
||||
|
|
|
|||
|
|
@ -1705,9 +1705,9 @@ unsafe fn public_window_callback_inner(
|
|||
}
|
||||
},
|
||||
|
||||
WM_LBUTTONDOWN => {
|
||||
WM_LBUTTONDOWN | WM_RBUTTONDOWN | WM_MBUTTONDOWN => {
|
||||
use winit_core::event::ElementState::Pressed;
|
||||
use winit_core::event::MouseButton::Left;
|
||||
use winit_core::event::MouseButton;
|
||||
use winit_core::event::WindowEvent::PointerButton;
|
||||
|
||||
unsafe { capture_mouse(window, &mut userdata.window_state_lock()) };
|
||||
|
|
@ -1723,14 +1723,20 @@ unsafe fn public_window_callback_inner(
|
|||
primary: true,
|
||||
state: Pressed,
|
||||
position,
|
||||
button: Left.into(),
|
||||
button: match msg {
|
||||
WM_LBUTTONDOWN => MouseButton::Left,
|
||||
WM_RBUTTONDOWN => MouseButton::Right,
|
||||
WM_MBUTTONDOWN => MouseButton::Middle,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
.into(),
|
||||
});
|
||||
result = ProcResult::Value(0);
|
||||
},
|
||||
|
||||
WM_LBUTTONUP => {
|
||||
WM_LBUTTONUP | WM_RBUTTONUP | WM_MBUTTONUP => {
|
||||
use winit_core::event::ElementState::Released;
|
||||
use winit_core::event::MouseButton::Left;
|
||||
use winit_core::event::MouseButton;
|
||||
use winit_core::event::WindowEvent::PointerButton;
|
||||
|
||||
unsafe { release_mouse(userdata.window_state_lock()) };
|
||||
|
|
@ -1746,106 +1752,20 @@ unsafe fn public_window_callback_inner(
|
|||
primary: true,
|
||||
state: Released,
|
||||
position,
|
||||
button: Left.into(),
|
||||
});
|
||||
result = ProcResult::Value(0);
|
||||
},
|
||||
|
||||
WM_RBUTTONDOWN => {
|
||||
use winit_core::event::ElementState::Pressed;
|
||||
use winit_core::event::MouseButton::Right;
|
||||
use winit_core::event::WindowEvent::PointerButton;
|
||||
|
||||
unsafe { capture_mouse(window, &mut userdata.window_state_lock()) };
|
||||
|
||||
update_modifiers(window, userdata);
|
||||
|
||||
let x = util::get_x_lparam(lparam as u32) as i32;
|
||||
let y = util::get_y_lparam(lparam as u32) as i32;
|
||||
let position = PhysicalPosition::new(x as f64, y as f64);
|
||||
|
||||
userdata.send_window_event(window, PointerButton {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
state: Pressed,
|
||||
position,
|
||||
button: Right.into(),
|
||||
});
|
||||
result = ProcResult::Value(0);
|
||||
},
|
||||
|
||||
WM_RBUTTONUP => {
|
||||
use winit_core::event::ElementState::Released;
|
||||
use winit_core::event::MouseButton::Right;
|
||||
use winit_core::event::WindowEvent::PointerButton;
|
||||
|
||||
unsafe { release_mouse(userdata.window_state_lock()) };
|
||||
|
||||
update_modifiers(window, userdata);
|
||||
|
||||
let x = util::get_x_lparam(lparam as u32) as i32;
|
||||
let y = util::get_y_lparam(lparam as u32) as i32;
|
||||
let position = PhysicalPosition::new(x as f64, y as f64);
|
||||
|
||||
userdata.send_window_event(window, PointerButton {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
state: Released,
|
||||
position,
|
||||
button: Right.into(),
|
||||
});
|
||||
result = ProcResult::Value(0);
|
||||
},
|
||||
|
||||
WM_MBUTTONDOWN => {
|
||||
use winit_core::event::ElementState::Pressed;
|
||||
use winit_core::event::MouseButton::Middle;
|
||||
use winit_core::event::WindowEvent::PointerButton;
|
||||
|
||||
unsafe { capture_mouse(window, &mut userdata.window_state_lock()) };
|
||||
|
||||
update_modifiers(window, userdata);
|
||||
|
||||
let x = util::get_x_lparam(lparam as u32) as i32;
|
||||
let y = util::get_y_lparam(lparam as u32) as i32;
|
||||
let position = PhysicalPosition::new(x as f64, y as f64);
|
||||
|
||||
userdata.send_window_event(window, PointerButton {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
state: Pressed,
|
||||
position,
|
||||
button: Middle.into(),
|
||||
});
|
||||
result = ProcResult::Value(0);
|
||||
},
|
||||
|
||||
WM_MBUTTONUP => {
|
||||
use winit_core::event::ElementState::Released;
|
||||
use winit_core::event::MouseButton::Middle;
|
||||
use winit_core::event::WindowEvent::PointerButton;
|
||||
|
||||
unsafe { release_mouse(userdata.window_state_lock()) };
|
||||
|
||||
update_modifiers(window, userdata);
|
||||
|
||||
let x = util::get_x_lparam(lparam as u32) as i32;
|
||||
let y = util::get_y_lparam(lparam as u32) as i32;
|
||||
let position = PhysicalPosition::new(x as f64, y as f64);
|
||||
|
||||
userdata.send_window_event(window, PointerButton {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
state: Released,
|
||||
position,
|
||||
button: Middle.into(),
|
||||
button: match msg {
|
||||
WM_LBUTTONUP => MouseButton::Left,
|
||||
WM_RBUTTONUP => MouseButton::Right,
|
||||
WM_MBUTTONUP => MouseButton::Middle,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
.into(),
|
||||
});
|
||||
result = ProcResult::Value(0);
|
||||
},
|
||||
|
||||
WM_XBUTTONDOWN => {
|
||||
use winit_core::event::ElementState::Pressed;
|
||||
use winit_core::event::MouseButton::{Back, Forward, Other};
|
||||
use winit_core::event::MouseButton;
|
||||
use winit_core::event::WindowEvent::PointerButton;
|
||||
let xbutton = util::get_xbutton_wparam(wparam as u32);
|
||||
|
||||
|
|
@ -1857,25 +1777,25 @@ unsafe fn public_window_callback_inner(
|
|||
let y = util::get_y_lparam(lparam as u32) as i32;
|
||||
let position = PhysicalPosition::new(x as f64, y as f64);
|
||||
|
||||
// 1 is defined as back, 2 as forward; other codes are unexpected.
|
||||
let b = xbutton as u8 + MouseButton::Back as u8 - 1;
|
||||
|
||||
userdata.send_window_event(window, PointerButton {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
state: Pressed,
|
||||
position,
|
||||
button: match xbutton {
|
||||
1 => Back,
|
||||
2 => Forward,
|
||||
_ => Other(xbutton),
|
||||
}
|
||||
.into(),
|
||||
// 1 is defined as back, 2 as forward; other codes are unexpected.
|
||||
button: MouseButton::try_from_u8(b).unwrap().into(),
|
||||
});
|
||||
result = ProcResult::Value(0);
|
||||
},
|
||||
|
||||
WM_XBUTTONUP => {
|
||||
use winit_core::event::ElementState::Released;
|
||||
use winit_core::event::MouseButton::{Back, Forward, Other};
|
||||
use winit_core::event::MouseButton;
|
||||
use winit_core::event::WindowEvent::PointerButton;
|
||||
|
||||
let xbutton = util::get_xbutton_wparam(wparam as u32);
|
||||
|
||||
unsafe { release_mouse(userdata.window_state_lock()) };
|
||||
|
|
@ -1886,17 +1806,16 @@ unsafe fn public_window_callback_inner(
|
|||
let y = util::get_y_lparam(lparam as u32) as i32;
|
||||
let position = PhysicalPosition::new(x as f64, y as f64);
|
||||
|
||||
// 1 is defined as back, 2 as forward; other codes are unexpected.
|
||||
let b = xbutton as u8 + MouseButton::Back as u8 - 1;
|
||||
|
||||
userdata.send_window_event(window, PointerButton {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
state: Released,
|
||||
position,
|
||||
button: match xbutton {
|
||||
1 => Back,
|
||||
2 => Forward,
|
||||
_ => Other(xbutton),
|
||||
}
|
||||
.into(),
|
||||
// 1 is defined as back, 2 as forward; other codes are unexpected.
|
||||
button: MouseButton::try_from_u8(b).unwrap().into(),
|
||||
});
|
||||
result = ProcResult::Value(0);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1007,7 +1007,6 @@ impl EventProcessor {
|
|||
position,
|
||||
button: MouseButton::Middle.into(),
|
||||
},
|
||||
|
||||
xlib::Button3 => WindowEvent::PointerButton {
|
||||
device_id,
|
||||
primary: true,
|
||||
|
|
@ -1034,28 +1033,25 @@ impl EventProcessor {
|
|||
},
|
||||
ElementState::Released => return,
|
||||
},
|
||||
8 => WindowEvent::PointerButton {
|
||||
device_id,
|
||||
primary: true,
|
||||
state,
|
||||
position,
|
||||
button: MouseButton::Back.into(),
|
||||
},
|
||||
|
||||
9 => WindowEvent::PointerButton {
|
||||
x @ 8..37 => WindowEvent::PointerButton {
|
||||
device_id,
|
||||
primary: true,
|
||||
state,
|
||||
position,
|
||||
button: MouseButton::Forward.into(),
|
||||
// Button 8 maps to MouseButton::BACK = 3; 36 maps to MouseButton::Button32.
|
||||
// 255 is the largest code yielded on X11 (tested).
|
||||
button: MouseButton::try_from_u8((x - 5) as u8).unwrap().into(),
|
||||
},
|
||||
x => WindowEvent::PointerButton {
|
||||
x @ 37..=0xff => WindowEvent::PointerButton {
|
||||
device_id,
|
||||
primary: true,
|
||||
state,
|
||||
position,
|
||||
button: MouseButton::Other(x as u16).into(),
|
||||
// 255 is the largest code yielded on X11 (tested).
|
||||
button: ButtonSource::Unknown(x as u16),
|
||||
},
|
||||
_ => return,
|
||||
};
|
||||
|
||||
app.window_event(&self.target, window_id, event);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
//! Note that a real application accepting text input **should** support
|
||||
//! the IME interface. See the `ime` example.
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::error::Error;
|
||||
use std::fmt::Debug;
|
||||
|
|
@ -485,8 +486,9 @@ impl ApplicationHandler for Application {
|
|||
let mods = window.modifiers;
|
||||
if let Some(action) = state
|
||||
.is_pressed()
|
||||
.then(|| Self::process_mouse_binding(button.mouse_button(), &mods))
|
||||
.then(|| button.mouse_button())
|
||||
.flatten()
|
||||
.and_then(|button| Self::process_mouse_binding(button, &mods))
|
||||
{
|
||||
self.handle_action_with_window(event_loop, window_id, action);
|
||||
}
|
||||
|
|
@ -1145,15 +1147,16 @@ fn modifiers_to_string(mods: ModifiersState) -> String {
|
|||
mods_line
|
||||
}
|
||||
|
||||
fn mouse_button_to_string(button: MouseButton) -> &'static str {
|
||||
fn mouse_button_to_string(button: MouseButton) -> Cow<'static, str> {
|
||||
match button {
|
||||
MouseButton::Left => "LMB",
|
||||
MouseButton::Right => "RMB",
|
||||
MouseButton::Middle => "MMB",
|
||||
MouseButton::Back => "Back",
|
||||
MouseButton::Forward => "Forward",
|
||||
MouseButton::Other(_) => "",
|
||||
other => return format!("button {}", other as u8 + 1).into(),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
#[cfg(web_platform)]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue