diff --git a/src/input/mod.rs b/src/input/mod.rs index cf08a721..1a26dc62 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -2168,14 +2168,14 @@ impl State { } Stage::StickyPopups(layout) => { if let Some(element) = - layout.popup_element_under(global_pos.to_local(output)) + layout.popup_element_under(global_pos.to_local(output), seat) { return ControlFlow::Break(Ok(Some(element))); } } Stage::Sticky(layout) => { if let Some(element) = - layout.toplevel_element_under(global_pos.to_local(output)) + layout.toplevel_element_under(global_pos.to_local(output), seat) { return ControlFlow::Break(Ok(Some(element))); } @@ -2330,7 +2330,7 @@ impl State { } Stage::StickyPopups(floating_layer) => { if let Some(under) = floating_layer - .popup_surface_under(relative_pos) + .popup_surface_under(relative_pos, seat) .map(|(target, point)| (target, point.to_global(output))) { return ControlFlow::Break(Ok(Some(under))); @@ -2338,7 +2338,7 @@ impl State { } Stage::Sticky(floating_layer) => { if let Some(under) = floating_layer - .toplevel_surface_under(relative_pos) + .toplevel_surface_under(relative_pos, seat) .map(|(target, point)| (target, point.to_global(output))) { return ControlFlow::Break(Ok(Some(under))); @@ -2392,11 +2392,8 @@ impl State { let window_size = geometry.size.to_f64(); let is_legal = |p: Point| { - let in_window = p.x >= 0.0 - && p.y >= 0.0 - // hack: prevent the cursor from touching the edge of the window - && p.x <= window_size.w - 1. - && p.y <= window_size.h - 1.; + let in_window = + p.x >= 0.0 && p.y >= 0.0 && p.x < window_size.w && p.y < window_size.h; if !in_window { return false; } diff --git a/src/shell/element/mod.rs b/src/shell/element/mod.rs index d5b79703..f58259bf 100644 --- a/src/shell/element/mod.rs +++ b/src/shell/element/mod.rs @@ -269,10 +269,13 @@ impl CosmicMapped { &self, relative_pos: Point, surface_type: WindowSurfaceType, + seat: &Seat, ) -> Option<(PointerFocusTarget, Point)> { match &self.element { CosmicMappedInternal::Stack(stack) => stack.focus_under(relative_pos, surface_type), - CosmicMappedInternal::Window(window) => window.focus_under(relative_pos, surface_type), + CosmicMappedInternal::Window(window) => { + window.focus_under(relative_pos, surface_type, Some(seat)) + } _ => unreachable!(), } } diff --git a/src/shell/element/window.rs b/src/shell/element/window.rs index 32ca4d33..dd45de4b 100644 --- a/src/shell/element/window.rs +++ b/src/shell/element/window.rs @@ -57,7 +57,7 @@ use smithay::{ Buffer, IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size, Transform, user_data::UserDataMap, }, - wayland::seat::WaylandFocus, + wayland::{pointer_constraints::with_pointer_constraint, seat::WaylandFocus}, }; use std::{ borrow::Cow, @@ -274,12 +274,25 @@ impl CosmicWindow { &self, mut relative_pos: Point, surface_type: WindowSurfaceType, + seat: Option<&Seat>, ) -> Option<(PointerFocusTarget, Point)> { + let has_constraint = if let Some(seat) = seat + && let Some(pointer) = seat.get_pointer() + && let Some(surface) = self.wl_surface() + && with_pointer_constraint(&surface, &pointer, |constraint| { + constraint.is_some_and(|c| c.is_active()) + }) { + true + } else { + false + }; + self.0.with_program(|p| { let mut offset = Point::from((0., 0.)); let mut window_ui = None; let has_ssd = p.has_ssd(false); - if (has_ssd || p.has_tiled_state()) + + if (!has_constraint && (has_ssd || p.has_tiled_state())) && surface_type.contains(WindowSurfaceType::TOPLEVEL) { let geo = p.window.geometry(); @@ -877,7 +890,8 @@ impl SpaceElement for CosmicWindow { }) } fn is_in_input_region(&self, point: &Point) -> bool { - self.focus_under(*point, WindowSurfaceType::ALL).is_some() + self.focus_under(*point, WindowSurfaceType::ALL, None) + .is_some() } fn set_activate(&self, activated: bool) { if self diff --git a/src/shell/grabs/moving.rs b/src/shell/grabs/moving.rs index ad5915f9..c92c5bf4 100644 --- a/src/shell/grabs/moving.rs +++ b/src/shell/grabs/moving.rs @@ -953,6 +953,7 @@ impl Drop for MoveGrab { if let Some((target, offset)) = mapped.focus_under( current_location - position.as_logical().to_f64(), WindowSurfaceType::ALL, + &seat, ) { pointer.motion( state, diff --git a/src/shell/layout/floating/mod.rs b/src/shell/layout/floating/mod.rs index e399f356..81c7a4da 100644 --- a/src/shell/layout/floating/mod.rs +++ b/src/shell/layout/floating/mod.rs @@ -731,7 +731,11 @@ impl FloatingLayout { self.space.element_geometry(elem).map(RectExt::as_local) } - pub fn popup_element_under(&self, location: Point) -> Option { + pub fn popup_element_under( + &self, + location: Point, + seat: &Seat, + ) -> Option { self.space .elements() .rev() @@ -752,6 +756,7 @@ impl FloatingLayout { if e.focus_under( point.as_logical(), WindowSurfaceType::POPUP | WindowSurfaceType::SUBSURFACE, + seat, ) .is_some() { @@ -765,6 +770,7 @@ impl FloatingLayout { pub fn toplevel_element_under( &self, location: Point, + seat: &Seat, ) -> Option { self.space .elements() @@ -786,6 +792,7 @@ impl FloatingLayout { if e.focus_under( point.as_logical(), WindowSurfaceType::TOPLEVEL | WindowSurfaceType::SUBSURFACE, + seat, ) .is_some() { @@ -799,6 +806,7 @@ impl FloatingLayout { pub fn popup_surface_under( &self, location: Point, + seat: &Seat, ) -> Option<(PointerFocusTarget, Point)> { self.space .elements() @@ -820,6 +828,7 @@ impl FloatingLayout { e.focus_under( point.as_logical(), WindowSurfaceType::POPUP | WindowSurfaceType::SUBSURFACE, + seat, ) .map(|(surface, surface_offset)| { (surface, render_location + surface_offset.as_local()) @@ -830,6 +839,7 @@ impl FloatingLayout { pub fn toplevel_surface_under( &self, location: Point, + seat: &Seat, ) -> Option<(PointerFocusTarget, Point)> { self.space .elements() @@ -851,6 +861,7 @@ impl FloatingLayout { e.focus_under( point.as_logical(), WindowSurfaceType::TOPLEVEL | WindowSurfaceType::SUBSURFACE, + seat, ) .map(|(surface, surface_offset)| { (surface, render_location + surface_offset.as_local()) diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 22d592bf..e7a7f0f1 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -3145,6 +3145,7 @@ impl TilingLayout { pub fn popup_element_under( &self, location_f64: Point, + seat: &Seat, ) -> Option { let location = location_f64.to_i32_round(); @@ -3157,6 +3158,7 @@ impl TilingLayout { .focus_under( (location_f64 - geo.loc.to_f64()).as_logical() + mapped.geometry().loc.to_f64(), WindowSurfaceType::POPUP | WindowSurfaceType::SUBSURFACE, + seat, ) .is_some() { @@ -3170,6 +3172,7 @@ impl TilingLayout { pub fn toplevel_element_under( &self, location_f64: Point, + seat: &Seat, ) -> Option { let location = location_f64.to_i32_round(); @@ -3182,6 +3185,7 @@ impl TilingLayout { .focus_under( (location_f64 - geo.loc.to_f64()).as_logical() + mapped.geometry().loc.to_f64(), WindowSurfaceType::TOPLEVEL | WindowSurfaceType::SUBSURFACE, + seat, ) .is_some() { @@ -3196,6 +3200,7 @@ impl TilingLayout { &self, location_f64: Point, overview: OverviewMode, + seat: &Seat, ) -> Option<(PointerFocusTarget, Point)> { let location = location_f64.to_i32_round(); @@ -3210,6 +3215,7 @@ impl TilingLayout { if let Some((target, surface_offset)) = mapped.focus_under( (location_f64 - geo.loc.to_f64()).as_logical() + mapped.geometry().loc.to_f64(), WindowSurfaceType::POPUP | WindowSurfaceType::SUBSURFACE, + seat, ) { return Some(( target, @@ -3227,6 +3233,7 @@ impl TilingLayout { &self, location_f64: Point, overview: OverviewMode, + seat: &Seat, ) -> Option<(PointerFocusTarget, Point)> { let tree = &self.queue.trees.back().unwrap().0; let root = tree.root_node_id()?; @@ -3243,6 +3250,7 @@ impl TilingLayout { if let Some((target, surface_offset)) = mapped.focus_under( (location_f64 - geo.loc.to_f64()).as_logical() + mapped.geometry().loc.to_f64(), WindowSurfaceType::TOPLEVEL | WindowSurfaceType::SUBSURFACE, + seat, ) { return Some(( target, @@ -3293,6 +3301,7 @@ impl TilingLayout { .focus_under( test_point, WindowSurfaceType::TOPLEVEL | WindowSurfaceType::SUBSURFACE, + seat, ) .map(|(surface, surface_offset)| { ( diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 66c3791f..6ea3b5e2 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -3714,7 +3714,11 @@ impl Shell { if old_mapped.is_maximized(false) { new_mapped.set_maximized(false); } - start_data.set_focus(new_mapped.focus_under((0., 0.).into(), WindowSurfaceType::ALL)); + start_data.set_focus(new_mapped.focus_under( + (0., 0.).into(), + WindowSurfaceType::ALL, + seat, + )); new_mapped } else { old_mapped.clone() @@ -4185,7 +4189,7 @@ impl Shell { let element_offset = (new_loc - geometry.loc).as_logical(); let focus = mapped - .focus_under(element_offset.to_f64(), WindowSurfaceType::ALL) + .focus_under(element_offset.to_f64(), WindowSurfaceType::ALL, seat) .map(|(target, surface_offset)| (target, (surface_offset + element_offset.to_f64()))); start_data.set_location(new_loc.as_logical().to_f64()); start_data.set_focus(focus.clone()); diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index a79b2acb..ccf5e4ab 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -791,8 +791,8 @@ impl Workspace { } self.floating_layer - .popup_element_under(location) - .or_else(|| self.tiling_layer.popup_element_under(location)) + .popup_element_under(location, seat) + .or_else(|| self.tiling_layer.popup_element_under(location, seat)) .or_else(|| { if last_focused.is_none_or(|t| !matches!(t, FocusTarget::Fullscreen(_))) && let Some(fullscreen) = self.fullscreen.as_ref() @@ -841,8 +841,8 @@ impl Workspace { } self.floating_layer - .toplevel_element_under(location) - .or_else(|| self.tiling_layer.toplevel_element_under(location)) + .toplevel_element_under(location, seat) + .or_else(|| self.tiling_layer.toplevel_element_under(location, seat)) .or_else(|| { if last_focused.is_none_or(|t| !matches!(t, FocusTarget::Fullscreen(_))) && let Some(fullscreen) = self.fullscreen.as_ref() @@ -895,8 +895,11 @@ impl Workspace { .as_ref() .filter(|f| last_focused.is_some_and(|t| t == &f.surface)) .and_then(check_fullscreen) - .or_else(|| self.floating_layer.popup_surface_under(location)) - .or_else(|| self.tiling_layer.popup_surface_under(location, overview)) + .or_else(|| self.floating_layer.popup_surface_under(location, seat)) + .or_else(|| { + self.tiling_layer + .popup_surface_under(location, overview, seat) + }) .or_else(|| { self.fullscreen .as_ref() @@ -941,8 +944,11 @@ impl Workspace { .as_ref() .filter(|f| last_focused.is_some_and(|t| t == &f.surface)) .and_then(check_fullscreen) - .or_else(|| self.floating_layer.toplevel_surface_under(location)) - .or_else(|| self.tiling_layer.toplevel_surface_under(location, overview)) + .or_else(|| self.floating_layer.toplevel_surface_under(location, seat)) + .or_else(|| { + self.tiling_layer + .toplevel_surface_under(location, overview, seat) + }) .or_else(|| { self.fullscreen .as_ref()