mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-21 02:01:55 +07:00
Implement is-floating window rule matcher
This commit is contained in:
@@ -1031,6 +1031,8 @@ pub struct Match {
|
||||
#[knuffel(property)]
|
||||
pub is_active_in_column: Option<bool>,
|
||||
#[knuffel(property)]
|
||||
pub is_floating: Option<bool>,
|
||||
#[knuffel(property)]
|
||||
pub at_startup: Option<bool>,
|
||||
}
|
||||
|
||||
@@ -3403,6 +3405,7 @@ mod tests {
|
||||
is_active: None,
|
||||
is_focused: None,
|
||||
is_active_in_column: None,
|
||||
is_floating: None,
|
||||
at_startup: None,
|
||||
}],
|
||||
excludes: vec![
|
||||
@@ -3412,6 +3415,7 @@ mod tests {
|
||||
is_active: None,
|
||||
is_focused: None,
|
||||
is_active_in_column: None,
|
||||
is_floating: None,
|
||||
at_startup: None,
|
||||
},
|
||||
Match {
|
||||
@@ -3420,6 +3424,7 @@ mod tests {
|
||||
is_active: Some(true),
|
||||
is_focused: Some(false),
|
||||
is_active_in_column: None,
|
||||
is_floating: None,
|
||||
at_startup: None,
|
||||
},
|
||||
],
|
||||
|
||||
@@ -220,6 +220,8 @@ impl LayoutElement for TestWindow {
|
||||
|
||||
fn set_active_in_column(&mut self, _active: bool) {}
|
||||
|
||||
fn set_floating(&mut self, _floating: bool) {}
|
||||
|
||||
fn set_bounds(&self, _bounds: Size<i32, Logical>) {}
|
||||
|
||||
fn configure_intent(&self) -> ConfigureIntent {
|
||||
|
||||
@@ -1029,6 +1029,7 @@ impl<W: LayoutElement> FloatingSpace<W> {
|
||||
let win = tile.window_mut();
|
||||
|
||||
win.set_active_in_column(true);
|
||||
win.set_floating(true);
|
||||
|
||||
let is_active = is_active && Some(win.id()) == active.as_ref();
|
||||
win.set_activated(is_active);
|
||||
|
||||
@@ -186,6 +186,7 @@ pub trait LayoutElement {
|
||||
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_floating(&mut self, floating: bool);
|
||||
fn set_bounds(&self, bounds: Size<i32, Logical>);
|
||||
|
||||
fn configure_intent(&self) -> ConfigureIntent;
|
||||
@@ -3746,6 +3747,7 @@ impl<W: LayoutElement> Layout<W> {
|
||||
let win = move_.tile.window_mut();
|
||||
|
||||
win.set_active_in_column(true);
|
||||
win.set_floating(move_.is_floating);
|
||||
win.set_activated(true);
|
||||
|
||||
win.set_interactive_resize(None);
|
||||
@@ -4074,6 +4076,8 @@ mod tests {
|
||||
|
||||
fn set_active_in_column(&mut self, _active: bool) {}
|
||||
|
||||
fn set_floating(&mut self, _floating: bool) {}
|
||||
|
||||
fn is_fullscreen(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
@@ -2614,6 +2614,7 @@ impl<W: LayoutElement> ScrollingSpace<W> {
|
||||
|
||||
let active_in_column = col.active_tile_idx == tile_idx;
|
||||
win.set_active_in_column(active_in_column);
|
||||
win.set_floating(false);
|
||||
|
||||
let active = is_active && self.active_column_idx == col_idx && active_in_column;
|
||||
win.set_activated(active);
|
||||
|
||||
@@ -66,6 +66,9 @@ pub struct Mapped {
|
||||
/// Whether this window is the active window in its column.
|
||||
is_active_in_column: bool,
|
||||
|
||||
/// Whether this window is floating.
|
||||
is_floating: bool,
|
||||
|
||||
/// Buffer to draw instead of the window when it should be blocked out.
|
||||
block_out_buffer: RefCell<SolidColorBuffer>,
|
||||
|
||||
@@ -163,6 +166,7 @@ impl Mapped {
|
||||
need_to_recompute_rules: false,
|
||||
is_focused: false,
|
||||
is_active_in_column: false,
|
||||
is_floating: false,
|
||||
block_out_buffer: RefCell::new(SolidColorBuffer::new((0., 0.), [0., 0., 0., 1.])),
|
||||
animate_next_configure: false,
|
||||
animate_serials: Vec::new(),
|
||||
@@ -220,6 +224,10 @@ impl Mapped {
|
||||
self.is_active_in_column
|
||||
}
|
||||
|
||||
pub fn is_floating(&self) -> bool {
|
||||
self.is_floating
|
||||
}
|
||||
|
||||
pub fn set_is_focused(&mut self, is_focused: bool) {
|
||||
if self.is_focused == is_focused {
|
||||
return;
|
||||
@@ -690,6 +698,12 @@ impl LayoutElement for Mapped {
|
||||
self.need_to_recompute_rules |= changed;
|
||||
}
|
||||
|
||||
fn set_floating(&mut self, floating: bool) {
|
||||
let changed = self.is_floating != floating;
|
||||
self.is_floating = floating;
|
||||
self.need_to_recompute_rules |= changed;
|
||||
}
|
||||
|
||||
fn set_bounds(&self, bounds: Size<i32, Logical>) {
|
||||
self.toplevel().with_pending_state(|state| {
|
||||
state.bounds = Some(bounds);
|
||||
|
||||
@@ -115,6 +115,21 @@ impl<'a> WindowRef<'a> {
|
||||
WindowRef::Mapped(mapped) => mapped.is_active_in_column(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_floating(self) -> bool {
|
||||
match self {
|
||||
// FIXME: This means you cannot set initial configure rules based on is-floating. I'm
|
||||
// not sure there's a good way to support it, since this matcher makes a cycle with the
|
||||
// open-floating rule.
|
||||
//
|
||||
// That said, I don't think there are a lot of useful initial configure properties you
|
||||
// may want to set through an is-floating matcher? Like, if you're configuring a
|
||||
// specific window to open as floating, you can also set those properties in that same
|
||||
// window rule, rather than relying on a different is-floating rule.
|
||||
WindowRef::Unmapped(_) => false,
|
||||
WindowRef::Mapped(mapped) => mapped.is_floating(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ResolvedWindowRules {
|
||||
@@ -381,5 +396,11 @@ fn window_matches(window: WindowRef, role: &XdgToplevelSurfaceRoleAttributes, m:
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(is_floating) = m.is_floating {
|
||||
if window.is_floating() != is_floating {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ window-rule {
|
||||
match is-active=true
|
||||
match is-focused=false
|
||||
match is-active-in-column=true
|
||||
match is-floating=true
|
||||
match at-startup=true
|
||||
|
||||
// Properties that apply once upon window opening.
|
||||
@@ -198,6 +199,23 @@ window-rule {
|
||||
}
|
||||
```
|
||||
|
||||
#### `is-floating`
|
||||
|
||||
<sup>Since: next release</sup>
|
||||
|
||||
Can be `true` or `false`.
|
||||
Matches floating windows.
|
||||
|
||||
> [!NOTE]
|
||||
> This matcher will apply only after the window is already open.
|
||||
> This means that you cannot use it to change the window opening properties like `default-window-height` or `open-on-workspace`.
|
||||
|
||||
```kdl
|
||||
window-rule {
|
||||
match is-floating=true
|
||||
}
|
||||
```
|
||||
|
||||
#### `at-startup`
|
||||
|
||||
<sup>Since: 0.1.6</sup>
|
||||
|
||||
Reference in New Issue
Block a user