Skip to content

Commit 4748890

Browse files
bbb651daxpedda
andauthored
Add MouseButton::{Back, Forward} to MouseInput
Add named variants for physical back and forward keys which could be found on some mice. The macOS bits may not work on all the hardware given that apple doesn't directly support such a thing. Co-authored-by: daxpedda <daxpedda@gmail.com>
1 parent 6300cf9 commit 4748890

File tree

7 files changed

+67
-9
lines changed

7 files changed

+67
-9
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ And please only add new entries to the top of this list, right below the `# Unre
8585
- On Web, fix `DeviceEvent::MouseMotion` only being emitted for each canvas instead of the whole window.
8686
- On Web, add `DeviceEvent::Motion`, `DeviceEvent::MouseWheel`, `DeviceEvent::Button` and
8787
`DeviceEvent::Key` support.
88+
- **Breaking** `MouseButton` now supports `Back` and `Forward` variants, emitted from mouse events
89+
on Wayland, X11, Windows, macOS and Web.
8890

8991
# 0.28.6
9092

src/event.rs

+7
Original file line numberDiff line numberDiff line change
@@ -1202,12 +1202,19 @@ pub enum ElementState {
12021202
}
12031203

12041204
/// Describes a button of a mouse controller.
1205+
///
1206+
/// ## Platform-specific
1207+
///
1208+
/// **macOS:** `Back` and `Forward` might not work with all hardware.
1209+
/// **Orbital:** `Back` and `Forward` are unsupported due to orbital not supporting them.
12051210
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
12061211
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
12071212
pub enum MouseButton {
12081213
Left,
12091214
Right,
12101215
Middle,
1216+
Back,
1217+
Forward,
12111218
Other(u16),
12121219
}
12131220

src/platform_impl/linux/wayland/seat/pointer/mod.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -397,15 +397,21 @@ impl Default for WinitPointerDataInner {
397397

398398
/// Convert the Wayland button into winit.
399399
fn wayland_button_to_winit(button: u32) -> MouseButton {
400-
// These values are comming from <linux/input-event-codes.h>.
400+
// These values are coming from <linux/input-event-codes.h>.
401401
const BTN_LEFT: u32 = 0x110;
402402
const BTN_RIGHT: u32 = 0x111;
403403
const BTN_MIDDLE: u32 = 0x112;
404+
const BTN_SIDE: u32 = 0x113;
405+
const BTN_EXTRA: u32 = 0x114;
406+
const BTN_FORWARD: u32 = 0x115;
407+
const BTN_BACK: u32 = 0x116;
404408

405409
match button {
406410
BTN_LEFT => MouseButton::Left,
407411
BTN_RIGHT => MouseButton::Right,
408412
BTN_MIDDLE => MouseButton::Middle,
413+
BTN_BACK | BTN_SIDE => MouseButton::Back,
414+
BTN_FORWARD | BTN_EXTRA => MouseButton::Forward,
409415
button => MouseButton::Other(button as u16),
410416
}
411417
}

src/platform_impl/linux/x11/event_processor.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ impl<T: 'static> EventProcessor<T> {
579579

580580
use crate::event::{
581581
ElementState::{Pressed, Released},
582-
MouseButton::{Left, Middle, Other, Right},
582+
MouseButton::{Back, Forward, Left, Middle, Other, Right},
583583
MouseScrollDelta::LineDelta,
584584
Touch,
585585
WindowEvent::{
@@ -651,6 +651,23 @@ impl<T: 'static> EventProcessor<T> {
651651
}
652652
}
653653

654+
8 => callback(Event::WindowEvent {
655+
window_id,
656+
event: MouseInput {
657+
device_id,
658+
state,
659+
button: Back,
660+
},
661+
}),
662+
9 => callback(Event::WindowEvent {
663+
window_id,
664+
event: MouseInput {
665+
device_id,
666+
state,
667+
button: Forward,
668+
},
669+
}),
670+
654671
x => callback(Event::WindowEvent {
655672
window_id,
656673
event: MouseInput {

src/platform_impl/macos/view.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1027,10 +1027,14 @@ fn mouse_button(event: &NSEvent) -> MouseButton {
10271027
// The buttonNumber property only makes sense for the mouse events:
10281028
// NSLeftMouse.../NSRightMouse.../NSOtherMouse...
10291029
// For the other events, it's always set to 0.
1030+
// MacOS only defines the left, right and middle buttons, 3..=31 are left as generic buttons,
1031+
// but 3 and 4 are very commonly used as Back and Forward by hardware vendors and applications.
10301032
match event.buttonNumber() {
10311033
0 => MouseButton::Left,
10321034
1 => MouseButton::Right,
10331035
2 => MouseButton::Middle,
1036+
3 => MouseButton::Back,
1037+
4 => MouseButton::Forward,
10341038
n => MouseButton::Other(n as u16),
10351039
}
10361040
}

src/platform_impl/web/web_sys/event.rs

+15-3
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,14 @@ use wasm_bindgen::{JsCast, JsValue};
1010
use web_sys::{HtmlCanvasElement, KeyboardEvent, MouseEvent, PointerEvent, WheelEvent};
1111

1212
bitflags! {
13+
// https://www.w3.org/TR/pointerevents3/#the-buttons-property
1314
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1415
pub struct ButtonsState: u16 {
15-
const LEFT = 0b001;
16-
const RIGHT = 0b010;
17-
const MIDDLE = 0b100;
16+
const LEFT = 0b00001;
17+
const RIGHT = 0b00010;
18+
const MIDDLE = 0b00100;
19+
const BACK = 0b01000;
20+
const FORWARD = 0b10000;
1821
}
1922
}
2023

@@ -24,6 +27,8 @@ impl From<ButtonsState> for MouseButton {
2427
ButtonsState::LEFT => MouseButton::Left,
2528
ButtonsState::RIGHT => MouseButton::Right,
2629
ButtonsState::MIDDLE => MouseButton::Middle,
30+
ButtonsState::BACK => MouseButton::Back,
31+
ButtonsState::FORWARD => MouseButton::Forward,
2732
_ => MouseButton::Other(value.bits()),
2833
}
2934
}
@@ -35,6 +40,8 @@ impl From<MouseButton> for ButtonsState {
3540
MouseButton::Left => ButtonsState::LEFT,
3641
MouseButton::Right => ButtonsState::RIGHT,
3742
MouseButton::Middle => ButtonsState::MIDDLE,
43+
MouseButton::Back => ButtonsState::BACK,
44+
MouseButton::Forward => ButtonsState::FORWARD,
3845
MouseButton::Other(value) => ButtonsState::from_bits_retain(value),
3946
}
4047
}
@@ -45,11 +52,14 @@ pub fn mouse_buttons(event: &MouseEvent) -> ButtonsState {
4552
}
4653

4754
pub fn mouse_button(event: &MouseEvent) -> Option<MouseButton> {
55+
// https://www.w3.org/TR/pointerevents3/#the-button-property
4856
match event.button() {
4957
-1 => None,
5058
0 => Some(MouseButton::Left),
5159
1 => Some(MouseButton::Middle),
5260
2 => Some(MouseButton::Right),
61+
3 => Some(MouseButton::Back),
62+
4 => Some(MouseButton::Forward),
5363
i => Some(MouseButton::Other(
5464
i.try_into()
5565
.expect("unexpected negative mouse button value"),
@@ -63,6 +73,8 @@ impl MouseButton {
6373
MouseButton::Left => 0,
6474
MouseButton::Right => 1,
6575
MouseButton::Middle => 2,
76+
MouseButton::Back => 3,
77+
MouseButton::Forward => 4,
6678
MouseButton::Other(value) => value.into(),
6779
}
6880
}

src/platform_impl/windows/event_loop.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -1647,7 +1647,8 @@ unsafe fn public_window_callback_inner<T: 'static>(
16471647

16481648
WM_XBUTTONDOWN => {
16491649
use crate::event::{
1650-
ElementState::Pressed, MouseButton::Other, WindowEvent::MouseInput,
1650+
ElementState::Pressed, MouseButton::Back, MouseButton::Forward, MouseButton::Other,
1651+
WindowEvent::MouseInput,
16511652
};
16521653
let xbutton = super::get_xbutton_wparam(wparam as u32);
16531654

@@ -1660,15 +1661,20 @@ unsafe fn public_window_callback_inner<T: 'static>(
16601661
event: MouseInput {
16611662
device_id: DEVICE_ID,
16621663
state: Pressed,
1663-
button: Other(xbutton),
1664+
button: match xbutton {
1665+
1 => Back,
1666+
2 => Forward,
1667+
_ => Other(xbutton),
1668+
},
16641669
},
16651670
});
16661671
result = ProcResult::Value(0);
16671672
}
16681673

16691674
WM_XBUTTONUP => {
16701675
use crate::event::{
1671-
ElementState::Released, MouseButton::Other, WindowEvent::MouseInput,
1676+
ElementState::Released, MouseButton::Back, MouseButton::Forward,
1677+
MouseButton::Other, WindowEvent::MouseInput,
16721678
};
16731679
let xbutton = super::get_xbutton_wparam(wparam as u32);
16741680

@@ -1681,7 +1687,11 @@ unsafe fn public_window_callback_inner<T: 'static>(
16811687
event: MouseInput {
16821688
device_id: DEVICE_ID,
16831689
state: Released,
1684-
button: Other(xbutton),
1690+
button: match xbutton {
1691+
1 => Back,
1692+
2 => Forward,
1693+
_ => Other(xbutton),
1694+
},
16851695
},
16861696
});
16871697
result = ProcResult::Value(0);

0 commit comments

Comments
 (0)