aboutsummaryrefslogtreecommitdiff
path: root/src/layout
diff options
context:
space:
mode:
Diffstat (limited to 'src/layout')
-rw-r--r--src/layout/floating.rs37
-rw-r--r--src/layout/mod.rs34
-rw-r--r--src/layout/tile.rs15
3 files changed, 56 insertions, 30 deletions
diff --git a/src/layout/floating.rs b/src/layout/floating.rs
index 4565e2f2..f870b2f2 100644
--- a/src/layout/floating.rs
+++ b/src/layout/floating.rs
@@ -366,24 +366,27 @@ impl<W: LayoutElement> FloatingSpace<W> {
) {
tile.update_config(self.scale, self.options.clone());
+ // Restore the previous floating window size, and in case the tile is fullscreen,
+ // unfullscreen it.
+ let floating_size = tile.floating_window_size();
let win = tile.window_mut();
- let size = if win.is_pending_fullscreen() {
- let mut size = Size::from((0, 0));
-
- // 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 == max_size.w {
- size.w = min_size.w;
- }
- if min_size.h == max_size.h {
- size.h = min_size.h;
- }
-
- size
+ let mut size = if win.is_pending_fullscreen() {
+ // If the window was fullscreen without a floating size, ask for (0, 0).
+ floating_size.unwrap_or_default()
} else {
- win.size()
+ // If the window wasn't fullscreen without a floating size (e.g. it was tiled before),
+ // ask for the current size.
+ floating_size.unwrap_or_else(|| win.size_to_request())
};
+ // 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);
if activate || self.tiles.is_empty() {
@@ -761,6 +764,10 @@ impl<W: LayoutElement> FloatingSpace<W> {
tile.update_window();
data.update(tile);
+ // Update the stored floating window size.
+ let floating_size = tile.window().size_to_request();
+ tile.set_floating_window_size(floating_size);
+
// When resizing by top/left edge, update the position accordingly.
if let Some(resize) = resize {
let mut offset = Point::from((0., 0.));
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index acc5257f..8e86c0ca 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -1152,6 +1152,12 @@ impl<W: LayoutElement> Layout<W> {
if let Some(InteractiveMoveState::Moving(move_)) = &mut self.interactive_move {
if move_.tile.window().id() == window {
move_.tile.update_window();
+
+ // Update the floating size in case the window resizes itself during an interactive
+ // move.
+ let floating_size = move_.tile.window().size_to_request();
+ move_.tile.set_floating_window_size(floating_size);
+
return;
}
}
@@ -3254,35 +3260,33 @@ impl<W: LayoutElement> Layout<W> {
Rc::new(Options::clone(&self.options).adjusted_for_scale(scale)),
);
- // Unfullscreen and let the window pick a natural size.
- //
- // TODO
- // When we have floating, we will want to always send a (0, 0) size here, not just
- // to unfullscreen. However, when implementing that, remember to check how GTK
- // tiled window size restoration works. It seems to remember *some* last size with
- // prefer-no-csd, and occasionally that last size can become the full-width size
- // rather than a smaller size, which is annoying. Need to see if niri can use some
- // heuristics to make this case behave better.
+ // Unfullscreen.
+ let floating_size = tile.floating_window_size();
+ let unfullscreen_to_floating = tile.unfullscreen_to_floating();
let win = tile.window_mut();
if win.is_pending_fullscreen() {
- let mut size = Size::from((0, 0));
+ // If we're unfullscreening to floating, use the stored floating size,
+ // otherwise use (0, 0).
+ let mut size = if unfullscreen_to_floating {
+ floating_size.unwrap_or_default()
+ } else {
+ Size::from((0, 0))
+ };
// 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 == max_size.w {
+ if min_size.w != 0 && min_size.w == max_size.w {
size.w = min_size.w;
}
- if min_size.h == max_size.h {
+ if min_size.h != 0 && min_size.h == max_size.h {
size.h = min_size.h;
}
win.request_size_once(size, true);
// If we're unfullscreening to floating, default to the floating layout.
- is_floating = tile.unfullscreen_to_floating();
- } else {
- win.request_size_once(win.size(), true);
+ is_floating = unfullscreen_to_floating;
}
let mut data = InteractiveMoveData {
diff --git a/src/layout/tile.rs b/src/layout/tile.rs
index 1b9aac2d..13adbd50 100644
--- a/src/layout/tile.rs
+++ b/src/layout/tile.rs
@@ -54,6 +54,12 @@ pub struct Tile<W: LayoutElement> {
/// Whether the tile should float upon unfullscreening.
unfullscreen_to_floating: bool,
+ /// The size that the window should assume when going floating.
+ ///
+ /// This is generally the last size the window had when it was floating. It can be unknown if
+ /// the window starts out in the tiling layout or fullscreen.
+ floating_window_size: Option<Size<i32, Logical>>,
+
/// The animation upon opening a window.
open_animation: Option<OpenAnimation>,
@@ -128,6 +134,7 @@ impl<W: LayoutElement> Tile<W> {
fullscreen_backdrop: SolidColorBuffer::new((0., 0.), [0., 0., 0., 1.]),
fullscreen_size: Default::default(),
unfullscreen_to_floating: false,
+ floating_window_size: None,
open_animation: None,
resize_animation: None,
move_x_animation: None,
@@ -935,6 +942,14 @@ impl<W: LayoutElement> Tile<W> {
self.unfullscreen_to_floating = value;
}
+ pub fn floating_window_size(&self) -> Option<Size<i32, Logical>> {
+ self.floating_window_size
+ }
+
+ pub fn set_floating_window_size(&mut self, floating_window_size: Size<i32, Logical>) {
+ self.floating_window_size = Some(floating_window_size);
+ }
+
#[cfg(test)]
pub fn verify_invariants(&self) {
use approx::assert_abs_diff_eq;