shell: Properly restore maximized state from minimize/fullscreen
This commit is contained in:
parent
b11456614f
commit
165f83fa38
3 changed files with 142 additions and 60 deletions
|
|
@ -2443,7 +2443,7 @@ impl Shell {
|
||||||
window,
|
window,
|
||||||
original_geometry.map(|rect| rect.loc),
|
original_geometry.map(|rect| rect.loc),
|
||||||
original_geometry.map(|rect| rect.size.as_logical()),
|
original_geometry.map(|rect| rect.size.as_logical()),
|
||||||
None,
|
Some(set.output.geometry().to_local(&set.output)),
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -2465,6 +2465,7 @@ impl Shell {
|
||||||
None => self.workspaces.active_mut(&seat.active_output()).unwrap(),
|
None => self.workspaces.active_mut(&seat.active_output()).unwrap(),
|
||||||
Some(FullscreenRestoreState::Sticky { .. }) => unreachable!(),
|
Some(FullscreenRestoreState::Sticky { .. }) => unreachable!(),
|
||||||
};
|
};
|
||||||
|
let fullscreen_geometry = workspace.output.geometry().to_local(&workspace.output);
|
||||||
|
|
||||||
match state {
|
match state {
|
||||||
None => {
|
None => {
|
||||||
|
|
@ -2472,22 +2473,43 @@ impl Shell {
|
||||||
toplevel_enter_workspace(&window.active_window(), &workspace.handle);
|
toplevel_enter_workspace(&window.active_window(), &workspace.handle);
|
||||||
|
|
||||||
if workspace.tiling_enabled {
|
if workspace.tiling_enabled {
|
||||||
workspace.tiling_layer.map(
|
workspace.tiling_layer.remap(
|
||||||
window,
|
window,
|
||||||
Some(workspace.focus_stack.get(seat).iter()),
|
Some(fullscreen_geometry),
|
||||||
None,
|
None,
|
||||||
|
Some(workspace.focus_stack.get(seat).iter()),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
workspace.floating_layer.map(window, None);
|
workspace.floating_layer.map_internal(
|
||||||
|
window,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
Some(fullscreen_geometry),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(FullscreenRestoreState::Floating { .. }) => {
|
Some(FullscreenRestoreState::Floating {
|
||||||
|
state: FloatingRestoreData { was_maximized, .. },
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
workspace.floating_layer.map_internal(
|
workspace.floating_layer.map_internal(
|
||||||
window,
|
window.clone(),
|
||||||
original_geometry.map(|geo| geo.loc),
|
original_geometry.map(|geo| geo.loc),
|
||||||
original_geometry.map(|geo| geo.size.as_logical()),
|
original_geometry.map(|geo| geo.size.as_logical()),
|
||||||
None,
|
Some(fullscreen_geometry),
|
||||||
);
|
);
|
||||||
|
if was_maximized {
|
||||||
|
let geometry = workspace.floating_layer.element_geometry(&window).unwrap();
|
||||||
|
let mut state = window.maximized_state.lock().unwrap();
|
||||||
|
*state = Some(MaximizedState {
|
||||||
|
original_geometry: geometry,
|
||||||
|
original_layer: ManagedLayer::Floating,
|
||||||
|
});
|
||||||
|
std::mem::drop(state);
|
||||||
|
workspace
|
||||||
|
.floating_layer
|
||||||
|
.map_maximized(window, fullscreen_geometry, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Some(FullscreenRestoreState::Tiling {
|
Some(FullscreenRestoreState::Tiling {
|
||||||
state:
|
state:
|
||||||
|
|
@ -2497,16 +2519,47 @@ impl Shell {
|
||||||
},
|
},
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
let focus_stack = workspace.focus_stack.get(seat);
|
if workspace.tiling_enabled {
|
||||||
workspace
|
let focus_stack = workspace.focus_stack.get(seat);
|
||||||
.tiling_layer
|
workspace.tiling_layer.remap(
|
||||||
.remap(window.clone(), None, state, Some(focus_stack.iter()));
|
window.clone(),
|
||||||
if was_maximized {
|
Some(fullscreen_geometry),
|
||||||
let previous_geometry =
|
state,
|
||||||
workspace.tiling_layer.element_geometry(&window).unwrap();
|
Some(focus_stack.iter()),
|
||||||
workspace
|
);
|
||||||
.floating_layer
|
if was_maximized {
|
||||||
.map_maximized(window, previous_geometry, true);
|
let previous_geometry =
|
||||||
|
workspace.tiling_layer.element_geometry(&window).unwrap();
|
||||||
|
let mut state = window.maximized_state.lock().unwrap();
|
||||||
|
*state = Some(MaximizedState {
|
||||||
|
original_geometry: previous_geometry,
|
||||||
|
original_layer: ManagedLayer::Tiling,
|
||||||
|
});
|
||||||
|
std::mem::drop(state);
|
||||||
|
workspace
|
||||||
|
.floating_layer
|
||||||
|
.map_maximized(window, fullscreen_geometry, true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
workspace.floating_layer.map_internal(
|
||||||
|
window.clone(),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
Some(fullscreen_geometry),
|
||||||
|
);
|
||||||
|
|
||||||
|
if was_maximized {
|
||||||
|
let geometry = workspace.floating_layer.element_geometry(&window).unwrap();
|
||||||
|
let mut state = window.maximized_state.lock().unwrap();
|
||||||
|
*state = Some(MaximizedState {
|
||||||
|
original_geometry: geometry,
|
||||||
|
original_layer: ManagedLayer::Floating,
|
||||||
|
});
|
||||||
|
std::mem::drop(state);
|
||||||
|
workspace
|
||||||
|
.floating_layer
|
||||||
|
.map_maximized(window, fullscreen_geometry, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(FullscreenRestoreState::Sticky { .. }) => unreachable!(),
|
Some(FullscreenRestoreState::Sticky { .. }) => unreachable!(),
|
||||||
|
|
@ -3940,6 +3993,7 @@ impl Shell {
|
||||||
previous: FloatingRestoreData {
|
previous: FloatingRestoreData {
|
||||||
geometry: geo,
|
geometry: geo,
|
||||||
output_size: set.output.geometry().size.as_logical(),
|
output_size: set.output.geometry().size.as_logical(),
|
||||||
|
was_maximized: false,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -4474,6 +4528,7 @@ impl Shell {
|
||||||
state: FloatingRestoreData {
|
state: FloatingRestoreData {
|
||||||
geometry: from,
|
geometry: from,
|
||||||
output_size: workspace.output.geometry().size.as_logical(),
|
output_size: workspace.output.geometry().size.as_logical(),
|
||||||
|
was_maximized: false,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
Some(from),
|
Some(from),
|
||||||
|
|
|
||||||
|
|
@ -274,6 +274,7 @@ impl From<ManagedLayer> for WorkspaceRestoreData {
|
||||||
pub struct FloatingRestoreData {
|
pub struct FloatingRestoreData {
|
||||||
pub geometry: Rectangle<i32, Local>,
|
pub geometry: Rectangle<i32, Local>,
|
||||||
pub output_size: Size<i32, Logical>,
|
pub output_size: Size<i32, Logical>,
|
||||||
|
pub was_maximized: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FloatingRestoreData {
|
impl FloatingRestoreData {
|
||||||
|
|
@ -571,10 +572,13 @@ impl Workspace {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unmap_element(&mut self, mapped: &CosmicMapped) -> Option<WorkspaceRestoreData> {
|
pub fn unmap_element(&mut self, mapped: &CosmicMapped) -> Option<WorkspaceRestoreData> {
|
||||||
if mapped.maximized_state.lock().unwrap().is_some() {
|
let was_maximized = if mapped.maximized_state.lock().unwrap().is_some() {
|
||||||
// If surface is maximized then unmaximize it, so it is assigned to only one layer
|
// If surface is maximized then unmaximize it, so it is assigned to only one layer
|
||||||
let _ = self.unmaximize_request(&mapped);
|
let _ = self.unmaximize_request(&mapped);
|
||||||
}
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
self.focus_stack
|
self.focus_stack
|
||||||
.0
|
.0
|
||||||
|
|
@ -594,18 +598,13 @@ impl Workspace {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let was_maximized =
|
if let Some(floating_geometry) = self.floating_layer.unmap(&mapped, None) {
|
||||||
if let Some(floating_geometry) = self.floating_layer.unmap(&mapped, None) {
|
return Some(WorkspaceRestoreData::Floating(Some(FloatingRestoreData {
|
||||||
if mapped.maximized_state.lock().unwrap().is_none() {
|
geometry: floating_geometry,
|
||||||
return Some(WorkspaceRestoreData::Floating(Some(FloatingRestoreData {
|
output_size: self.output.geometry().size.as_logical(),
|
||||||
geometry: floating_geometry,
|
was_maximized,
|
||||||
output_size: self.output.geometry().size.as_logical(),
|
})));
|
||||||
})));
|
};
|
||||||
}
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
};
|
|
||||||
if let Ok(state) = self.tiling_layer.unmap(&mapped, None) {
|
if let Ok(state) = self.tiling_layer.unmap(&mapped, None) {
|
||||||
return Some(WorkspaceRestoreData::Tiling(Some(TilingRestoreData {
|
return Some(WorkspaceRestoreData::Tiling(Some(TilingRestoreData {
|
||||||
state,
|
state,
|
||||||
|
|
@ -1012,37 +1011,37 @@ impl Workspace {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let maybe_elem = self
|
let mapped = self
|
||||||
.tiling_layer
|
|
||||||
.mapped()
|
.mapped()
|
||||||
.find(|(m, _)| m.windows().any(|(ref s, _)| s == surface))
|
.find(|m| m.windows().any(|(ref s, _)| s == surface))
|
||||||
.map(|(s, _)| s.clone());
|
.cloned()?;
|
||||||
if let Some(elem) = maybe_elem {
|
let was_maximized = if mapped.maximized_state.lock().unwrap().is_some() {
|
||||||
let was_maximized = self.floating_layer.unmap(&elem, None).is_some();
|
// If surface is maximized then unmaximize it, so it is assigned to only one layer
|
||||||
let previous_state = self.tiling_layer.unmap(&elem, Some(to)).unwrap();
|
let _ = self.unmaximize_request(&mapped);
|
||||||
elem.set_minimized(true);
|
true
|
||||||
return Some(MinimizedWindow::Tiling {
|
} else {
|
||||||
window: elem,
|
false
|
||||||
previous: TilingRestoreData {
|
};
|
||||||
state: previous_state,
|
|
||||||
|
if let Some(geometry) = self.floating_layer.unmap(&mapped, Some(to)) {
|
||||||
|
mapped.set_minimized(true);
|
||||||
|
return Some(MinimizedWindow::Floating {
|
||||||
|
window: mapped,
|
||||||
|
previous: FloatingRestoreData {
|
||||||
|
geometry,
|
||||||
|
output_size: self.output.geometry().size.as_logical(),
|
||||||
was_maximized,
|
was_maximized,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let maybe_elem = self
|
if let Ok(state) = self.tiling_layer.unmap(&mapped, Some(to)) {
|
||||||
.floating_layer
|
mapped.set_minimized(true);
|
||||||
.mapped()
|
return Some(MinimizedWindow::Tiling {
|
||||||
.find(|m| m.windows().any(|(ref s, _)| s == surface))
|
window: mapped,
|
||||||
.cloned();
|
previous: TilingRestoreData {
|
||||||
if let Some(elem) = maybe_elem {
|
state,
|
||||||
let geometry = self.floating_layer.unmap(&elem, Some(to)).unwrap();
|
was_maximized,
|
||||||
elem.set_minimized(true);
|
|
||||||
return Some(MinimizedWindow::Floating {
|
|
||||||
window: elem,
|
|
||||||
previous: FloatingRestoreData {
|
|
||||||
geometry,
|
|
||||||
output_size: self.output.geometry().size.as_logical(),
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -1079,7 +1078,19 @@ impl Workspace {
|
||||||
|
|
||||||
window.set_minimized(false);
|
window.set_minimized(false);
|
||||||
self.floating_layer
|
self.floating_layer
|
||||||
.remap_minimized(window, from, previous_position);
|
.remap_minimized(window.clone(), from, previous_position);
|
||||||
|
|
||||||
|
if previous.was_maximized {
|
||||||
|
let geometry = self.floating_layer.element_geometry(&window).unwrap();
|
||||||
|
let mut state = window.maximized_state.lock().unwrap();
|
||||||
|
*state = Some(MaximizedState {
|
||||||
|
original_geometry: geometry,
|
||||||
|
original_layer: ManagedLayer::Floating,
|
||||||
|
});
|
||||||
|
std::mem::drop(state);
|
||||||
|
self.floating_layer.map_maximized(window, geometry, false);
|
||||||
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
MinimizedWindow::Tiling {
|
MinimizedWindow::Tiling {
|
||||||
|
|
@ -1098,16 +1109,29 @@ impl Workspace {
|
||||||
if was_maximized {
|
if was_maximized {
|
||||||
let previous_geometry =
|
let previous_geometry =
|
||||||
self.tiling_layer.element_geometry(&window).unwrap();
|
self.tiling_layer.element_geometry(&window).unwrap();
|
||||||
|
let mut state = window.maximized_state.lock().unwrap();
|
||||||
|
*state = Some(MaximizedState {
|
||||||
|
original_geometry: previous_geometry,
|
||||||
|
original_layer: ManagedLayer::Tiling,
|
||||||
|
});
|
||||||
|
std::mem::drop(state);
|
||||||
self.floating_layer
|
self.floating_layer
|
||||||
.map_maximized(window, previous_geometry, true);
|
.map_maximized(window, previous_geometry, true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
self.floating_layer.map(window.clone(), None);
|
||||||
|
let geometry = self.floating_layer.element_geometry(&window).unwrap();
|
||||||
|
|
||||||
if was_maximized {
|
if was_maximized {
|
||||||
|
let mut state = window.maximized_state.lock().unwrap();
|
||||||
|
*state = Some(MaximizedState {
|
||||||
|
original_geometry: geometry,
|
||||||
|
original_layer: ManagedLayer::Floating,
|
||||||
|
});
|
||||||
|
std::mem::drop(state);
|
||||||
self.floating_layer.map_maximized(window, from, true);
|
self.floating_layer.map_maximized(window, from, true);
|
||||||
} else {
|
} else {
|
||||||
self.floating_layer.map(window.clone(), None);
|
|
||||||
// get the right animation
|
// get the right animation
|
||||||
let geometry = self.floating_layer.element_geometry(&window).unwrap();
|
|
||||||
self.floating_layer
|
self.floating_layer
|
||||||
.remap_minimized(window.clone(), from, geometry.loc);
|
.remap_minimized(window.clone(), from, geometry.loc);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,10 @@ impl ToplevelManagementHandler for State {
|
||||||
{
|
{
|
||||||
for mapped in workspace
|
for mapped in workspace
|
||||||
.mapped()
|
.mapped()
|
||||||
.filter(|m| m.maximized_state.lock().unwrap().is_some())
|
.filter(|m| {
|
||||||
|
m.maximized_state.lock().unwrap().is_some()
|
||||||
|
&& !m.windows().any(|(ref w, _)| w == window)
|
||||||
|
})
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue