Skip to content

Commit 7a52eff

Browse files
committed
workspace: Animation and geometry fixes around maximized windows
1 parent a7b369f commit 7a52eff

File tree

1 file changed

+56
-40
lines changed

1 file changed

+56
-40
lines changed

src/shell/workspace.rs

Lines changed: 56 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -948,21 +948,24 @@ impl Workspace {
948948
match state.original_layer {
949949
ManagedLayer::Tiling if self.tiling_enabled => {
950950
// should still be mapped in tiling
951-
self.floating_layer.unmap(&elem, None);
951+
let geo = self.tiling_layer.element_geometry(&elem);
952+
self.floating_layer.unmap(&elem, geo);
952953
elem.output_enter(&self.output, elem.bbox());
953954
elem.set_maximized(false);
954955
elem.set_geometry(state.original_geometry.to_global(&self.output));
955956
elem.configure();
956957
self.tiling_layer.recalculate();
957-
self.tiling_layer.element_geometry(&elem)
958+
geo
958959
}
959960
ManagedLayer::Sticky => unreachable!(),
960-
_ => {
961+
962+
x => {
963+
let use_geometry = !matches!(x, ManagedLayer::Tiling);
961964
elem.set_maximized(false);
962965
self.floating_layer.map_internal(
963966
elem.clone(),
964-
Some(state.original_geometry.loc),
965-
Some(state.original_geometry.size.as_logical()),
967+
use_geometry.then_some(state.original_geometry.loc),
968+
use_geometry.then_some(state.original_geometry.size.as_logical()),
966969
None,
967970
);
968971
Some(state.original_geometry)
@@ -1016,38 +1019,54 @@ impl Workspace {
10161019
.mapped()
10171020
.find(|m| m.windows().any(|(ref s, _)| s == surface))
10181021
.cloned()?;
1019-
let was_maximized = if mapped.maximized_state.lock().unwrap().is_some() {
1020-
// If surface is maximized then unmaximize it, so it is assigned to only one layer
1021-
let _ = self.unmaximize_request(&mapped);
1022-
true
1022+
let was_maximized = if let Some(MaximizedState {
1023+
original_geometry,
1024+
original_layer,
1025+
}) = mapped.maximized_state.lock().unwrap().take()
1026+
{
1027+
// we need to do this manually instead of calling `self.unmaximize_request`
1028+
// to get the correct animation in the tiling case.
1029+
match original_layer {
1030+
ManagedLayer::Tiling if self.tiling_enabled => {
1031+
self.floating_layer.unmap(&mapped, Some(to));
1032+
}
1033+
_ => {}
1034+
}
1035+
mapped.set_geometry(original_geometry.to_global(&self.output));
1036+
mapped.set_maximized(false);
1037+
Some(original_geometry)
10231038
} else {
1024-
false
1039+
None
10251040
};
10261041

1042+
mapped.set_minimized(true);
1043+
mapped.configure();
1044+
10271045
if let Some(geometry) = self.floating_layer.unmap(&mapped, Some(to)) {
1028-
mapped.set_minimized(true);
10291046
return Some(MinimizedWindow::Floating {
10301047
window: mapped,
10311048
previous: FloatingRestoreData {
1032-
geometry,
1049+
geometry: was_maximized.unwrap_or(geometry),
10331050
output_size: self.output.geometry().size.as_logical(),
1034-
was_maximized,
1051+
was_maximized: was_maximized.is_some(),
10351052
},
10361053
});
10371054
}
10381055

1039-
if let Ok(state) = self.tiling_layer.unmap(&mapped, Some(to)) {
1040-
mapped.set_minimized(true);
1056+
if let Ok(state) = self
1057+
.tiling_layer
1058+
.unmap(&mapped, was_maximized.is_none().then_some(to))
1059+
{
10411060
return Some(MinimizedWindow::Tiling {
10421061
window: mapped,
10431062
previous: TilingRestoreData {
10441063
state,
1045-
was_maximized,
1064+
was_maximized: was_maximized.is_some(),
10461065
},
10471066
});
10481067
}
10491068

1050-
None
1069+
unreachable!()
10511070
}
10521071

10531072
pub fn unminimize(
@@ -1089,7 +1108,7 @@ impl Workspace {
10891108
original_layer: ManagedLayer::Floating,
10901109
});
10911110
std::mem::drop(state);
1092-
self.floating_layer.map_maximized(window, geometry, false);
1111+
self.floating_layer.map_maximized(window, geometry, true);
10931112
}
10941113

10951114
None
@@ -1105,8 +1124,12 @@ impl Workspace {
11051124
window.set_minimized(false);
11061125
if self.tiling_enabled {
11071126
let focus_stack = self.focus_stack.get(seat);
1108-
self.tiling_layer
1109-
.remap(window.clone(), None, state, Some(focus_stack.iter()));
1127+
self.tiling_layer.remap(
1128+
window.clone(),
1129+
(!was_maximized).then_some(from),
1130+
state,
1131+
Some(focus_stack.iter()),
1132+
);
11101133
if was_maximized {
11111134
let previous_geometry =
11121135
self.tiling_layer.element_geometry(&window).unwrap();
@@ -1116,18 +1139,20 @@ impl Workspace {
11161139
original_layer: ManagedLayer::Tiling,
11171140
});
11181141
std::mem::drop(state);
1119-
self.floating_layer
1120-
.map_maximized(window, previous_geometry, true);
1142+
self.floating_layer.map_maximized(window, from, true);
11211143
}
11221144
} else {
11231145
self.floating_layer.map(window.clone(), None);
1124-
let geometry = self.floating_layer.element_geometry(&window).unwrap();
1146+
let mut geometry = self.floating_layer.element_geometry(&window).unwrap();
1147+
if let Some(pending_size) = window.pending_size() {
1148+
geometry.size = pending_size.as_local();
1149+
}
11251150

11261151
if was_maximized {
11271152
let mut state = window.maximized_state.lock().unwrap();
11281153
*state = Some(MaximizedState {
11291154
original_geometry: geometry,
1130-
original_layer: ManagedLayer::Floating,
1155+
original_layer: ManagedLayer::Tiling,
11311156
});
11321157
std::mem::drop(state);
11331158
self.floating_layer.map_maximized(window, from, true);
@@ -1275,12 +1300,7 @@ impl Workspace {
12751300
let floating_windows = self.floating_layer.mapped().cloned().collect::<Vec<_>>();
12761301

12771302
for window in floating_windows.iter().filter(|w| w.is_maximized(false)) {
1278-
let original_geometry = {
1279-
let state = window.maximized_state.lock().unwrap();
1280-
state.as_ref().unwrap().original_geometry.clone()
1281-
};
1282-
self.unmaximize_request(&window);
1283-
maximized_windows.push((window.clone(), ManagedLayer::Tiling, original_geometry));
1303+
maximized_windows.push((window.clone(), ManagedLayer::Tiling));
12841304
}
12851305

12861306
let focus_stack = self.focus_stack.get(seat);
@@ -1300,24 +1320,20 @@ impl Workspace {
13001320
.into_iter()
13011321
{
13021322
if window.is_maximized(false) {
1303-
let original_geometry = {
1304-
let state = window.maximized_state.lock().unwrap();
1305-
state.as_ref().unwrap().original_geometry.clone()
1306-
};
13071323
self.unmaximize_request(&window);
1308-
maximized_windows.push((
1309-
window.clone(),
1310-
ManagedLayer::Floating,
1311-
original_geometry,
1312-
));
1324+
maximized_windows.push((window.clone(), ManagedLayer::Floating));
13131325
}
13141326
let _ = self.tiling_layer.unmap(&window, None);
13151327
self.floating_layer.map(window, None);
13161328
}
13171329
workspace_state.set_workspace_tiling_state(&self.handle, TilingState::FloatingOnly);
13181330
self.tiling_enabled = false;
13191331
}
1320-
for (window, original_layer, original_geometry) in maximized_windows {
1332+
for (window, original_layer) in maximized_windows {
1333+
let mut original_geometry = self.element_geometry(&window).unwrap();
1334+
if let Some(pending_size) = window.pending_size() {
1335+
original_geometry.size = pending_size.as_local();
1336+
}
13211337
let mut state = window.maximized_state.lock().unwrap();
13221338
*state = Some(MaximizedState {
13231339
original_geometry,

0 commit comments

Comments
 (0)