aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheZoq2 <frans.skarman@protonmail.com>2024-04-22 22:51:52 +0200
committerIvan Molodetskikh <yalterz@gmail.com>2024-05-11 10:42:49 +0400
commit47a8e75fd585e351dd2846a58152a7766403ca11 (patch)
treebf8b53c9befcb935a9a228a09db8649d58ba7751
parent6d9cfe28823e88df68f172496c928bd366777ad1 (diff)
downloadniri-47a8e75fd585e351dd2846a58152a7766403ca11.tar.gz
niri-47a8e75fd585e351dd2846a58152a7766403ca11.tar.bz2
niri-47a8e75fd585e351dd2846a58152a7766403ca11.zip
Add is_active_in_column
Add missing ``` Fix tests
-rw-r--r--niri-config/src/lib.rs5
-rw-r--r--niri-visual-tests/src/test_window.rs2
-rw-r--r--src/layout/mod.rs3
-rw-r--r--src/layout/workspace.rs8
-rw-r--r--src/window/mapped.rs10
-rw-r--r--src/window/mod.rs13
-rw-r--r--wiki/Configuration:-Window-Rules.md14
7 files changed, 52 insertions, 3 deletions
diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs
index 9f61bce3..52676fa8 100644
--- a/niri-config/src/lib.rs
+++ b/niri-config/src/lib.rs
@@ -734,6 +734,8 @@ pub struct Match {
pub is_active: Option<bool>,
#[knuffel(property)]
pub is_focused: Option<bool>,
+ #[knuffel(property)]
+ pub is_active_in_column: Option<bool>,
}
impl PartialEq for Match {
@@ -2416,6 +2418,7 @@ mod tests {
title: None,
is_active: None,
is_focused: None,
+ is_active_in_column: None,
}],
excludes: vec![
Match {
@@ -2423,12 +2426,14 @@ mod tests {
title: Some(Regex::new("~").unwrap()),
is_active: None,
is_focused: None,
+ is_active_in_column: None,
},
Match {
app_id: None,
title: None,
is_active: Some(true),
is_focused: Some(false),
+ is_active_in_column: None,
},
],
open_on_output: Some("eDP-1".to_owned()),
diff --git a/niri-visual-tests/src/test_window.rs b/niri-visual-tests/src/test_window.rs
index ac2ec996..8f163d2c 100644
--- a/niri-visual-tests/src/test_window.rs
+++ b/niri-visual-tests/src/test_window.rs
@@ -213,6 +213,8 @@ impl LayoutElement for TestWindow {
fn set_activated(&mut self, _active: bool) {}
+ fn set_active_in_column(&mut self, _active: bool) {}
+
fn set_bounds(&self, _bounds: Size<i32, Logical>) {}
fn send_pending_configure(&mut self) {}
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index 75f6cd4c..0cb8e493 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -152,6 +152,7 @@ pub trait LayoutElement {
fn output_leave(&self, output: &Output);
fn set_offscreen_element_id(&self, id: Option<Id>);
fn set_activated(&mut self, active: bool);
+ fn set_active_in_column(&mut self, active: bool);
fn set_bounds(&self, bounds: Size<i32, Logical>);
fn send_pending_configure(&mut self);
@@ -2190,6 +2191,8 @@ mod tests {
fn send_pending_configure(&mut self) {}
+ fn set_active_in_column(&mut self, _active: bool) {}
+
fn is_fullscreen(&self) -> bool {
false
}
diff --git a/src/layout/workspace.rs b/src/layout/workspace.rs
index 3dbb473b..b2d1d5a2 100644
--- a/src/layout/workspace.rs
+++ b/src/layout/workspace.rs
@@ -2459,9 +2459,11 @@ impl<W: LayoutElement> Workspace<W> {
for (tile_idx, tile) in col.tiles.iter_mut().enumerate() {
let win = tile.window_mut();
- let active = is_active
- && self.active_column_idx == col_idx
- && col.active_tile_idx == tile_idx;
+
+ let active_in_column = col.active_tile_idx == tile_idx;
+ win.set_active_in_column(active_in_column);
+
+ let active = is_active && self.active_column_idx == col_idx && active_in_column;
win.set_activated(active);
win.set_interactive_resize(col_resize_data);
diff --git a/src/window/mapped.rs b/src/window/mapped.rs
index 4b31da22..bdb62df8 100644
--- a/src/window/mapped.rs
+++ b/src/window/mapped.rs
@@ -49,6 +49,9 @@ pub struct Mapped {
/// Whether this window has the keyboard focus.
is_focused: bool,
+ /// Whether this window is the active window in its column.
+ pub is_active_in_column: bool,
+
/// Buffer to draw instead of the window when it should be blocked out.
block_out_buffer: RefCell<SolidColorBuffer>,
@@ -102,6 +105,7 @@ impl Mapped {
rules,
need_to_recompute_rules: false,
is_focused: false,
+ is_active_in_column: false,
block_out_buffer: RefCell::new(SolidColorBuffer::new((0, 0), [0., 0., 0., 1.])),
animate_next_configure: false,
animate_serials: Vec::new(),
@@ -458,6 +462,12 @@ impl LayoutElement for Mapped {
self.need_to_recompute_rules |= changed;
}
+ fn set_active_in_column(&mut self, active: bool) {
+ let changed = self.is_active_in_column != active;
+ self.is_active_in_column = active;
+ self.need_to_recompute_rules |= changed;
+ }
+
fn set_bounds(&self, bounds: Size<i32, Logical>) {
self.toplevel().with_pending_state(|state| {
state.bounds = Some(bounds);
diff --git a/src/window/mod.rs b/src/window/mod.rs
index 3af9eebd..4ccbb111 100644
--- a/src/window/mod.rs
+++ b/src/window/mod.rs
@@ -85,6 +85,13 @@ impl<'a> WindowRef<'a> {
WindowRef::Mapped(mapped) => mapped.is_focused(),
}
}
+
+ pub fn is_active_in_column(self) -> bool {
+ match self {
+ WindowRef::Unmapped(_) => false,
+ WindowRef::Mapped(mapped) => mapped.is_active_in_column,
+ }
+ }
}
impl ResolvedWindowRules {
@@ -254,5 +261,11 @@ fn window_matches(window: WindowRef, role: &XdgToplevelSurfaceRoleAttributes, m:
}
}
+ if let Some(is_active_in_column) = m.is_active_in_column {
+ if window.is_active_in_column() != is_active_in_column {
+ return false;
+ }
+ }
+
true
}
diff --git a/wiki/Configuration:-Window-Rules.md b/wiki/Configuration:-Window-Rules.md
index 6cdb2320..02a53a5f 100644
--- a/wiki/Configuration:-Window-Rules.md
+++ b/wiki/Configuration:-Window-Rules.md
@@ -174,6 +174,20 @@ window-rule {
}
```
+#### `is-active-in-column`
+
+Can be `true` or `false`.
+Matches the window that is the "active" window in its column.
+
+Contrary to `is-active`, there is always one `is-active-in-column` window in each column.
+It is the window that was last focused in the column, i.e. the one that will gain focus if this column is focused.
+
+```
+window-rule {
+ match is-active-in-column=true
+}
+```
+
### Window Opening Properties
These properties apply once, when a window first opens.