diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/layout/scrolling.rs | 34 | ||||
| -rw-r--r-- | src/layout/tests.rs | 63 |
2 files changed, 84 insertions, 13 deletions
diff --git a/src/layout/scrolling.rs b/src/layout/scrolling.rs index 0c70fc7a..37feb227 100644 --- a/src/layout/scrolling.rs +++ b/src/layout/scrolling.rs @@ -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. diff --git a/src/layout/tests.rs b/src/layout/tests.rs index acfced00..524ade8b 100644 --- a/src/layout/tests.rs +++ b/src/layout/tests.rs @@ -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; |
