diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2023-12-28 08:45:12 +0400 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2023-12-28 08:45:12 +0400 |
| commit | b13892ca637cccfb496e3204b2793c069af17ccb (patch) | |
| tree | 751ba2381c595baae1296eb8cbd5889418541b10 /src | |
| parent | 777ad4ee5c8cf84b2bfa13c6bdb0d254c24881f9 (diff) | |
| download | niri-b13892ca637cccfb496e3204b2793c069af17ccb.tar.gz niri-b13892ca637cccfb496e3204b2793c069af17ccb.tar.bz2 niri-b13892ca637cccfb496e3204b2793c069af17ccb.zip | |
Activate windows when clicking on the border
Diffstat (limited to 'src')
| -rw-r--r-- | src/layout/mod.rs | 9 | ||||
| -rw-r--r-- | src/layout/monitor.rs | 4 | ||||
| -rw-r--r-- | src/layout/tile.rs | 7 | ||||
| -rw-r--r-- | src/layout/workspace.rs | 21 | ||||
| -rw-r--r-- | src/niri.rs | 9 |
5 files changed, 41 insertions, 9 deletions
diff --git a/src/layout/mod.rs b/src/layout/mod.rs index 484a377a..1a9b5076 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -920,11 +920,18 @@ impl<W: LayoutElement> Layout<W> { monitors[*active_monitor_idx].focus() } + /// 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. pub fn window_under( &self, output: &Output, pos_within_output: Point<f64, Logical>, - ) -> Option<(&W, Point<i32, Logical>)> { + ) -> Option<(&W, Option<Point<i32, Logical>>)> { let MonitorSet::Normal { monitors, .. } = &self.monitor_set else { return None; }; diff --git a/src/layout/monitor.rs b/src/layout/monitor.rs index aefbf29f..aa4c439e 100644 --- a/src/layout/monitor.rs +++ b/src/layout/monitor.rs @@ -450,7 +450,7 @@ impl<W: LayoutElement> Monitor<W> { pub fn window_under( &self, pos_within_output: Point<f64, Logical>, - ) -> Option<(&W, Point<i32, Logical>)> { + ) -> Option<(&W, Option<Point<i32, Logical>>)> { match &self.workspace_switch { Some(switch) => { let size = output_size(&self.output); @@ -469,7 +469,7 @@ impl<W: LayoutElement> Monitor<W> { let ws = &self.workspaces[idx]; let (win, win_pos) = ws.window_under(pos_within_output + ws_offset.to_f64())?; - Some((win, win_pos - ws_offset)) + Some((win, win_pos.map(|p| p - ws_offset))) } None => { let ws = &self.workspaces[self.active_workspace_idx]; diff --git a/src/layout/tile.rs b/src/layout/tile.rs index 56af4fa4..ea8515af 100644 --- a/src/layout/tile.rs +++ b/src/layout/tile.rs @@ -6,7 +6,7 @@ use smithay::backend::renderer::element::solid::{SolidColorBuffer, SolidColorRen use smithay::backend::renderer::element::utils::{Relocate, RelocateRenderElement}; use smithay::backend::renderer::element::Kind; use smithay::backend::renderer::{ImportAll, Renderer}; -use smithay::utils::{Logical, Point, Scale, Size}; +use smithay::utils::{Logical, Point, Rectangle, Scale, Size}; use super::focus_ring::FocusRing; use super::workspace::WorkspaceRenderElement; @@ -150,6 +150,11 @@ impl<W: LayoutElement> Tile<W> { self.window.is_in_input_region(point) } + pub fn is_in_activation_region(&self, point: Point<f64, Logical>) -> bool { + let activation_region = Rectangle::from_loc_and_size((0, 0), self.tile_size()); + activation_region.to_f64().contains(point) + } + pub fn request_tile_size(&mut self, mut size: Size<i32, Logical>) { // Can't go through effective_border_width() because we might be fullscreen. if !self.border.is_off() { diff --git a/src/layout/workspace.rs b/src/layout/workspace.rs index 32302187..090e27dd 100644 --- a/src/layout/workspace.rs +++ b/src/layout/workspace.rs @@ -761,7 +761,10 @@ impl<W: LayoutElement> Workspace<W> { self.column_x(self.active_column_idx) + self.view_offset } - pub fn window_under(&self, pos: Point<f64, Logical>) -> Option<(&W, Point<i32, Logical>)> { + pub fn window_under( + &self, + pos: Point<f64, Logical>, + ) -> Option<(&W, Option<Point<i32, Logical>>)> { if self.columns.is_empty() { return None; } @@ -775,8 +778,12 @@ impl<W: LayoutElement> Workspace<W> { self.column_x(self.active_column_idx) - view_pos, col.tile_y(col.active_tile_idx), )); - if active_tile.is_in_input_region(pos - tile_pos.to_f64()) { - return Some((active_tile.window(), tile_pos + active_tile.buf_loc())); + let pos_within_tile = pos - tile_pos.to_f64(); + if active_tile.is_in_input_region(pos_within_tile) { + let pos_within_surface = tile_pos + active_tile.buf_loc(); + return Some((active_tile.window(), Some(pos_within_surface))); + } else if active_tile.is_in_activation_region(pos_within_tile) { + return Some((active_tile.window(), None)); } let mut x = -view_pos; @@ -788,8 +795,12 @@ impl<W: LayoutElement> Workspace<W> { } let tile_pos = Point::from((x, y)); - if tile.is_in_input_region(pos - tile_pos.to_f64()) { - return Some((tile.window(), tile_pos + tile.buf_loc())); + let pos_within_tile = pos - tile_pos.to_f64(); + if tile.is_in_input_region(pos_within_tile) { + let pos_within_surface = tile_pos + tile.buf_loc(); + return Some((tile.window(), Some(pos_within_surface))); + } else if tile.is_in_activation_region(pos_within_tile) { + return Some((tile.window(), None)); } } diff --git a/src/niri.rs b/src/niri.rs index a0a98c90..3a3a4f4d 100644 --- a/src/niri.rs +++ b/src/niri.rs @@ -1035,6 +1035,10 @@ impl Niri { Some((output, pos_within_output)) } + /// Returns the window under the position to be activated. + /// + /// The cursor may be inside the window's activation region, but not within the window's input + /// region. pub fn window_under(&self, pos: Point<f64, Logical>) -> Option<&Window> { if self.is_locked() || self.screenshot_ui.is_open() { return None; @@ -1045,6 +1049,10 @@ impl Niri { Some(window) } + /// Returns the window under the cursor to be activated. + /// + /// The cursor may be inside the window's activation region, but not within the window's input + /// region. pub fn window_under_cursor(&self) -> Option<&Window> { let pos = self.seat.get_pointer().unwrap().current_location(); self.window_under(pos) @@ -1103,6 +1111,7 @@ impl Niri { self.layout .window_under(output, pos_within_output) .and_then(|(window, win_pos_within_output)| { + let win_pos_within_output = win_pos_within_output?; window .surface_under( pos_within_output - win_pos_within_output.to_f64(), |
