mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-24 02:01:18 +07:00
floating: Take into account non-fixed min/max size window rule
This commit is contained in:
@@ -20,7 +20,7 @@ use crate::render_helpers::RenderTarget;
|
|||||||
use crate::utils::transaction::TransactionBlocker;
|
use crate::utils::transaction::TransactionBlocker;
|
||||||
use crate::utils::{
|
use crate::utils::{
|
||||||
center_preferring_top_left_in_area, clamp_preferring_top_left_in_area, ensure_min_max_size,
|
center_preferring_top_left_in_area, clamp_preferring_top_left_in_area, ensure_min_max_size,
|
||||||
ResizeEdge,
|
ensure_min_max_size_maybe_zero, ResizeEdge,
|
||||||
};
|
};
|
||||||
use crate::window::ResolvedWindowRules;
|
use crate::window::ResolvedWindowRules;
|
||||||
|
|
||||||
@@ -386,15 +386,14 @@ impl<W: LayoutElement> FloatingSpace<W> {
|
|||||||
// fullscreen until now), fall back to (0, 0).
|
// fullscreen until now), fall back to (0, 0).
|
||||||
floating_size.unwrap_or_else(|| win.expected_size().unwrap_or_default())
|
floating_size.unwrap_or_else(|| win.expected_size().unwrap_or_default())
|
||||||
};
|
};
|
||||||
// Make sure fixed-size through window rules keeps working.
|
|
||||||
|
// Apply min/max size window rules. If requesting a concrete size, apply completely; if
|
||||||
|
// requesting (0, 0), apply only when min/max results in a fixed size.
|
||||||
let min_size = win.min_size();
|
let min_size = win.min_size();
|
||||||
let max_size = win.max_size();
|
let max_size = win.max_size();
|
||||||
if min_size.w != 0 && min_size.w == max_size.w {
|
size.w = ensure_min_max_size_maybe_zero(size.w, min_size.w, max_size.w);
|
||||||
size.w = min_size.w;
|
size.h = ensure_min_max_size_maybe_zero(size.h, min_size.h, max_size.h);
|
||||||
}
|
|
||||||
if min_size.h != 0 && min_size.h == max_size.h {
|
|
||||||
size.h = min_size.h;
|
|
||||||
}
|
|
||||||
win.request_size_once(size, true);
|
win.request_size_once(size, true);
|
||||||
|
|
||||||
if activate || self.tiles.is_empty() {
|
if activate || self.tiles.is_empty() {
|
||||||
|
|||||||
+16
-15
@@ -62,7 +62,10 @@ use crate::render_helpers::texture::TextureBuffer;
|
|||||||
use crate::render_helpers::{BakedBuffer, RenderTarget, SplitElements};
|
use crate::render_helpers::{BakedBuffer, RenderTarget, SplitElements};
|
||||||
use crate::rubber_band::RubberBand;
|
use crate::rubber_band::RubberBand;
|
||||||
use crate::utils::transaction::{Transaction, TransactionBlocker};
|
use crate::utils::transaction::{Transaction, TransactionBlocker};
|
||||||
use crate::utils::{output_matches_name, output_size, round_logical_in_physical_max1, ResizeEdge};
|
use crate::utils::{
|
||||||
|
ensure_min_max_size_maybe_zero, output_matches_name, output_size,
|
||||||
|
round_logical_in_physical_max1, ResizeEdge,
|
||||||
|
};
|
||||||
use crate::window::ResolvedWindowRules;
|
use crate::window::ResolvedWindowRules;
|
||||||
|
|
||||||
pub mod closing_window;
|
pub mod closing_window;
|
||||||
@@ -2698,15 +2701,15 @@ impl<W: LayoutElement> Layout<W> {
|
|||||||
let win = move_.tile.window_mut();
|
let win = move_.tile.window_mut();
|
||||||
let mut size =
|
let mut size =
|
||||||
floating_size.unwrap_or_else(|| win.expected_size().unwrap_or_default());
|
floating_size.unwrap_or_else(|| win.expected_size().unwrap_or_default());
|
||||||
// Make sure fixed-size through window rules keeps working.
|
|
||||||
|
// Apply min/max size window rules. If requesting a concrete size, apply
|
||||||
|
// completely; if requesting (0, 0), apply only when min/max results in a fixed
|
||||||
|
// size.
|
||||||
let min_size = win.min_size();
|
let min_size = win.min_size();
|
||||||
let max_size = win.max_size();
|
let max_size = win.max_size();
|
||||||
if min_size.w != 0 && min_size.w == max_size.w {
|
size.w = ensure_min_max_size_maybe_zero(size.w, min_size.w, max_size.w);
|
||||||
size.w = min_size.w;
|
size.h = ensure_min_max_size_maybe_zero(size.h, min_size.h, max_size.h);
|
||||||
}
|
|
||||||
if min_size.h != 0 && min_size.h == max_size.h {
|
|
||||||
size.h = min_size.h;
|
|
||||||
}
|
|
||||||
win.request_size_once(size, true);
|
win.request_size_once(size, true);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -3277,15 +3280,13 @@ impl<W: LayoutElement> Layout<W> {
|
|||||||
Size::from((0, 0))
|
Size::from((0, 0))
|
||||||
};
|
};
|
||||||
|
|
||||||
// Make sure fixed-size through window rules keeps working.
|
// Apply min/max size window rules. If requesting a concrete size, apply
|
||||||
|
// completely; if requesting (0, 0), apply only when min/max results in a fixed
|
||||||
|
// size.
|
||||||
let min_size = win.min_size();
|
let min_size = win.min_size();
|
||||||
let max_size = win.max_size();
|
let max_size = win.max_size();
|
||||||
if min_size.w != 0 && min_size.w == max_size.w {
|
size.w = ensure_min_max_size_maybe_zero(size.w, min_size.w, max_size.w);
|
||||||
size.w = min_size.w;
|
size.h = ensure_min_max_size_maybe_zero(size.h, min_size.h, max_size.h);
|
||||||
}
|
|
||||||
if min_size.h != 0 && min_size.h == max_size.h {
|
|
||||||
size.h = min_size.h;
|
|
||||||
}
|
|
||||||
|
|
||||||
win.request_size_once(size, true);
|
win.request_size_once(size, true);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use client::ClientId;
|
use client::ClientId;
|
||||||
use insta::assert_snapshot;
|
use insta::assert_snapshot;
|
||||||
|
use niri_config::Config;
|
||||||
use niri_ipc::SizeChange;
|
use niri_ipc::SizeChange;
|
||||||
use smithay::utils::Point;
|
use smithay::utils::Point;
|
||||||
use wayland_client::protocol::wl_surface::WlSurface;
|
use wayland_client::protocol::wl_surface::WlSurface;
|
||||||
@@ -785,3 +786,71 @@ fn floating_doesnt_store_fullscreen_size() {
|
|||||||
@"size: 100 × 100, bounds: 1920 × 1080, states: [Activated]"
|
@"size: 100 × 100, bounds: 1920 × 1080, states: [Activated]"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn floating_respects_non_fixed_min_max_rule() {
|
||||||
|
let config = r##"
|
||||||
|
window-rule {
|
||||||
|
min-width 200
|
||||||
|
max-width 300
|
||||||
|
}
|
||||||
|
"##;
|
||||||
|
let config = Config::parse("test.kdl", config).unwrap();
|
||||||
|
let mut f = Fixture::with_config(config);
|
||||||
|
f.add_output(1, (1920, 1080));
|
||||||
|
f.add_output(2, (1280, 720));
|
||||||
|
|
||||||
|
let id = f.add_client();
|
||||||
|
let window = f.client(id).create_window();
|
||||||
|
let surface = window.surface.clone();
|
||||||
|
window.commit();
|
||||||
|
f.roundtrip(id);
|
||||||
|
|
||||||
|
// Open with smaller width than min.
|
||||||
|
let window = f.client(id).window(&surface);
|
||||||
|
window.attach_new_buffer();
|
||||||
|
window.set_size(100, 100);
|
||||||
|
window.ack_last_and_commit();
|
||||||
|
f.double_roundtrip(id);
|
||||||
|
|
||||||
|
// Commit to the Activated state configure.
|
||||||
|
f.client(id).window(&surface).ack_last_and_commit();
|
||||||
|
f.double_roundtrip(id);
|
||||||
|
|
||||||
|
let _ = f.client(id).window(&surface).recent_configures();
|
||||||
|
|
||||||
|
// Make it floating.
|
||||||
|
f.niri().layout.toggle_window_floating(None);
|
||||||
|
f.double_roundtrip(id);
|
||||||
|
|
||||||
|
// This should clamp to min-width and request 200 × 100.
|
||||||
|
assert_snapshot!(
|
||||||
|
f.client(id).window(&surface).format_recent_configures(),
|
||||||
|
@"size: 200 × 100, bounds: 1920 × 1080, states: [Activated]"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Commit with a bigger width than max.
|
||||||
|
let window = f.client(id).window(&surface);
|
||||||
|
window.set_size(400, 100);
|
||||||
|
window.ack_last_and_commit();
|
||||||
|
f.roundtrip(id);
|
||||||
|
|
||||||
|
// Make it tiling.
|
||||||
|
f.niri().layout.toggle_window_floating(None);
|
||||||
|
f.double_roundtrip(id);
|
||||||
|
|
||||||
|
let _ = f.client(id).window(&surface).recent_configures();
|
||||||
|
|
||||||
|
f.client(id).window(&surface).ack_last_and_commit();
|
||||||
|
f.roundtrip(id);
|
||||||
|
|
||||||
|
// Make it floating.
|
||||||
|
f.niri().layout.toggle_window_floating(None);
|
||||||
|
f.double_roundtrip(id);
|
||||||
|
|
||||||
|
// This should clamp to max-width and request 300 × 100.
|
||||||
|
assert_snapshot!(
|
||||||
|
f.client(id).window(&surface).format_recent_configures(),
|
||||||
|
@"size: 300 × 100, bounds: 1920 × 1080, states: [Activated]"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -272,6 +272,16 @@ pub fn ensure_min_max_size(mut x: i32, min_size: i32, max_size: i32) -> i32 {
|
|||||||
x
|
x
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn ensure_min_max_size_maybe_zero(x: i32, min_size: i32, max_size: i32) -> i32 {
|
||||||
|
if x != 0 {
|
||||||
|
ensure_min_max_size(x, min_size, max_size)
|
||||||
|
} else if min_size > 0 && min_size == max_size {
|
||||||
|
min_size
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn clamp_preferring_top_left_in_area(
|
pub fn clamp_preferring_top_left_in_area(
|
||||||
area: Rectangle<f64, Logical>,
|
area: Rectangle<f64, Logical>,
|
||||||
rect: &mut Rectangle<f64, Logical>,
|
rect: &mut Rectangle<f64, Logical>,
|
||||||
|
|||||||
Reference in New Issue
Block a user