Skip to content

Commit

Permalink
Support mouse scroll in X11. (#961)
Browse files Browse the repository at this point in the history
  • Loading branch information
jneem authored May 20, 2020
1 parent 3136d26 commit 70d5900
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 4 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ This means that druid no longer requires cairo on macOS and uses Core Graphics i
- Routing `LifeCycle::FocusChanged` to descendant widgets. ([#925] by [@yrns])
- Built-in open and save menu items now show the correct label and submit the right commands. ([#930] by [@finnerale])
- Wheel events now properly update hot state. ([#951] by [@xStrom])
- X11: Support mouse scrolling. ([#961] by [@jneem])

### Visual

Expand Down Expand Up @@ -197,11 +198,12 @@ This means that druid no longer requires cairo on macOS and uses Core Graphics i
[#940]: https://github.com/xi-editor/druid/pull/940
[#942]: https://github.com/xi-editor/druid/pull/942
[#943]: https://github.com/xi-editor/druid/pull/943
[#949]: https://github.com/xi-editor/druid/pull/949
[#951]: https://github.com/xi-editor/druid/pull/951
[#953]: https://github.com/xi-editor/druid/pull/953
[#954]: https://github.com/xi-editor/druid/pull/954
[#959]: https://github.com/xi-editor/druid/pull/959
[#949]: https://github.com/xi-editor/druid/pull/949
[#961]: https://github.com/xi-editor/druid/pull/961

## [0.5.0] - 2020-04-01

Expand Down
17 changes: 14 additions & 3 deletions druid-shell/src/platform/x11/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,6 @@ impl Application {
self.screen_num
}

// TODO(x11/events): handle mouse scroll events
#[allow(clippy::cognitive_complexity)]
pub fn run(self, _handler: Option<Box<dyn AppHandler>>) {
loop {
Expand Down Expand Up @@ -226,7 +225,16 @@ impl Application {
let window_id = button_press.event();
match self.window(window_id) {
Ok(w) => {
if let Err(err) = w.handle_button_press(button_press) {
// X doesn't have dedicated scroll events: it uses mouse buttons instead.
// Buttons 4/5 are vertical; 6/7 are horizontal.
if button_press.detail() >= 4 && button_press.detail() <= 7 {
if let Err(err) = w.handle_wheel(button_press) {
log::error!(
"BUTTON_PRESS - failed to handle wheel: {}",
err
);
}
} else if let Err(err) = w.handle_button_press(button_press) {
log::error!("BUTTON_PRESS - failed to handle: {}", err);
}
}
Expand All @@ -238,7 +246,10 @@ impl Application {
let window_id = button_release.event();
match self.window(window_id) {
Ok(w) => {
if let Err(err) = w.handle_button_release(button_release) {
if button_release.detail() >= 4 && button_release.detail() <= 7 {
// This is the release event corresponding to a mouse wheel.
// Ignore it: we already handled the press event.
} else if let Err(err) = w.handle_button_release(button_release) {
log::error!("BUTTON_RELEASE - failed to handle: {}", err);
}
}
Expand Down
41 changes: 41 additions & 0 deletions druid-shell/src/platform/x11/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,47 @@ impl Window {
}
}

pub fn handle_wheel(&self, event: &xcb::ButtonPressEvent) -> Result<(), Error> {
let button = event.detail();
let mods = key_mods(event.state());

// We use a delta of 120 per tick to match the behavior of Windows.
let delta = match button {
4 if mods.shift => (-120.0, 0.0),
4 => (0.0, -120.0),
5 if mods.shift => (120.0, 0.0),
5 => (0.0, 120.0),
6 => (-120.0, 0.0),
7 => (120.0, 0.0),
_ => {
return Err(Error::Generic(format!(
"unexpected mouse wheel button: {}",
button
)))
}
};
let mouse_event = MouseEvent {
pos: Point::new(event.event_x() as f64, event.event_y() as f64),
buttons: mouse_buttons(event.state()),
mods: key_mods(event.state()),
count: 0,
focus: false,
button: MouseButton::None,
wheel_delta: delta.into(),
};

match self.handler.try_borrow_mut() {
Ok(mut handler) => {
handler.wheel(&mouse_event);
Ok(())
}
Err(err) => Err(Error::BorrowError(format!(
"Window::handle_wheel handle: {}",
err
))),
}
}

pub fn handle_motion_notify(
&self,
motion_notify: &xcb::MotionNotifyEvent,
Expand Down

0 comments on commit 70d5900

Please sign in to comment.