aboutsummaryrefslogtreecommitdiff
path: root/src/layout
diff options
context:
space:
mode:
Diffstat (limited to 'src/layout')
-rw-r--r--src/layout/mod.rs7
-rw-r--r--src/layout/scrolling.rs47
-rw-r--r--src/layout/tab_indicator.rs21
-rw-r--r--src/layout/tile.rs4
-rw-r--r--src/layout/workspace.rs18
5 files changed, 86 insertions, 11 deletions
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index ae338ced..4dec85f6 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -466,7 +466,10 @@ pub enum HitType {
/// 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,
+ Activate {
+ /// Whether the hit was on the tab indicator.
+ is_tab_indicator: bool,
+ },
}
impl<W: LayoutElement> InteractiveMoveState<W> {
@@ -515,7 +518,7 @@ 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 => (),
+ HitType::Activate { .. } => (),
}
self
}
diff --git a/src/layout/scrolling.rs b/src/layout/scrolling.rs
index ab0ad69a..18da2b46 100644
--- a/src/layout/scrolling.rs
+++ b/src/layout/scrolling.rs
@@ -14,7 +14,7 @@ use super::insert_hint_element::{InsertHintElement, InsertHintRenderElement};
use super::tab_indicator::{TabIndicator, TabIndicatorRenderElement, TabInfo};
use super::tile::{Tile, TileRenderElement, TileRenderSnapshot};
use super::workspace::{InteractiveResize, ResolvedSize};
-use super::{ConfigureIntent, InteractiveResizeData, LayoutElement, Options, RemovedTile};
+use super::{ConfigureIntent, HitType, InteractiveResizeData, LayoutElement, Options, RemovedTile};
use crate::animation::{Animation, Clock};
use crate::input::swipe_tracker::SwipeTracker;
use crate::niri_render_elements;
@@ -2645,6 +2645,51 @@ impl<W: LayoutElement> ScrollingSpace<W> {
rv
}
+ pub fn window_under(&self, pos: Point<f64, Logical>) -> Option<(&W, HitType)> {
+ // This matches self.tiles_with_render_positions().
+ let scale = self.scale;
+ let view_off = Point::from((-self.view_pos(), 0.));
+ for (col, col_x) in self.columns_in_render_order() {
+ let col_off = Point::from((col_x, 0.));
+ let col_render_off = col.render_offset();
+
+ // Hit the tab indicator.
+ if col.display_mode == ColumnDisplay::Tabbed && !col.is_fullscreen {
+ let col_pos = view_off + col_off + col_render_off;
+ let col_pos = col_pos.to_physical_precise_round(scale).to_logical(scale);
+
+ if let Some(idx) = col.tab_indicator.hit(
+ col.tab_indicator_area(),
+ col.tiles.len(),
+ scale,
+ pos - col_pos,
+ ) {
+ let hit = HitType::Activate {
+ is_tab_indicator: true,
+ };
+ return Some((col.tiles[idx].window(), hit));
+ }
+ }
+
+ for (tile, tile_off, visible) in col.tiles_in_render_order() {
+ if !visible {
+ continue;
+ }
+
+ let tile_pos =
+ view_off + col_off + col_render_off + tile_off + tile.render_offset();
+ // Round to physical pixels.
+ let tile_pos = tile_pos.to_physical_precise_round(scale).to_logical(scale);
+
+ if let Some(rv) = HitType::hit_tile(tile, tile_pos, pos) {
+ return Some(rv);
+ }
+ }
+ }
+
+ None
+ }
+
pub fn view_offset_gesture_begin(&mut self, is_touchpad: bool) {
if self.columns.is_empty() {
return;
diff --git a/src/layout/tab_indicator.rs b/src/layout/tab_indicator.rs
index 451f2224..ad457386 100644
--- a/src/layout/tab_indicator.rs
+++ b/src/layout/tab_indicator.rs
@@ -182,6 +182,27 @@ impl TabIndicator {
}
}
+ pub fn hit(
+ &self,
+ area: Rectangle<f64, Logical>,
+ tab_count: usize,
+ scale: f64,
+ point: Point<f64, Logical>,
+ ) -> Option<usize> {
+ if self.config.off {
+ return None;
+ }
+
+ let count = tab_count;
+ if self.config.hide_when_single_tab && count == 1 {
+ return None;
+ }
+
+ self.tab_rects(area, count, scale)
+ .enumerate()
+ .find_map(|(idx, rect)| rect.contains(point).then_some(idx))
+ }
+
pub fn render(
&self,
renderer: &mut impl NiriRenderer,
diff --git a/src/layout/tile.rs b/src/layout/tile.rs
index 7877457b..e3c1cce7 100644
--- a/src/layout/tile.rs
+++ b/src/layout/tile.rs
@@ -658,7 +658,9 @@ impl<W: LayoutElement> Tile<W> {
let win_pos = self.buf_loc();
Some(HitType::Input { win_pos })
} else if self.is_in_activation_region(point) {
- Some(HitType::Activate)
+ Some(HitType::Activate {
+ is_tab_indicator: false,
+ })
} else {
None
}
diff --git a/src/layout/workspace.rs b/src/layout/workspace.rs
index b5392644..25d2bb80 100644
--- a/src/layout/workspace.rs
+++ b/src/layout/workspace.rs
@@ -1475,14 +1475,18 @@ impl<W: LayoutElement> Workspace<W> {
}
pub fn window_under(&self, pos: Point<f64, Logical>) -> Option<(&W, HitType)> {
- self.tiles_with_render_positions()
- .find_map(|(tile, tile_pos, visible)| {
- if !visible {
- return None;
- }
+ // This logic is consistent with tiles_with_render_positions().
+ if self.is_floating_visible() {
+ if let Some(rv) = self
+ .floating
+ .tiles_with_render_positions()
+ .find_map(|(tile, tile_pos)| HitType::hit_tile(tile, tile_pos, pos))
+ {
+ return Some(rv);
+ }
+ }
- HitType::hit_tile(tile, tile_pos, pos)
- })
+ self.scrolling.window_under(pos)
}
pub fn resize_edges_under(&self, pos: Point<f64, Logical>) -> Option<ResizeEdge> {