diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-12-11 09:27:38 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-12-30 20:12:37 +0300 |
| commit | 10460191b93194ed4d9dc16e1fd7a2eb6f297ae3 (patch) | |
| tree | 7188b36849ef71caca2a1cf69fc577c351dc4f0f /src/layout | |
| parent | c5fffd6e2c48aa7fb8b45b8bdcd972bbd8ce900b (diff) | |
| download | niri-10460191b93194ed4d9dc16e1fd7a2eb6f297ae3.tar.gz niri-10460191b93194ed4d9dc16e1fd7a2eb6f297ae3.tar.bz2 niri-10460191b93194ed4d9dc16e1fd7a2eb6f297ae3.zip | |
Honor min/max size in more places like initial configure
Diffstat (limited to 'src/layout')
| -rw-r--r-- | src/layout/floating.rs | 50 | ||||
| -rw-r--r-- | src/layout/mod.rs | 18 | ||||
| -rw-r--r-- | src/layout/workspace.rs | 56 |
3 files changed, 82 insertions, 42 deletions
diff --git a/src/layout/floating.rs b/src/layout/floating.rs index 75345eed..64446c61 100644 --- a/src/layout/floating.rs +++ b/src/layout/floating.rs @@ -1,4 +1,4 @@ -use std::cmp::{max, min}; +use std::cmp::max; use std::iter::zip; use std::rc::Rc; @@ -16,7 +16,7 @@ use crate::niri_render_elements; use crate::render_helpers::renderer::NiriRenderer; use crate::render_helpers::RenderTarget; use crate::utils::transaction::TransactionBlocker; -use crate::utils::ResizeEdge; +use crate::utils::{ensure_min_max_size, ResizeEdge}; use crate::window::ResolvedWindowRules; /// Space for floating windows. @@ -332,13 +332,25 @@ impl<W: LayoutElement> FloatingSpace<W> { ) { tile.update_config(self.scale, self.options.clone()); - if tile.window().is_pending_fullscreen() { - tile.window_mut() - .request_size(Size::from((0, 0)), true, None); + let win = tile.window_mut(); + if win.is_pending_fullscreen() { + let mut size = Size::from((0, 0)); + + // Make sure fixed-size through window rules keeps working. + let min_size = win.min_size(); + let max_size = win.max_size(); + if min_size.w == max_size.w { + size.w = min_size.w; + } + if min_size.h == max_size.h { + size.h = min_size.h; + } + + win.request_size(size, true, None); } if activate || self.tiles.is_empty() { - self.active_window_id = Some(tile.window().id().clone()); + self.active_window_id = Some(win.id().clone()); } let mut pos = pos.unwrap_or_else(|| { @@ -500,15 +512,10 @@ impl<W: LayoutElement> FloatingSpace<W> { let tile = &mut self.tiles[idx]; let win = tile.window_mut(); - let min_w = win.min_size().w; - let max_w = win.max_size().w; + let min_size = win.min_size(); + let max_size = win.max_size(); - if max_w > 0 { - win_width = min(win_width, max_w); - } - if min_w > 0 { - win_width = max(win_width, min_w); - } + win_width = ensure_min_max_size(win_width, min_size.w, max_size.w); win_width = max(1, win_width); let win_height = win @@ -517,6 +524,8 @@ impl<W: LayoutElement> FloatingSpace<W> { // If we requested height = 0, then switch to the current height. .filter(|h| *h != 0) .unwrap_or_else(|| win.size().h); + let win_height = ensure_min_max_size(win_height, min_size.h, max_size.h); + let win_size = Size::from((win_width, win_height)); win.request_size(win_size, animate, None); } @@ -534,15 +543,10 @@ impl<W: LayoutElement> FloatingSpace<W> { let tile = &mut self.tiles[idx]; let win = tile.window_mut(); - let min_h = win.min_size().h; - let max_h = win.max_size().h; + let min_size = win.min_size(); + let max_size = win.max_size(); - if max_h > 0 { - win_height = min(win_height, max_h); - } - if min_h > 0 { - win_height = max(win_height, min_h); - } + win_height = ensure_min_max_size(win_height, min_size.h, max_size.h); win_height = max(1, win_height); let win_width = win @@ -551,6 +555,8 @@ impl<W: LayoutElement> FloatingSpace<W> { // If we requested width = 0, then switch to the current width. .filter(|w| *w != 0) .unwrap_or_else(|| win.size().w); + let win_width = ensure_min_max_size(win_width, min_size.w, max_size.w); + let win_size = Size::from((win_width, win_height)); win.request_size(win_size, animate, None); } diff --git a/src/layout/mod.rs b/src/layout/mod.rs index 48a7954a..916b6b41 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -3219,9 +3219,21 @@ impl<W: LayoutElement> Layout<W> { // prefer-no-csd, and occasionally that last size can become the full-width size // rather than a smaller size, which is annoying. Need to see if niri can use some // heuristics to make this case behave better. - if tile.window().is_pending_fullscreen() { - tile.window_mut() - .request_size(Size::from((0, 0)), true, None); + let win = tile.window_mut(); + if win.is_pending_fullscreen() { + let mut size = Size::from((0, 0)); + + // Make sure fixed-size through window rules keeps working. + let min_size = win.min_size(); + let max_size = win.max_size(); + if min_size.w == max_size.w { + size.w = min_size.w; + } + if min_size.h == max_size.h { + size.h = min_size.h; + } + + win.request_size(size, true, None); } let mut data = InteractiveMoveData { diff --git a/src/layout/workspace.rs b/src/layout/workspace.rs index 21ef208f..1e1ded9d 100644 --- a/src/layout/workspace.rs +++ b/src/layout/workspace.rs @@ -9,6 +9,8 @@ use smithay::output::Output; use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel; use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface; use smithay::utils::{Logical, Point, Rectangle, Scale, Serial, Size, Transform}; +use smithay::wayland::compositor::with_states; +use smithay::wayland::shell::xdg::SurfaceCachedState; use super::floating::{FloatingSpace, FloatingSpaceRenderElement}; use super::scrolling::{ @@ -22,7 +24,7 @@ use crate::render_helpers::renderer::NiriRenderer; use crate::render_helpers::RenderTarget; use crate::utils::id::IdCounter; use crate::utils::transaction::{Transaction, TransactionBlocker}; -use crate::utils::{output_size, send_scale_transform, ResizeEdge}; +use crate::utils::{ensure_min_max_size, output_size, send_scale_transform, ResizeEdge}; use crate::window::ResolvedWindowRules; #[derive(Debug)] @@ -680,12 +682,28 @@ impl<W: LayoutElement> Workspace<W> { width: Option<ColumnWidth>, is_floating: bool, rules: &ResolvedWindowRules, + (min_size, max_size): (Size<i32, Logical>, Size<i32, Logical>), ) -> Size<i32, Logical> { - if is_floating { + let mut size = if is_floating { Size::from((0, 0)) } else { self.scrolling.new_window_size(width, rules) + }; + + // If the window has a fixed size, or we're picking some fixed size, apply min and max + // size. This is to ensure that a fixed-size window rule works on open, while still + // allowing the window freedom to pick its default size otherwise. + let (min_size, max_size) = rules.apply_min_max_size(min_size, max_size); + if size.w > 0 || min_size.w == max_size.w { + size.w = ensure_min_max_size(size.w, min_size.w, max_size.w); + } + // For scrolling (where height is > 0) only ensure fixed height, since at runtime scrolling + // will only honor fixed height currently. + if min_size.h == max_size.h { + size.h = ensure_min_max_size(size.h, min_size.h, max_size.h); } + + size } pub fn configure_new_window( @@ -699,22 +717,26 @@ impl<W: LayoutElement> Workspace<W> { send_scale_transform(surface, data, self.scale, self.transform); }); - window - .toplevel() - .expect("no x11 support") - .with_pending_state(|state| { - if state.states.contains(xdg_toplevel::State::Fullscreen) { - state.size = Some(self.view_size.to_i32_round()); - } else { - state.size = Some(self.new_window_size(width, is_floating, rules)); - } + let toplevel = window.toplevel().expect("no x11 support"); + let (min_size, 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) + }); + toplevel.with_pending_state(|state| { + if state.states.contains(xdg_toplevel::State::Fullscreen) { + state.size = Some(self.view_size.to_i32_round()); + } else { + let size = self.new_window_size(width, is_floating, rules, (min_size, max_size)); + state.size = Some(size); + } - if is_floating { - state.bounds = Some(self.floating.toplevel_bounds(rules)); - } else { - state.bounds = Some(self.scrolling.toplevel_bounds(rules)); - } - }); + if is_floating { + state.bounds = Some(self.floating.toplevel_bounds(rules)); + } else { + state.bounds = Some(self.scrolling.toplevel_bounds(rules)); + } + }); } pub fn focus_left(&mut self) -> bool { |
