mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-21 02:01:55 +07:00
layout/scrolling: Take unfullscreen view offset unconditionally
It might get set and unset all while the view is frozen with a gesture.
This commit is contained in:
+21
-13
@@ -1291,20 +1291,28 @@ impl<W: LayoutElement> ScrollingSpace<W> {
|
||||
self.view_offset.offset(offset);
|
||||
}
|
||||
|
||||
if self.interactive_resize.is_none() && !self.view_offset.is_gesture() {
|
||||
// We might need to move the view to ensure the resized window is still visible.
|
||||
// Upon unfullscreening, restore the view offset.
|
||||
//
|
||||
// In tabbed display mode, there can be multiple tiles in a fullscreen column. They
|
||||
// will unfullscreen one by one, and the column width will shrink only when the
|
||||
// last tile unfullscreens. This is when we want to restore the view offset,
|
||||
// otherwise it will immediately reset back by the animate_view_offset below.
|
||||
let is_fullscreen = self.columns[col_idx].tiles.iter().any(Tile::is_fullscreen);
|
||||
let unfullscreen_offset = if was_fullscreen && !is_fullscreen {
|
||||
// Take the value unconditionally, even if the view is currently frozen by
|
||||
// a view gesture. It shouldn't linger around because it's only valid for this
|
||||
// particular unfullscreen.
|
||||
self.view_offset_before_fullscreen.take()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Upon unfullscreening, restore the view offset.
|
||||
//
|
||||
// In tabbed display mode, there can be multiple tiles in a fullscreen column. They
|
||||
// will unfullscreen one by one, and the column width will shrink only when the
|
||||
// last tile unfullscreens. This is when we want to restore the view offset,
|
||||
// otherwise it will immediately reset back by the animate_view_offset below.
|
||||
let is_fullscreen = self.columns[col_idx].tiles.iter().any(Tile::is_fullscreen);
|
||||
if was_fullscreen && !is_fullscreen {
|
||||
if let Some(prev_offset) = self.view_offset_before_fullscreen.take() {
|
||||
self.animate_view_offset(col_idx, prev_offset);
|
||||
}
|
||||
// We might need to move the view to ensure the resized window is still visible. But
|
||||
// only do it when the view isn't frozen by an interactive resize or a view gesture.
|
||||
if self.interactive_resize.is_none() && !self.view_offset.is_gesture() {
|
||||
// Restore the view offset upon unfullscreening if needed.
|
||||
if let Some(prev_offset) = unfullscreen_offset {
|
||||
self.animate_view_offset(col_idx, prev_offset);
|
||||
}
|
||||
|
||||
// Synchronize the horizontal view movement with the resize so that it looks nice.
|
||||
|
||||
@@ -3471,6 +3471,69 @@ fn interactive_move_unfullscreen_to_floating_stops_dnd_scroll() {
|
||||
check_ops(&ops);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unfullscreen_view_offset_not_reset_during_dnd_gesture() {
|
||||
let ops = [
|
||||
Op::AddOutput(1),
|
||||
Op::AddWindow {
|
||||
params: TestWindowParams::new(3),
|
||||
},
|
||||
Op::FullscreenWindow(3),
|
||||
Op::Communicate(3),
|
||||
Op::DndUpdate {
|
||||
output_idx: 1,
|
||||
px: 0.0,
|
||||
py: 0.0,
|
||||
},
|
||||
Op::FullscreenWindow(3),
|
||||
Op::Communicate(3),
|
||||
];
|
||||
|
||||
check_ops(&ops);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unfullscreen_view_offset_not_reset_during_gesture() {
|
||||
let ops = [
|
||||
Op::AddOutput(1),
|
||||
Op::AddWindow {
|
||||
params: TestWindowParams::new(3),
|
||||
},
|
||||
Op::FullscreenWindow(3),
|
||||
Op::Communicate(3),
|
||||
Op::ViewOffsetGestureBegin {
|
||||
output_idx: 1,
|
||||
workspace_idx: None,
|
||||
is_touchpad: false,
|
||||
},
|
||||
Op::FullscreenWindow(3),
|
||||
Op::Communicate(3),
|
||||
];
|
||||
|
||||
check_ops(&ops);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unfullscreen_view_offset_not_reset_during_ongoing_gesture() {
|
||||
let ops = [
|
||||
Op::AddOutput(1),
|
||||
Op::AddWindow {
|
||||
params: TestWindowParams::new(3),
|
||||
},
|
||||
Op::ViewOffsetGestureBegin {
|
||||
output_idx: 1,
|
||||
workspace_idx: None,
|
||||
is_touchpad: false,
|
||||
},
|
||||
Op::FullscreenWindow(3),
|
||||
Op::Communicate(3),
|
||||
Op::FullscreenWindow(3),
|
||||
Op::Communicate(3),
|
||||
];
|
||||
|
||||
check_ops(&ops);
|
||||
}
|
||||
|
||||
fn parent_id_causes_loop(layout: &Layout<TestWindow>, id: usize, mut parent_id: usize) -> bool {
|
||||
if parent_id == id {
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user