mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-21 02:01:55 +07:00
Restore floating size during interactive move
This commit is contained in:
@@ -2717,6 +2717,23 @@ impl<W: LayoutElement> Layout<W> {
|
||||
if let Some(InteractiveMoveState::Moving(move_)) = &mut self.interactive_move {
|
||||
if window.is_none() || window == Some(move_.tile.window().id()) {
|
||||
move_.is_floating = !move_.is_floating;
|
||||
|
||||
// When going to floating, restore the floating window size.
|
||||
if move_.is_floating {
|
||||
let floating_size = move_.tile.floating_window_size();
|
||||
let win = move_.tile.window_mut();
|
||||
let mut size = floating_size.unwrap_or_else(|| win.expected_size());
|
||||
// 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 != 0 && min_size.w == max_size.w {
|
||||
size.w = min_size.w;
|
||||
}
|
||||
if min_size.h != 0 && min_size.h == max_size.h {
|
||||
size.h = min_size.h;
|
||||
}
|
||||
win.request_size_once(size, true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -651,3 +651,77 @@ fn state_change_doesnt_break_use_window_size() {
|
||||
@"size: 300 × 600, bounds: 1920 × 1080, states: [Activated]"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interactive_move_restores_floating_size_when_set_to_floating() {
|
||||
let (mut f, id, surface) = set_up();
|
||||
|
||||
f.niri().layout.toggle_window_floating(None);
|
||||
f.double_roundtrip(id);
|
||||
|
||||
// Change size while we're floating and commit to make niri remember it.
|
||||
let window = f.client(id).window(&surface);
|
||||
window.set_size(200, 200);
|
||||
window.ack_last_and_commit();
|
||||
f.double_roundtrip(id);
|
||||
|
||||
let _ = f.client(id).window(&surface).recent_configures();
|
||||
|
||||
// Change back to tiling.
|
||||
f.niri().layout.toggle_window_floating(None);
|
||||
f.double_roundtrip(id);
|
||||
|
||||
// We should get a tiled size configure.
|
||||
assert_snapshot!(
|
||||
f.client(id).window(&surface).format_recent_configures(),
|
||||
@"size: 200 × 1048, bounds: 1888 × 1048, states: [Activated]"
|
||||
);
|
||||
|
||||
// Resize as requested.
|
||||
let window = f.client(id).window(&surface);
|
||||
let (_, configure) = window.configures_received.last().unwrap();
|
||||
window.set_size(configure.size.0 as u16, configure.size.1 as u16);
|
||||
window.ack_last_and_commit();
|
||||
f.roundtrip(id);
|
||||
|
||||
// Start an interactive move.
|
||||
let output = f.niri_output(1);
|
||||
let niri = f.niri();
|
||||
let mapped = niri.layout.windows().next().unwrap().1;
|
||||
let window_id = mapped.window.clone();
|
||||
niri.layout
|
||||
.interactive_move_begin(window_id.clone(), &output, Point::default());
|
||||
niri.layout.interactive_move_update(
|
||||
&window_id,
|
||||
Point::from((1000., 0.)),
|
||||
output,
|
||||
Point::default(),
|
||||
);
|
||||
f.double_roundtrip(id);
|
||||
|
||||
// This shouldn't request any new size because interactive move targets tiling.
|
||||
assert_snapshot!(
|
||||
f.client(id).window(&surface).format_recent_configures(),
|
||||
@"size: 200 × 1048, bounds: 1920 × 1080, states: [Activated]"
|
||||
);
|
||||
|
||||
// Change interactive move to target floating.
|
||||
f.niri().layout.toggle_window_floating(None);
|
||||
f.double_roundtrip(id);
|
||||
|
||||
// This should restore the floating window size (200 × 200).
|
||||
assert_snapshot!(
|
||||
f.client(id).window(&surface).format_recent_configures(),
|
||||
@"size: 200 × 200, bounds: 1920 × 1080, states: [Activated]"
|
||||
);
|
||||
|
||||
// End the interactive move, placing the window into floating.
|
||||
f.niri().layout.interactive_move_end(&window_id);
|
||||
f.double_roundtrip(id);
|
||||
|
||||
// This should keep the floating window size (200 × 200).
|
||||
assert_snapshot!(
|
||||
f.client(id).window(&surface).format_recent_configures(),
|
||||
@""
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user