diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-11-29 21:11:02 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-12-30 20:12:37 +0300 |
| commit | c5fffd6e2c48aa7fb8b45b8bdcd972bbd8ce900b (patch) | |
| tree | f4bf7c768d21cd72d81da6ca0d1b084631e71276 /src/window/mod.rs | |
| parent | 951f63b6fd48b47ca60e8ed6aa91b4a7b47534f9 (diff) | |
| download | niri-c5fffd6e2c48aa7fb8b45b8bdcd972bbd8ce900b.tar.gz niri-c5fffd6e2c48aa7fb8b45b8bdcd972bbd8ce900b.tar.bz2 niri-c5fffd6e2c48aa7fb8b45b8bdcd972bbd8ce900b.zip | |
Initial WIP floating window implementation
Diffstat (limited to 'src/window/mod.rs')
| -rw-r--r-- | src/window/mod.rs | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/src/window/mod.rs b/src/window/mod.rs index 98c26e7f..4f4b6674 100644 --- a/src/window/mod.rs +++ b/src/window/mod.rs @@ -3,7 +3,10 @@ use std::cmp::{max, min}; use niri_config::{BlockOutFrom, BorderRule, CornerRadius, Match, WindowRule}; use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel; use smithay::utils::{Logical, Size}; -use smithay::wayland::shell::xdg::{ToplevelSurface, XdgToplevelSurfaceRoleAttributes}; +use smithay::wayland::compositor::with_states; +use smithay::wayland::shell::xdg::{ + SurfaceCachedState, ToplevelSurface, XdgToplevelSurfaceRoleAttributes, +}; use crate::layout::scrolling::ColumnWidth; use crate::utils::with_toplevel_role; @@ -43,6 +46,9 @@ pub struct ResolvedWindowRules { /// Whether the window should open fullscreen. pub open_fullscreen: Option<bool>, + /// Whether the window should open floating. + pub open_floating: Option<bool>, + /// Extra bound on the minimum window width. pub min_width: Option<u16>, /// Extra bound on the minimum window height. @@ -109,6 +115,7 @@ impl ResolvedWindowRules { open_on_workspace: None, open_maximized: None, open_fullscreen: None, + open_floating: None, min_width: None, min_height: None, max_width: None, @@ -197,6 +204,10 @@ impl ResolvedWindowRules { resolved.open_fullscreen = Some(x); } + if let Some(x) = rule.open_floating { + resolved.open_floating = Some(x); + } + if let Some(x) = rule.min_width { resolved.min_width = Some(x); } @@ -273,6 +284,28 @@ impl ResolvedWindowRules { size } + + pub fn compute_open_floating(&self, toplevel: &ToplevelSurface) -> bool { + if let Some(res) = self.open_floating { + return res; + } + + // Windows with a parent (usually dialogs) open as floating by default. + if toplevel.parent().is_some() { + return true; + } + + let (mut min_size, mut max_size) = with_states(toplevel.wl_surface(), |state| { + let mut guard = state.cached_state.get::<SurfaceCachedState>(); + let current = guard.current(); + (current.min_size, current.max_size) + }); + min_size = self.apply_min_size(min_size); + max_size = self.apply_max_size(max_size); + + // We open fixed-height windows as floating. + min_size.h > 0 && min_size.h == max_size.h + } } fn window_matches(window: WindowRef, role: &XdgToplevelSurfaceRoleAttributes, m: &Match) -> bool { |
