diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-03-18 17:50:31 +0400 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-03-18 19:32:03 +0400 |
| commit | d970abead82abab8ac2596662bc4d8e41a53e003 (patch) | |
| tree | 36b122ba4917cc10a24ec329607b95060e6e79fa /src | |
| parent | 4f6ed9dfc9bc71563c584a1dce51cee03d1cff49 (diff) | |
| download | niri-d970abead82abab8ac2596662bc4d8e41a53e003.tar.gz niri-d970abead82abab8ac2596662bc4d8e41a53e003.tar.bz2 niri-d970abead82abab8ac2596662bc4d8e41a53e003.zip | |
Keep track of output and window in PointerFocus separately
Diffstat (limited to 'src')
| -rw-r--r-- | src/input.rs | 41 | ||||
| -rw-r--r-- | src/niri.rs | 85 |
2 files changed, 65 insertions, 61 deletions
diff --git a/src/input.rs b/src/input.rs index 9536731a..c7a0e264 100644 --- a/src/input.rs +++ b/src/input.rs @@ -778,12 +778,11 @@ impl State { // Check if we have an active pointer constraint. let mut pointer_confined = None; - if let Some(focus) = self.niri.pointer_focus.as_ref() { - let focus_surface_loc = focus.surface.1; - let pos_within_surface = pos.to_i32_round() - focus_surface_loc; + if let Some(focus) = &self.niri.pointer_focus.surface { + let pos_within_surface = pos.to_i32_round() - focus.1; let mut pointer_locked = false; - with_pointer_constraint(&focus.surface.0, &pointer, |constraint| { + with_pointer_constraint(&focus.0, &pointer, |constraint| { let Some(constraint) = constraint else { return }; if !constraint.is_active() { return; @@ -801,7 +800,7 @@ impl State { pointer_locked = true; } PointerConstraint::Confined(confine) => { - pointer_confined = Some((focus.surface.clone(), confine.region().cloned())); + pointer_confined = Some((focus.clone(), confine.region().cloned())); } } }); @@ -810,7 +809,7 @@ impl State { if pointer_locked { pointer.relative_motion( self, - Some(focus.surface.clone()), + Some(focus.clone()), &RelativeMotionEvent { delta: event.delta(), delta_unaccel: event.delta_unaccel(), @@ -875,7 +874,7 @@ impl State { let mut prevent = false; // Prevent the pointer from leaving the focused surface. - if Some(&focus_surface.0) != under.as_ref().map(|x| &x.surface.0) { + if Some(&focus_surface.0) != under.surface.as_ref().map(|(s, _)| s) { prevent = true; } @@ -908,11 +907,10 @@ impl State { self.niri.maybe_activate_pointer_constraint(new_pos, &under); self.niri.pointer_focus.clone_from(&under); - let under = under.map(|u| u.surface); pointer.motion( self, - under.clone(), + under.surface.clone(), &MotionEvent { location: new_pos, serial, @@ -922,7 +920,7 @@ impl State { pointer.relative_motion( self, - under, + under.surface, &RelativeMotionEvent { delta: event.delta(), delta_unaccel: event.delta_unaccel(), @@ -971,11 +969,10 @@ impl State { let under = self.niri.surface_under_and_global_space(pos); self.niri.maybe_activate_pointer_constraint(pos, &under); self.niri.pointer_focus.clone_from(&under); - let under = under.map(|u| u.surface); pointer.motion( self, - under, + under.surface, &MotionEvent { location: pos, serial, @@ -1113,7 +1110,6 @@ impl State { }; let under = self.niri.surface_under_and_global_space(pos); - let under = under.map(|u| u.surface); let tablet_seat = self.niri.seat.tablet_seat(); let tablet = tablet_seat.get_tablet(&TabletDescriptor::from(&event.device())); @@ -1140,7 +1136,7 @@ impl State { tool.motion( pos, - under, + under.surface, &tablet, SERIAL_COUNTER.next_serial(), event.time_msec(), @@ -1195,7 +1191,6 @@ impl State { }; let under = self.niri.surface_under_and_global_space(pos); - let under = under.map(|u| u.surface); let tablet_seat = self.niri.seat.tablet_seat(); let tool = tablet_seat.add_tool::<Self>(&self.niri.display_handle, &event.tool()); @@ -1203,7 +1198,7 @@ impl State { if let Some(tablet) = tablet { match event.state() { ProximityState::In => { - if let Some(under) = under { + if let Some(under) = under.surface { tool.proximity_in( pos, under, @@ -1538,13 +1533,10 @@ impl State { }; let serial = SERIAL_COUNTER.next_serial(); - let under = self - .niri - .surface_under_and_global_space(touch_location) - .map(|under| under.surface); + let under = self.niri.surface_under_and_global_space(touch_location); handle.down( self, - under, + under.surface, &DownEvent { slot: evt.slot(), location: touch_location, @@ -1574,13 +1566,10 @@ impl State { let Some(touch_location) = self.compute_touch_location(&evt) else { return; }; - let under = self - .niri - .surface_under_and_global_space(touch_location) - .map(|under| under.surface); + let under = self.niri.surface_under_and_global_space(touch_location); handle.motion( self, - under, + under.surface, &TouchMotionEvent { slot: evt.slot(), location: touch_location, diff --git a/src/niri.rs b/src/niri.rs index d5087d81..ef369e35 100644 --- a/src/niri.rs +++ b/src/niri.rs @@ -201,7 +201,7 @@ pub struct Niri { pub cursor_texture_cache: CursorTextureCache, pub cursor_shape_manager_state: CursorShapeManagerState, pub dnd_icon: Option<WlSurface>, - pub pointer_focus: Option<PointerFocus>, + pub pointer_focus: PointerFocus, pub tablet_cursor_location: Option<Point<f64, Logical>>, pub gesture_swipe_3f_cumulative: Option<(f64, f64)>, @@ -292,10 +292,14 @@ pub enum KeyboardFocus { ScreenshotUi, } -#[derive(Clone, PartialEq, Eq)] +#[derive(Default, Clone, PartialEq, Eq)] pub struct PointerFocus { - pub output: Output, - pub surface: (WlSurface, Point<i32, Logical>), + // Output under pointer. + pub output: Option<Output>, + // Surface under pointer and its location in global coordinate space. + pub surface: Option<(WlSurface, Point<i32, Logical>)>, + // If surface belongs to a window, this is that window. + pub window: Option<Window>, } #[derive(Default)] @@ -421,12 +425,11 @@ impl State { self.niri .maybe_activate_pointer_constraint(location, &under); self.niri.pointer_focus.clone_from(&under); - let under = under.map(|u| u.surface); let pointer = &self.niri.seat.get_pointer().unwrap(); pointer.motion( self, - under, + under.surface, &MotionEvent { location, serial: SERIAL_COUNTER.next_serial(), @@ -560,11 +563,10 @@ impl State { .maybe_activate_pointer_constraint(location, &under); self.niri.pointer_focus.clone_from(&under); - let under = under.map(|u| u.surface); pointer.motion( self, - under, + under.surface, &MotionEvent { location, serial: SERIAL_COUNTER.next_serial(), @@ -1225,7 +1227,7 @@ impl Niri { cursor_texture_cache: Default::default(), cursor_shape_manager_state, dnd_icon: None, - pointer_focus: None, + pointer_focus: PointerFocus::default(), tablet_cursor_location: None, gesture_swipe_3f_cumulative: None, @@ -1622,32 +1624,39 @@ impl Niri { /// Pointer needs location in global space, and focused window location compatible with that /// global space. We don't have a global space for all windows, but this function converts the /// window location temporarily to the current global space. - pub fn surface_under_and_global_space( - &mut self, - pos: Point<f64, Logical>, - ) -> Option<PointerFocus> { - let (output, pos_within_output) = self.output_under(pos)?; + pub fn surface_under_and_global_space(&mut self, pos: Point<f64, Logical>) -> PointerFocus { + let mut rv = PointerFocus::default(); + + let Some((output, pos_within_output)) = self.output_under(pos) else { + return rv; + }; + rv.output = Some(output.clone()); let output_pos_in_global_space = self.global_space.output_geometry(output).unwrap().loc; if self.is_locked() { - let state = self.output_state.get(output)?; - let surface = state.lock_surface.as_ref()?; - // We put lock surfaces at (0, 0). - let point = pos_within_output; - let (surface, point) = under_from_surface_tree( + let Some(state) = self.output_state.get(output) else { + return rv; + }; + let Some(surface) = state.lock_surface.as_ref() else { + return rv; + }; + + rv.surface = under_from_surface_tree( surface.wl_surface(), - point, + pos_within_output, + // We put lock surfaces at (0, 0). (0, 0), WindowSurfaceType::ALL, - )?; - return Some(PointerFocus { - output: output.clone(), - surface: (surface, point + output_pos_in_global_space), + ) + .map(|(surface, pos_within_output)| { + (surface, pos_within_output + output_pos_in_global_space) }); + + return rv; } if self.screenshot_ui.is_open() { - return None; + return rv; } let layers = layer_map_for_output(output); @@ -1665,6 +1674,7 @@ impl Niri { (surface, pos_within_layer + layer_pos_within_output) }) }) + .map(|s| (s, None)) }; let window_under = || { @@ -1680,6 +1690,7 @@ impl Niri { .map(|(s, pos_within_window)| { (s, pos_within_window + win_pos_within_output) }) + .map(|s| (s, Some(window.clone()))) }) }; @@ -1697,16 +1708,18 @@ impl Niri { .or_else(window_under); } - let (surface, surface_pos_within_output) = under + let Some(((surface, surface_pos_within_output), window)) = under .or_else(|| layer_surface_under(Layer::Bottom)) - .or_else(|| layer_surface_under(Layer::Background))?; + .or_else(|| layer_surface_under(Layer::Background)) + else { + return rv; + }; let surface_loc_in_global_space = surface_pos_within_output + output_pos_in_global_space; - Some(PointerFocus { - output: output.clone(), - surface: (surface, surface_loc_in_global_space), - }) + rv.surface = Some((surface, surface_loc_in_global_space)); + rv.window = window; + rv } pub fn output_under_cursor(&self) -> Option<Output> { @@ -3231,11 +3244,13 @@ impl Niri { pub fn maybe_activate_pointer_constraint( &self, new_pos: Point<f64, Logical>, - new_under: &Option<PointerFocus>, + new_under: &PointerFocus, ) { - let Some(under) = new_under else { return }; + let Some((surface, surface_loc)) = &new_under.surface else { + return; + }; let pointer = &self.seat.get_pointer().unwrap(); - with_pointer_constraint(&under.surface.0, pointer, |constraint| { + with_pointer_constraint(surface, pointer, |constraint| { let Some(constraint) = constraint else { return }; if constraint.is_active() { return; @@ -3243,7 +3258,7 @@ impl Niri { // Constraint does not apply if not within region. if let Some(region) = constraint.region() { - let new_pos_within_surface = new_pos.to_i32_round() - under.surface.1; + let new_pos_within_surface = new_pos.to_i32_round() - *surface_loc; if !region.contains(new_pos_within_surface) { return; } |
