Skip to content

Commit d510166

Browse files
committed
DRAFT: Make non-primary click events focus buttons and checkboxes.
This matches the web's behavior.
1 parent 904d41c commit d510166

File tree

2 files changed

+58
-5
lines changed

2 files changed

+58
-5
lines changed

masonry/src/widgets/button.rs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,20 +101,32 @@ impl Widget for Button {
101101
event: &PointerEvent,
102102
) {
103103
match event {
104-
PointerEvent::Down { .. } => {
104+
PointerEvent::Down {
105+
button: Some(PointerButton::Primary),
106+
..
107+
} => {
105108
ctx.capture_pointer();
106109
// Changes in pointer capture impact appearance, but not accessibility node
107110
ctx.request_paint_only();
108111
trace!("Button {:?} pressed", ctx.widget_id());
109112
}
110-
PointerEvent::Up { button, .. } => {
113+
PointerEvent::Up {
114+
button: Some(PointerButton::Primary),
115+
..
116+
} => {
111117
if ctx.is_active() && ctx.is_hovered() {
112-
ctx.submit_action::<Self::Action>(ButtonPress { button: *button });
118+
ctx.submit_action::<Self::Action>(ButtonPress {
119+
button: Some(PointerButton::Primary),
120+
});
113121
trace!("Button {:?} released", ctx.widget_id());
114122
}
115123
// Changes in pointer capture impact appearance, but not accessibility node
116124
ctx.request_paint_only();
117125
}
126+
PointerEvent::Down { .. } => {
127+
// Any non-primary click event should lead to this widget getting focused.
128+
ctx.request_focus();
129+
}
118130
_ => (),
119131
}
120132
}
@@ -305,6 +317,7 @@ impl Widget for Button {
305317
// --- MARK: TESTS
306318
#[cfg(test)]
307319
mod tests {
320+
use assert_matches::assert_matches;
308321
use masonry_testing::{TestHarnessParams, assert_failing_render_snapshot};
309322

310323
use super::*;
@@ -352,6 +365,19 @@ mod tests {
352365
);
353366
}
354367

368+
#[test]
369+
fn button_right_click() {
370+
let button = NewWidget::new(Button::with_text("Hello"));
371+
372+
let mut harness = TestHarness::create(default_property_set(), button);
373+
let button_id = harness.root_id();
374+
375+
harness.mouse_move_to(button_id);
376+
harness.mouse_button_press(PointerButton::Secondary);
377+
assert_eq!(harness.focused_widget_id(), Some(button_id));
378+
assert_matches!(harness.pop_action_erased(), None);
379+
}
380+
355381
#[test]
356382
fn edit_button() {
357383
let image_1 = {

masonry/src/widgets/checkbox.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use std::any::TypeId;
88
use accesskit::{Node, Role, Toggled};
99
use tracing::{Span, trace, trace_span};
1010
use ui_events::keyboard::Key;
11+
use ui_events::pointer::PointerButton;
1112
use vello::Scene;
1213
use vello::kurbo::Rect;
1314
use vello::kurbo::{Affine, BezPath, Cap, Dashes, Join, Size, Stroke};
@@ -93,13 +94,19 @@ impl Widget for Checkbox {
9394
event: &PointerEvent,
9495
) {
9596
match event {
96-
PointerEvent::Down { .. } => {
97+
PointerEvent::Down {
98+
button: Some(PointerButton::Primary),
99+
..
100+
} => {
97101
ctx.capture_pointer();
98102
// Checked state impacts appearance and accessibility node
99103
ctx.request_render();
100104
trace!("Checkbox {:?} pressed", ctx.widget_id());
101105
}
102-
PointerEvent::Up { .. } => {
106+
PointerEvent::Up {
107+
button: Some(PointerButton::Primary),
108+
..
109+
} => {
103110
if ctx.is_active() && ctx.is_hovered() {
104111
self.checked = !self.checked;
105112
ctx.submit_action::<Self::Action>(CheckboxToggled(self.checked));
@@ -108,6 +115,10 @@ impl Widget for Checkbox {
108115
// Checked state impacts appearance and accessibility node
109116
ctx.request_render();
110117
}
118+
PointerEvent::Down { .. } => {
119+
// Any non-primary click event should lead to this widget getting focused.
120+
ctx.request_focus();
121+
}
111122
_ => (),
112123
}
113124
}
@@ -341,6 +352,8 @@ impl Widget for Checkbox {
341352
// --- MARK: TESTS
342353
#[cfg(test)]
343354
mod tests {
355+
use assert_matches::assert_matches;
356+
344357
use super::*;
345358
use crate::core::{Properties, StyleProperty};
346359
use crate::properties::ContentColor;
@@ -399,6 +412,20 @@ mod tests {
399412
harness.focus_on(Some(checkbox_id));
400413
assert_render_snapshot!(harness, "checkbox_focus_focused");
401414
}
415+
416+
#[test]
417+
fn checkbox_right_click() {
418+
let checkbox = NewWidget::new(Checkbox::new(true, "Hello"));
419+
420+
let mut harness = TestHarness::create(default_property_set(), checkbox);
421+
let checkbox_id = harness.root_id();
422+
423+
harness.mouse_move_to(checkbox_id);
424+
harness.mouse_button_press(PointerButton::Secondary);
425+
assert_eq!(harness.focused_widget_id(), Some(checkbox_id));
426+
assert_matches!(harness.pop_action_erased(), None);
427+
}
428+
402429
#[test]
403430
fn edit_checkbox() {
404431
let image_1 = {

0 commit comments

Comments
 (0)