Activate windows when clicking on the border

This commit is contained in:
Ivan Molodetskikh
2023-12-28 08:45:12 +04:00
parent 777ad4ee5c
commit b13892ca63
5 changed files with 41 additions and 9 deletions
+8 -1
View File
@@ -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;
};
+2 -2
View File
@@ -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];
+6 -1
View File
@@ -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() {
+16 -5
View File
@@ -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));
}
}
+9
View File
@@ -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(),