Skip to content

Commit

Permalink
feat: restore to previous tiling size from minimized/fullscreen (#876)
Browse files Browse the repository at this point in the history
  • Loading branch information
lars-berger authored Dec 2, 2024
1 parent 47ef45c commit ee9f756
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 21 deletions.
57 changes: 43 additions & 14 deletions packages/wm/src/windows/commands/update_window_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ use tracing::info;

use crate::{
containers::{
commands::{move_container_within_tree, replace_container},
traits::CommonGetters,
commands::{
move_container_within_tree, replace_container,
resize_tiling_container,
},
traits::{CommonGetters, TilingSizeGetters},
WindowContainer,
},
user_config::UserConfig,
windows::{traits::WindowGetters, WindowState},
windows::{traits::WindowGetters, InsertionTarget, WindowState},
wm_state::WmState,
};

Expand Down Expand Up @@ -49,17 +52,26 @@ fn set_tiling(
let workspace =
window.workspace().context("Window has no workspace.")?;

// Get the position in the tree to insert the new tiling window. This
// will be the window's previous tiling position if it has one, or
// instead beside the last focused tiling window in the workspace.
let (target_parent, target_index) = window
.insertion_target()
// Check whether insertion target is still valid.
.filter(|(insertion_target, _)| {
// Check whether insertion target is still valid.
let insertion_target =
window.insertion_target().filter(|insertion_target| {
insertion_target
.target_parent
.workspace()
.map(|workspace| workspace.is_displayed())
.unwrap_or(false)
});

// Get the position in the tree to insert the new tiling window. This
// will be the window's previous tiling position if it has one, or
// instead beside the last focused tiling window in the workspace.
let (target_parent, target_index) = insertion_target
.as_ref()
.map(|insertion_target| {
(
insertion_target.target_parent.clone(),
insertion_target.target_index,
)
})
// Fallback to the last focused tiling window within the workspace.
.or_else(|| {
Expand All @@ -77,7 +89,7 @@ fn set_tiling(
// Replace the original window with the created tiling window.
replace_container(
tiling_window.clone().into(),
window.parent().context("No parent")?,
window.parent().context("No parent.")?,
window.index(),
)?;

Expand All @@ -88,6 +100,17 @@ fn set_tiling(
state,
)?;

if let Some(insertion_target) = &insertion_target {
let size_scale = (insertion_target.prev_sibling_count + 1) as f32
/ (tiling_window.tiling_siblings().count() + 1) as f32;

// Scale the window's previous size based on the current number of
// siblings. E.g. if the window was 0.5 with 1 sibling, and now has 2
// siblings, scale to 0.5 * (2/3) to maintain proportional sizing.
let target_size = insertion_target.prev_tiling_size * size_scale;
resize_tiling_container(&tiling_window.clone().into(), target_size);
}

state
.pending_sync
.containers_to_redraw
Expand Down Expand Up @@ -137,9 +160,15 @@ fn set_non_tiling(
let parent = window.parent().context("No parent")?;
let workspace = window.workspace().context("No workspace.")?;

let insertion_target = (parent.clone(), window.index());
let non_tiling_window =
window.to_non_tiling(target_state.clone(), Some(insertion_target));
let non_tiling_window = window.to_non_tiling(
target_state.clone(),
Some(InsertionTarget {
target_parent: parent.clone(),
target_index: window.index(),
prev_tiling_size: window.tiling_size(),
prev_sibling_count: window.tiling_siblings().count(),
}),
);

// Non-tiling windows should always be direct children of the
// workspace.
Expand Down
9 changes: 9 additions & 0 deletions packages/wm/src/windows/insertion_target.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use crate::containers::Container;

#[derive(Debug, Clone)]
pub struct InsertionTarget {
pub target_parent: Container,
pub target_index: usize,
pub prev_tiling_size: f32,
pub prev_sibling_count: usize,
}
2 changes: 2 additions & 0 deletions packages/wm/src/windows/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
mod active_drag;
pub mod commands;
mod insertion_target;
mod non_tiling_window;
mod tiling_window;
pub mod traits;
mod window_dto;
mod window_state;

pub use active_drag::*;
pub use insertion_target::*;
pub use non_tiling_window::*;
pub use tiling_window::*;
pub use window_dto::*;
Expand Down
11 changes: 6 additions & 5 deletions packages/wm/src/windows/non_tiling_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ use anyhow::Context;
use uuid::Uuid;

use super::{
traits::WindowGetters, ActiveDrag, TilingWindow, WindowDto, WindowState,
traits::WindowGetters, ActiveDrag, InsertionTarget, TilingWindow,
WindowDto, WindowState,
};
use crate::{
common::{platform::NativeWindow, DisplayState, Rect, RectDelta},
Expand All @@ -32,7 +33,7 @@ struct NonTilingWindowInner {
native: NativeWindow,
state: WindowState,
prev_state: Option<WindowState>,
insertion_target: Option<(Container, usize)>,
insertion_target: Option<InsertionTarget>,
display_state: DisplayState,
border_delta: RectDelta,
has_pending_dpi_adjustment: bool,
Expand All @@ -49,7 +50,7 @@ impl NonTilingWindow {
state: WindowState,
prev_state: Option<WindowState>,
border_delta: RectDelta,
insertion_target: Option<(Container, usize)>,
insertion_target: Option<InsertionTarget>,
floating_placement: Rect,
has_custom_floating_placement: bool,
done_window_rules: Vec<WindowRuleConfig>,
Expand All @@ -76,13 +77,13 @@ impl NonTilingWindow {
Self(Rc::new(RefCell::new(window)))
}

pub fn insertion_target(&self) -> Option<(Container, usize)> {
pub fn insertion_target(&self) -> Option<InsertionTarget> {
self.0.borrow().insertion_target.clone()
}

pub fn set_insertion_target(
&self,
insertion_target: Option<(Container, usize)>,
insertion_target: Option<InsertionTarget>,
) {
self.0.borrow_mut().insertion_target = insertion_target;
}
Expand Down
5 changes: 3 additions & 2 deletions packages/wm/src/windows/tiling_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ use anyhow::Context;
use uuid::Uuid;

use super::{
traits::WindowGetters, NonTilingWindow, WindowDto, WindowState,
traits::WindowGetters, InsertionTarget, NonTilingWindow, WindowDto,
WindowState,
};
use crate::{
common::{
Expand Down Expand Up @@ -88,7 +89,7 @@ impl TilingWindow {
pub fn to_non_tiling(
&self,
state: WindowState,
insertion_target: Option<(Container, usize)>,
insertion_target: Option<InsertionTarget>,
) -> NonTilingWindow {
NonTilingWindow::new(
Some(self.id()),
Expand Down

0 comments on commit ee9f756

Please sign in to comment.