mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-22 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 let Some(InteractiveMoveState::Moving(move_)) = &mut self.interactive_move {
|
||||||
if window.is_none() || window == Some(move_.tile.window().id()) {
|
if window.is_none() || window == Some(move_.tile.window().id()) {
|
||||||
move_.is_floating = !move_.is_floating;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -651,3 +651,77 @@ fn state_change_doesnt_break_use_window_size() {
|
|||||||
@"size: 300 × 600, bounds: 1920 × 1080, states: [Activated]"
|
@"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