mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-24 02:01:18 +07:00
Honor min/max size in more places like initial configure
This commit is contained in:
@@ -159,8 +159,10 @@ impl Layout {
|
||||
|
||||
fn add_window(&mut self, mut window: TestWindow, width: Option<ColumnWidth>) {
|
||||
let ws = self.layout.active_workspace().unwrap();
|
||||
let min_size = window.min_size();
|
||||
let max_size = window.max_size();
|
||||
window.request_size(
|
||||
ws.new_window_size(width, false, window.rules()),
|
||||
ws.new_window_size(width, false, window.rules(), (min_size, max_size)),
|
||||
false,
|
||||
None,
|
||||
);
|
||||
@@ -183,8 +185,10 @@ impl Layout {
|
||||
width: Option<ColumnWidth>,
|
||||
) {
|
||||
let ws = self.layout.active_workspace().unwrap();
|
||||
let min_size = window.min_size();
|
||||
let max_size = window.max_size();
|
||||
window.request_size(
|
||||
ws.new_window_size(width, false, window.rules()),
|
||||
ws.new_window_size(width, false, window.rules(), (min_size, max_size)),
|
||||
false,
|
||||
None,
|
||||
);
|
||||
|
||||
+28
-22
@@ -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);
|
||||
}
|
||||
|
||||
+15
-3
@@ -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 {
|
||||
|
||||
+29
-7
@@ -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,14 +717,18 @@ impl<W: LayoutElement> Workspace<W> {
|
||||
send_scale_transform(surface, data, self.scale, self.transform);
|
||||
});
|
||||
|
||||
window
|
||||
.toplevel()
|
||||
.expect("no x11 support")
|
||||
.with_pending_state(|state| {
|
||||
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 {
|
||||
state.size = Some(self.new_window_size(width, is_floating, rules));
|
||||
let size = self.new_window_size(width, is_floating, rules, (min_size, max_size));
|
||||
state.size = Some(size);
|
||||
}
|
||||
|
||||
if is_floating {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use std::cmp::{max, min};
|
||||
use std::ffi::{CString, OsStr};
|
||||
use std::io::Write;
|
||||
use std::os::unix::prelude::OsStrExt;
|
||||
@@ -261,6 +262,16 @@ pub fn get_credentials_for_surface(surface: &WlSurface) -> Option<Credentials> {
|
||||
client.get_credentials(&dh).ok()
|
||||
}
|
||||
|
||||
pub fn ensure_min_max_size(mut x: i32, min_size: i32, max_size: i32) -> i32 {
|
||||
if max_size > 0 {
|
||||
x = min(x, max_size);
|
||||
}
|
||||
if min_size > 0 {
|
||||
x = max(x, min_size);
|
||||
}
|
||||
x
|
||||
}
|
||||
|
||||
#[cfg(feature = "dbus")]
|
||||
pub fn show_screenshot_notification(image_path: Option<PathBuf>) {
|
||||
let mut notification = notify_rust::Notification::new();
|
||||
|
||||
+12
-3
@@ -285,6 +285,16 @@ impl ResolvedWindowRules {
|
||||
size
|
||||
}
|
||||
|
||||
pub fn apply_min_max_size(
|
||||
&self,
|
||||
min_size: Size<i32, Logical>,
|
||||
max_size: Size<i32, Logical>,
|
||||
) -> (Size<i32, Logical>, Size<i32, Logical>) {
|
||||
let min_size = self.apply_min_size(min_size);
|
||||
let max_size = self.apply_max_size(max_size);
|
||||
(min_size, max_size)
|
||||
}
|
||||
|
||||
pub fn compute_open_floating(&self, toplevel: &ToplevelSurface) -> bool {
|
||||
if let Some(res) = self.open_floating {
|
||||
return res;
|
||||
@@ -295,13 +305,12 @@ impl ResolvedWindowRules {
|
||||
return true;
|
||||
}
|
||||
|
||||
let (mut min_size, mut max_size) = with_states(toplevel.wl_surface(), |state| {
|
||||
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)
|
||||
});
|
||||
min_size = self.apply_min_size(min_size);
|
||||
max_size = self.apply_max_size(max_size);
|
||||
let (min_size, max_size) = self.apply_min_max_size(min_size, max_size);
|
||||
|
||||
// We open fixed-height windows as floating.
|
||||
min_size.h > 0 && min_size.h == max_size.h
|
||||
|
||||
Reference in New Issue
Block a user