From 39a1dccafed3b60958eec5589ca971b9b6555d2c Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Fri, 16 Feb 2024 13:53:25 -0800 Subject: [PATCH] Make `PointerTarget`/`KeyboardTarget` object-safe; use in Anvil I've been thinking about how to simplify this code for a while. Implementations of these traits become particularly verbose with a more complicated shell like cosmic-comp: https://github.com/pop-os/cosmic-comp/blob/master/src/shell/focus/target.rs. It turns out it can be make object-safe, so we can have a `&dyn PointerTarget`, if `PartialEq` and `Clone` requirements are moved out of the trait itself. I still wonder if it could be better to use enums for input events instead of a million methods. Anyway, something to think about. Leaving as a draft pending the other changes in input targets in https://github.com/Smithay/smithay/pull/1326. --- anvil/src/focus.rs | 134 +++++++++++--------------------------- src/input/keyboard/mod.rs | 2 +- src/input/mod.rs | 4 +- src/input/pointer/mod.rs | 2 +- 4 files changed, 41 insertions(+), 101 deletions(-) diff --git a/anvil/src/focus.rs b/anvil/src/focus.rs index 354bd419284e..89a932f09295 100644 --- a/anvil/src/focus.rs +++ b/anvil/src/focus.rs @@ -43,6 +43,24 @@ impl From for WlSurface { } } +impl FocusTarget { + fn inner_keyboard_target(&self) -> &dyn KeyboardTarget> { + match self { + FocusTarget::Window(w) => w, + FocusTarget::LayerSurface(l) => l, + FocusTarget::Popup(p) => p.wl_surface(), + } + } + + fn inner_pointer_target(&self) -> &dyn PointerTarget> { + match self { + FocusTarget::Window(w) => w, + FocusTarget::LayerSurface(l) => l, + FocusTarget::Popup(p) => p.wl_surface(), + } + } +} + impl PointerTarget> for FocusTarget { fn enter( &self, @@ -50,11 +68,7 @@ impl PointerTarget> for FocusTarge data: &mut AnvilState, event: &MotionEvent, ) { - match self { - FocusTarget::Window(w) => PointerTarget::enter(w, seat, data, event), - FocusTarget::LayerSurface(l) => PointerTarget::enter(l, seat, data, event), - FocusTarget::Popup(p) => PointerTarget::enter(p.wl_surface(), seat, data, event), - } + self.inner_pointer_target().enter(seat, data, event) } fn motion( &self, @@ -62,11 +76,7 @@ impl PointerTarget> for FocusTarge data: &mut AnvilState, event: &MotionEvent, ) { - match self { - FocusTarget::Window(w) => PointerTarget::motion(w, seat, data, event), - FocusTarget::LayerSurface(l) => PointerTarget::motion(l, seat, data, event), - FocusTarget::Popup(p) => PointerTarget::motion(p.wl_surface(), seat, data, event), - } + self.inner_pointer_target().motion(seat, data, event) } fn relative_motion( &self, @@ -74,11 +84,7 @@ impl PointerTarget> for FocusTarge data: &mut AnvilState, event: &RelativeMotionEvent, ) { - match self { - FocusTarget::Window(w) => PointerTarget::relative_motion(w, seat, data, event), - FocusTarget::LayerSurface(l) => PointerTarget::relative_motion(l.wl_surface(), seat, data, event), - FocusTarget::Popup(p) => PointerTarget::relative_motion(p.wl_surface(), seat, data, event), - } + self.inner_pointer_target().relative_motion(seat, data, event) } fn button( &self, @@ -86,11 +92,7 @@ impl PointerTarget> for FocusTarge data: &mut AnvilState, event: &ButtonEvent, ) { - match self { - FocusTarget::Window(w) => PointerTarget::button(w, seat, data, event), - FocusTarget::LayerSurface(l) => PointerTarget::button(l, seat, data, event), - FocusTarget::Popup(p) => PointerTarget::button(p.wl_surface(), seat, data, event), - } + self.inner_pointer_target().button(seat, data, event) } fn axis( &self, @@ -98,18 +100,10 @@ impl PointerTarget> for FocusTarge data: &mut AnvilState, frame: AxisFrame, ) { - match self { - FocusTarget::Window(w) => PointerTarget::axis(w, seat, data, frame), - FocusTarget::LayerSurface(l) => PointerTarget::axis(l, seat, data, frame), - FocusTarget::Popup(p) => PointerTarget::axis(p.wl_surface(), seat, data, frame), - } + self.inner_pointer_target().axis(seat, data, frame) } fn frame(&self, seat: &Seat>, data: &mut AnvilState) { - match self { - FocusTarget::Window(w) => PointerTarget::frame(w, seat, data), - FocusTarget::LayerSurface(l) => PointerTarget::frame(l, seat, data), - FocusTarget::Popup(p) => PointerTarget::frame(p.wl_surface(), seat, data), - } + self.inner_pointer_target().frame(seat, data) } fn leave( &self, @@ -118,11 +112,7 @@ impl PointerTarget> for FocusTarge serial: Serial, time: u32, ) { - match self { - FocusTarget::Window(w) => PointerTarget::leave(w, seat, data, serial, time), - FocusTarget::LayerSurface(l) => PointerTarget::leave(l, seat, data, serial, time), - FocusTarget::Popup(p) => PointerTarget::leave(p.wl_surface(), seat, data, serial, time), - } + self.inner_pointer_target().leave(seat, data, serial, time) } fn gesture_swipe_begin( &self, @@ -130,11 +120,7 @@ impl PointerTarget> for FocusTarge data: &mut AnvilState, event: &GestureSwipeBeginEvent, ) { - match self { - FocusTarget::Window(w) => PointerTarget::gesture_swipe_begin(w, seat, data, event), - FocusTarget::LayerSurface(l) => PointerTarget::gesture_swipe_begin(l, seat, data, event), - FocusTarget::Popup(p) => PointerTarget::gesture_swipe_begin(p.wl_surface(), seat, data, event), - } + self.inner_pointer_target().gesture_swipe_begin(seat, data, event) } fn gesture_swipe_update( &self, @@ -142,11 +128,7 @@ impl PointerTarget> for FocusTarge data: &mut AnvilState, event: &GestureSwipeUpdateEvent, ) { - match self { - FocusTarget::Window(w) => PointerTarget::gesture_swipe_update(w, seat, data, event), - FocusTarget::LayerSurface(l) => PointerTarget::gesture_swipe_update(l, seat, data, event), - FocusTarget::Popup(p) => PointerTarget::gesture_swipe_update(p.wl_surface(), seat, data, event), - } + self.inner_pointer_target().gesture_swipe_update(seat, data, event) } fn gesture_swipe_end( &self, @@ -154,11 +136,7 @@ impl PointerTarget> for FocusTarge data: &mut AnvilState, event: &GestureSwipeEndEvent, ) { - match self { - FocusTarget::Window(w) => PointerTarget::gesture_swipe_end(w, seat, data, event), - FocusTarget::LayerSurface(l) => PointerTarget::gesture_swipe_end(l, seat, data, event), - FocusTarget::Popup(p) => PointerTarget::gesture_swipe_end(p.wl_surface(), seat, data, event), - } + self.inner_pointer_target().gesture_swipe_end(seat, data, event) } fn gesture_pinch_begin( &self, @@ -166,11 +144,7 @@ impl PointerTarget> for FocusTarge data: &mut AnvilState, event: &GesturePinchBeginEvent, ) { - match self { - FocusTarget::Window(w) => PointerTarget::gesture_pinch_begin(w, seat, data, event), - FocusTarget::LayerSurface(l) => PointerTarget::gesture_pinch_begin(l, seat, data, event), - FocusTarget::Popup(p) => PointerTarget::gesture_pinch_begin(p.wl_surface(), seat, data, event), - } + self.inner_pointer_target().gesture_pinch_begin(seat, data, event) } fn gesture_pinch_update( &self, @@ -178,11 +152,7 @@ impl PointerTarget> for FocusTarge data: &mut AnvilState, event: &GesturePinchUpdateEvent, ) { - match self { - FocusTarget::Window(w) => PointerTarget::gesture_pinch_update(w, seat, data, event), - FocusTarget::LayerSurface(l) => PointerTarget::gesture_pinch_update(l, seat, data, event), - FocusTarget::Popup(p) => PointerTarget::gesture_pinch_update(p.wl_surface(), seat, data, event), - } + self.inner_pointer_target().gesture_pinch_update(seat, data, event) } fn gesture_pinch_end( &self, @@ -190,11 +160,7 @@ impl PointerTarget> for FocusTarge data: &mut AnvilState, event: &GesturePinchEndEvent, ) { - match self { - FocusTarget::Window(w) => PointerTarget::gesture_pinch_end(w, seat, data, event), - FocusTarget::LayerSurface(l) => PointerTarget::gesture_pinch_end(l, seat, data, event), - FocusTarget::Popup(p) => PointerTarget::gesture_pinch_end(p.wl_surface(), seat, data, event), - } + self.inner_pointer_target().gesture_pinch_end(seat, data, event) } fn gesture_hold_begin( &self, @@ -202,11 +168,7 @@ impl PointerTarget> for FocusTarge data: &mut AnvilState, event: &GestureHoldBeginEvent, ) { - match self { - FocusTarget::Window(w) => PointerTarget::gesture_hold_begin(w, seat, data, event), - FocusTarget::LayerSurface(l) => PointerTarget::gesture_hold_begin(l, seat, data, event), - FocusTarget::Popup(p) => PointerTarget::gesture_hold_begin(p.wl_surface(), seat, data, event), - } + self.inner_pointer_target().gesture_hold_begin(seat, data, event) } fn gesture_hold_end( &self, @@ -214,11 +176,7 @@ impl PointerTarget> for FocusTarge data: &mut AnvilState, event: &GestureHoldEndEvent, ) { - match self { - FocusTarget::Window(w) => PointerTarget::gesture_hold_end(w, seat, data, event), - FocusTarget::LayerSurface(l) => PointerTarget::gesture_hold_end(l, seat, data, event), - FocusTarget::Popup(p) => PointerTarget::gesture_hold_end(p.wl_surface(), seat, data, event), - } + self.inner_pointer_target().gesture_hold_end(seat, data, event) } } @@ -230,11 +188,7 @@ impl KeyboardTarget> for FocusTarg keys: Vec>, serial: Serial, ) { - match self { - FocusTarget::Window(w) => KeyboardTarget::enter(w, seat, data, keys, serial), - FocusTarget::LayerSurface(l) => KeyboardTarget::enter(l, seat, data, keys, serial), - FocusTarget::Popup(p) => KeyboardTarget::enter(p.wl_surface(), seat, data, keys, serial), - } + self.inner_keyboard_target().enter(seat, data, keys, serial) } fn leave( &self, @@ -242,11 +196,7 @@ impl KeyboardTarget> for FocusTarg data: &mut AnvilState, serial: Serial, ) { - match self { - FocusTarget::Window(w) => KeyboardTarget::leave(w, seat, data, serial), - FocusTarget::LayerSurface(l) => KeyboardTarget::leave(l, seat, data, serial), - FocusTarget::Popup(p) => KeyboardTarget::leave(p.wl_surface(), seat, data, serial), - } + self.inner_keyboard_target().leave(seat, data, serial) } fn key( &self, @@ -257,13 +207,7 @@ impl KeyboardTarget> for FocusTarg serial: Serial, time: u32, ) { - match self { - FocusTarget::Window(w) => KeyboardTarget::key(w, seat, data, key, state, serial, time), - FocusTarget::LayerSurface(l) => KeyboardTarget::key(l, seat, data, key, state, serial, time), - FocusTarget::Popup(p) => { - KeyboardTarget::key(p.wl_surface(), seat, data, key, state, serial, time) - } - } + self.inner_keyboard_target().key(seat, data, key, state, serial, time) } fn modifiers( &self, @@ -272,11 +216,7 @@ impl KeyboardTarget> for FocusTarg modifiers: ModifiersState, serial: Serial, ) { - match self { - FocusTarget::Window(w) => KeyboardTarget::modifiers(w, seat, data, modifiers, serial), - FocusTarget::LayerSurface(l) => KeyboardTarget::modifiers(l, seat, data, modifiers, serial), - FocusTarget::Popup(p) => KeyboardTarget::modifiers(p.wl_surface(), seat, data, modifiers, serial), - } + self.inner_keyboard_target().modifiers(seat, data, modifiers, serial) } } diff --git a/src/input/keyboard/mod.rs b/src/input/keyboard/mod.rs index 59b78457a462..95337106ebd5 100644 --- a/src/input/keyboard/mod.rs +++ b/src/input/keyboard/mod.rs @@ -30,7 +30,7 @@ mod xkb_config; pub use xkb_config::XkbConfig; /// Trait representing object that can receive keyboard interactions -pub trait KeyboardTarget: IsAlive + PartialEq + Clone + fmt::Debug + Send +pub trait KeyboardTarget: IsAlive + fmt::Debug + Send where D: SeatHandler, { diff --git a/src/input/mod.rs b/src/input/mod.rs index b5e18f97893f..4e1a70130190 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -127,9 +127,9 @@ pub mod pointer; /// Handler trait for Seats pub trait SeatHandler: Sized { /// Type used to represent the target currently holding the keyboard focus - type KeyboardFocus: KeyboardTarget + 'static; + type KeyboardFocus: KeyboardTarget + PartialEq + Clone + 'static; /// Type used to represent the target currently holding the pointer focus - type PointerFocus: PointerTarget + 'static; + type PointerFocus: PointerTarget + PartialEq + Clone + 'static; /// [SeatState] getter fn seat_state(&mut self) -> &mut SeatState; diff --git a/src/input/pointer/mod.rs b/src/input/pointer/mod.rs index e0101a8f291a..cc74a47b6d70 100644 --- a/src/input/pointer/mod.rs +++ b/src/input/pointer/mod.rs @@ -107,7 +107,7 @@ impl std::cmp::PartialEq for PointerHandle { impl std::cmp::Eq for PointerHandle {} /// Trait representing object that can receive pointer interactions -pub trait PointerTarget: IsAlive + PartialEq + Clone + fmt::Debug + Send +pub trait PointerTarget: IsAlive + fmt::Debug + Send where D: SeatHandler, {