diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-12-16 09:03:50 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-12-30 20:12:37 +0300 |
| commit | f38acfe98848746598233a275ac3ee226f3df658 (patch) | |
| tree | cffe239a9cb01cae9ddabbe1a01288904783d842 | |
| parent | 965619d0964973966bbd1d9d8087d1e8e8ff4867 (diff) | |
| download | niri-f38acfe98848746598233a275ac3ee226f3df658.tar.gz niri-f38acfe98848746598233a275ac3ee226f3df658.tar.bz2 niri-f38acfe98848746598233a275ac3ee226f3df658.zip | |
layout: Remember whether to unfullscreen back into floating
| -rw-r--r-- | src/layout/mod.rs | 5 | ||||
| -rw-r--r-- | src/layout/scrolling.rs | 6 | ||||
| -rw-r--r-- | src/layout/tile.rs | 12 | ||||
| -rw-r--r-- | src/layout/workspace.rs | 37 |
4 files changed, 54 insertions, 6 deletions
diff --git a/src/layout/mod.rs b/src/layout/mod.rs index 5068f43a..1a87b671 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -3214,7 +3214,7 @@ impl<W: LayoutElement> Layout<W> { mut tile, width, is_full_width, - is_floating, + mut is_floating, } = self.remove_window(window, Transaction::new()).unwrap(); tile.stop_move_animations(); @@ -3255,6 +3255,9 @@ impl<W: LayoutElement> Layout<W> { } win.request_size(size, true, None); + + // If we're unfullscreening to floating, default to the floating layout. + is_floating = tile.unfullscreen_to_floating(); } let mut data = InteractiveMoveData { diff --git a/src/layout/scrolling.rs b/src/layout/scrolling.rs index 27618217..ee4378a3 100644 --- a/src/layout/scrolling.rs +++ b/src/layout/scrolling.rs @@ -2081,7 +2081,7 @@ impl<W: LayoutElement> ScrollingSpace<W> { cancel_resize_for_column(&mut self.interactive_resize, col); } - pub fn set_fullscreen(&mut self, window: &W::Id, is_fullscreen: bool) { + pub fn set_fullscreen(&mut self, window: &W::Id, is_fullscreen: bool) -> bool { let (mut col_idx, tile_idx) = self .columns .iter() @@ -2090,7 +2090,7 @@ impl<W: LayoutElement> ScrollingSpace<W> { .unwrap(); if is_fullscreen == self.columns[col_idx].is_fullscreen { - return; + return false; } if is_fullscreen @@ -2138,6 +2138,8 @@ impl<W: LayoutElement> ScrollingSpace<W> { { self.view_offset_before_fullscreen = None; } + + true } pub fn render_above_top_layer(&self) -> bool { diff --git a/src/layout/tile.rs b/src/layout/tile.rs index 83080870..1b9aac2d 100644 --- a/src/layout/tile.rs +++ b/src/layout/tile.rs @@ -51,6 +51,9 @@ pub struct Tile<W: LayoutElement> { /// The size we were requested to fullscreen into. fullscreen_size: Size<f64, Logical>, + /// Whether the tile should float upon unfullscreening. + unfullscreen_to_floating: bool, + /// The animation upon opening a window. open_animation: Option<OpenAnimation>, @@ -124,6 +127,7 @@ impl<W: LayoutElement> Tile<W> { is_fullscreen: false, // FIXME: up-to-date fullscreen right away, but we need size. fullscreen_backdrop: SolidColorBuffer::new((0., 0.), [0., 0., 0., 1.]), fullscreen_size: Default::default(), + unfullscreen_to_floating: false, open_animation: None, resize_animation: None, move_x_animation: None, @@ -923,6 +927,14 @@ impl<W: LayoutElement> Tile<W> { self.unmap_snapshot.take() } + pub fn unfullscreen_to_floating(&self) -> bool { + self.unfullscreen_to_floating + } + + pub fn set_unfullscreen_to_floating(&mut self, value: bool) { + self.unfullscreen_to_floating = value; + } + #[cfg(test)] pub fn verify_invariants(&self) { use approx::assert_abs_diff_eq; diff --git a/src/layout/workspace.rs b/src/layout/workspace.rs index d4463636..6220fd1e 100644 --- a/src/layout/workspace.rs +++ b/src/layout/workspace.rs @@ -471,12 +471,13 @@ impl<W: LayoutElement> Workspace<W> { is_full_width: bool, is_floating: bool, ) { - let tile = Tile::new( + let mut tile = Tile::new( window, self.scale.fractional_scale(), self.clock.clone(), self.options.clone(), ); + tile.set_unfullscreen_to_floating(is_floating); if is_floating { self.add_floating_tile(tile, None, activate); @@ -541,12 +542,13 @@ impl<W: LayoutElement> Workspace<W> { // TODO: smarter enum, so you can override is_floating = false for floating right_of. is_floating: bool, ) { - let tile = Tile::new( + let mut tile = Tile::new( window, self.scale.fractional_scale(), self.clock.clone(), self.options.clone(), ); + tile.set_unfullscreen_to_floating(is_floating); self.add_tile_right_of(right_of, tile, width, is_full_width, is_floating); } @@ -972,16 +974,45 @@ impl<W: LayoutElement> Workspace<W> { } pub fn set_fullscreen(&mut self, window: &W::Id, is_fullscreen: bool) { + let mut unfullscreen_to_floating = false; if self.floating.has_window(window) { if is_fullscreen { + unfullscreen_to_floating = true; self.toggle_window_floating(Some(window)); } else { // Floating windows are never fullscreen, so this is an unfullscreen request for an // already unfullscreen window. return; } + } else if !is_fullscreen { + // The window is in the scrolling layout and we're requesting an unfullscreen. If it is + // indeed fullscreen (i.e. this isn't a duplicate unfullscreen request), then we may + // need to unfullscreen into floating. + let tile = self + .scrolling + .tiles() + .find(|tile| tile.window().id() == window) + .unwrap(); + if tile.window().is_pending_fullscreen() && tile.unfullscreen_to_floating() { + // Unfullscreen and float in one call so it has a chance to notice and request a + // (0, 0) size, rather than the scrolling column size. + self.toggle_window_floating(Some(window)); + return; + } + } + + let changed = self.scrolling.set_fullscreen(window, is_fullscreen); + + // When going to fullscreen, remember if we should unfullscreen to floating. + if changed && is_fullscreen { + let tile = self + .scrolling + .tiles_mut() + .find(|tile| tile.window().id() == window) + .unwrap(); + + tile.set_unfullscreen_to_floating(unfullscreen_to_floating); } - self.scrolling.set_fullscreen(window, is_fullscreen); } pub fn toggle_fullscreen(&mut self, window: &W::Id) { |
