aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2024-12-16 09:03:50 +0300
committerIvan Molodetskikh <yalterz@gmail.com>2024-12-30 20:12:37 +0300
commitf38acfe98848746598233a275ac3ee226f3df658 (patch)
treecffe239a9cb01cae9ddabbe1a01288904783d842 /src
parent965619d0964973966bbd1d9d8087d1e8e8ff4867 (diff)
downloadniri-f38acfe98848746598233a275ac3ee226f3df658.tar.gz
niri-f38acfe98848746598233a275ac3ee226f3df658.tar.bz2
niri-f38acfe98848746598233a275ac3ee226f3df658.zip
layout: Remember whether to unfullscreen back into floating
Diffstat (limited to 'src')
-rw-r--r--src/layout/mod.rs5
-rw-r--r--src/layout/scrolling.rs6
-rw-r--r--src/layout/tile.rs12
-rw-r--r--src/layout/workspace.rs37
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) {