mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-24 02:01:18 +07:00
Add open-focused window rule
This commit is contained in:
@@ -985,6 +985,8 @@ pub struct WindowRule {
|
||||
pub open_fullscreen: Option<bool>,
|
||||
#[knuffel(child, unwrap(argument))]
|
||||
pub open_floating: Option<bool>,
|
||||
#[knuffel(child, unwrap(argument))]
|
||||
pub open_focused: Option<bool>,
|
||||
|
||||
// Rules applied dynamically.
|
||||
#[knuffel(child, unwrap(argument))]
|
||||
@@ -3142,6 +3144,7 @@ mod tests {
|
||||
open-maximized true
|
||||
open-fullscreen false
|
||||
open-floating false
|
||||
open-focused true
|
||||
|
||||
focus-ring {
|
||||
off
|
||||
@@ -3421,6 +3424,7 @@ mod tests {
|
||||
open_maximized: Some(true),
|
||||
open_fullscreen: Some(false),
|
||||
open_floating: Some(false),
|
||||
open_focused: Some(true),
|
||||
focus_ring: BorderRule {
|
||||
off: true,
|
||||
width: Some(FloatOrInt(3.)),
|
||||
|
||||
+26
-16
@@ -126,6 +126,32 @@ impl CompositorHandler for State {
|
||||
// moment, that is here.
|
||||
let is_floating = rules.compute_open_floating(toplevel);
|
||||
|
||||
// Figure out if we should activate the window.
|
||||
let activate = rules.open_focused.map(|focus| {
|
||||
if focus {
|
||||
ActivateWindow::Yes
|
||||
} else {
|
||||
ActivateWindow::No
|
||||
}
|
||||
});
|
||||
let activate = activate.unwrap_or_else(|| {
|
||||
// Check the token timestamp again in case the window took a while between
|
||||
// requesting activation and mapping.
|
||||
let token = activation_token_data.filter(|token| {
|
||||
token.timestamp.elapsed() < XDG_ACTIVATION_TOKEN_TIMEOUT
|
||||
});
|
||||
if token.is_some() {
|
||||
ActivateWindow::Yes
|
||||
} else {
|
||||
let config = self.niri.config.borrow();
|
||||
if config.debug.strict_new_window_focus_policy {
|
||||
ActivateWindow::No
|
||||
} else {
|
||||
ActivateWindow::Smart
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let parent = toplevel
|
||||
.parent()
|
||||
.and_then(|parent| self.niri.layout.find_window_and_output(&parent))
|
||||
@@ -146,22 +172,6 @@ impl CompositorHandler for State {
|
||||
let mapped = Mapped::new(window, rules, hook);
|
||||
let window = mapped.window.clone();
|
||||
|
||||
// Check the token timestamp again in case the window took a while between
|
||||
// requesting activation and mapping.
|
||||
let activate = match activation_token_data
|
||||
.filter(|token| token.timestamp.elapsed() < XDG_ACTIVATION_TOKEN_TIMEOUT)
|
||||
{
|
||||
Some(_) => ActivateWindow::Yes,
|
||||
None => {
|
||||
let config = self.niri.config.borrow();
|
||||
if config.debug.strict_new_window_focus_policy {
|
||||
ActivateWindow::No
|
||||
} else {
|
||||
ActivateWindow::Smart
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let target = if let Some(p) = &parent {
|
||||
// Open dialogs next to their parent window.
|
||||
AddWindowTarget::NextTo(p)
|
||||
|
||||
@@ -49,6 +49,9 @@ pub struct ResolvedWindowRules {
|
||||
/// Whether the window should open floating.
|
||||
pub open_floating: Option<bool>,
|
||||
|
||||
/// Whether the window should open focused.
|
||||
pub open_focused: Option<bool>,
|
||||
|
||||
/// Extra bound on the minimum window width.
|
||||
pub min_width: Option<u16>,
|
||||
/// Extra bound on the minimum window height.
|
||||
@@ -116,6 +119,7 @@ impl ResolvedWindowRules {
|
||||
open_maximized: None,
|
||||
open_fullscreen: None,
|
||||
open_floating: None,
|
||||
open_focused: None,
|
||||
min_width: None,
|
||||
min_height: None,
|
||||
max_width: None,
|
||||
@@ -208,6 +212,10 @@ impl ResolvedWindowRules {
|
||||
resolved.open_floating = Some(x);
|
||||
}
|
||||
|
||||
if let Some(x) = rule.open_focused {
|
||||
resolved.open_focused = Some(x);
|
||||
}
|
||||
|
||||
if let Some(x) = rule.min_width {
|
||||
resolved.min_width = Some(x);
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ window-rule {
|
||||
open-maximized true
|
||||
open-fullscreen true
|
||||
open-floating true
|
||||
open-focused false
|
||||
|
||||
// Properties that apply continuously.
|
||||
draw-border-with-background false
|
||||
@@ -338,6 +339,35 @@ window-rule {
|
||||
}
|
||||
```
|
||||
|
||||
#### `open-focused`
|
||||
|
||||
<sup>Since: next release</sup>
|
||||
|
||||
Set this to `false` to prevent this window from being automatically focused upon opening.
|
||||
|
||||
```kdl
|
||||
// Don't give focus to the GIMP startup splash screen.
|
||||
window-rule {
|
||||
match app-id="^gimp" title="^GIMP Startup$"
|
||||
|
||||
open-focused false
|
||||
}
|
||||
```
|
||||
|
||||
You can also set this to `true` to focus the window, even if normally it wouldn't get auto-focused.
|
||||
|
||||
```kdl
|
||||
// Always focus the KeePassXC-Browser unlock dialog.
|
||||
//
|
||||
// This dialog opens parented to the KeePassXC window rather than the browser,
|
||||
// so it doesn't get auto-focused by default.
|
||||
window-rule {
|
||||
match app-id=r#"^org\.keepassxc\.KeePassXC$"# title="^Unlock Database - KeePassXC$"
|
||||
|
||||
open-focused true
|
||||
}
|
||||
```
|
||||
|
||||
### Dynamic Properties
|
||||
|
||||
These properties apply continuously to open windows.
|
||||
|
||||
Reference in New Issue
Block a user