aboutsummaryrefslogtreecommitdiff
path: root/src/layout/mod.rs
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2025-02-10 08:03:39 +0300
committerIvan Molodetskikh <yalterz@gmail.com>2025-02-10 07:29:33 -0800
commit1d883931b4ae7704128f02fd566486fb02351196 (patch)
tree575124aeaa26ee6a0ccff0c55a3facda9dfe9944 /src/layout/mod.rs
parentb65fad09d8f5253a28ee7ad9d293583641fc2c36 (diff)
downloadniri-1d883931b4ae7704128f02fd566486fb02351196.tar.gz
niri-1d883931b4ae7704128f02fd566486fb02351196.tar.bz2
niri-1d883931b4ae7704128f02fd566486fb02351196.zip
Account for border in contents_under()
Fixes pointer clicks going through window borders to a layer surface below, also fixes window not getting activated in all cases from a border click.
Diffstat (limited to 'src/layout/mod.rs')
-rw-r--r--src/layout/mod.rs38
1 files changed, 28 insertions, 10 deletions
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index 01122177..593279b7 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -450,6 +450,20 @@ pub enum AddWindowTarget<'a, W: LayoutElement> {
NextTo(&'a W::Id),
}
+/// Type of the window hit from `window_under()`.
+#[derive(Debug, Clone, Copy, PartialEq)]
+pub enum HitType {
+ /// The hit is within a window's input region and can be used for sending events to it.
+ Input {
+ /// Position of the window's buffer.
+ win_pos: Point<f64, Logical>,
+ },
+ /// The hit can activate a window, but it is not in the input region so cannot send events.
+ ///
+ /// For example, this could be clicking on a tile border outside the window.
+ Activate,
+}
+
impl<W: LayoutElement> InteractiveMoveState<W> {
fn moving(&self) -> Option<&InteractiveMoveData<W>> {
match self {
@@ -485,6 +499,16 @@ impl ActivateWindow {
}
}
+impl HitType {
+ pub fn offset_win_pos(mut self, offset: Point<f64, Logical>) -> Self {
+ match &mut self {
+ HitType::Input { win_pos } => *win_pos += offset,
+ HitType::Activate => (),
+ }
+ self
+ }
+}
+
impl Options {
fn from_config(config: &Config) -> Self {
let layout = &config.layout;
@@ -2155,18 +2179,12 @@ impl<W: LayoutElement> Layout<W> {
mon.active_window().map(|win| (win, &mon.output))
}
- /// Returns the window under the cursor and the position of its toplevel surface within the
- /// output.
- ///
- /// `Some((w, Some(p)))` means that the cursor is within the window's input region and can be
- /// used for delivering events to the window. `Some((w, None))` means that the cursor is within
- /// the window's activation region, but not within the window's input region. For example, the
- /// cursor may be on the window's server-side border.
+ /// Returns the window under the cursor and the hit type.
pub fn window_under(
&self,
output: &Output,
pos_within_output: Point<f64, Logical>,
- ) -> Option<(&W, Option<Point<f64, Logical>>)> {
+ ) -> Option<(&W, HitType)> {
let MonitorSet::Normal { monitors, .. } = &self.monitor_set else {
return None;
};
@@ -2177,9 +2195,9 @@ impl<W: LayoutElement> Layout<W> {
if move_.tile.is_in_input_region(pos_within_tile) {
let win_pos = tile_pos + move_.tile.buf_loc();
- return Some((move_.tile.window(), Some(win_pos)));
+ return Some((move_.tile.window(), HitType::Input { win_pos }));
} else if move_.tile.is_in_activation_region(pos_within_tile) {
- return Some((move_.tile.window(), None));
+ return Some((move_.tile.window(), HitType::Activate));
}
return None;