shell: Restore fullscreen to single-element stack

If a surface was previously a single-element stack, restore it normally
using the floating/tiling restore data, but map as a single element
stack instead of a plain window.
This commit is contained in:
Ian Douglas Scott 2026-06-23 15:54:37 -07:00 committed by Ian Douglas Scott
parent 98e1dd7f6b
commit 373a44d431
2 changed files with 38 additions and 7 deletions

View file

@ -12,7 +12,10 @@ use std::{
use wayland_backend::server::ClientId; use wayland_backend::server::ClientId;
use crate::{ use crate::{
shell::{focus::FocusTarget, grabs::fullscreen_items, layout::tiling::PlaceholderType}, shell::{
element::CosmicStack, focus::FocusTarget, grabs::fullscreen_items,
layout::tiling::PlaceholderType,
},
wayland::{ wayland::{
handlers::data_device::{self, get_dnd_icon}, handlers::data_device::{self, get_dnd_icon},
protocols::workspace::{State as WState, WorkspaceCapabilities}, protocols::workspace::{State as WState, WorkspaceCapabilities},
@ -2607,12 +2610,21 @@ impl Shell {
} }
} }
let window = CosmicMapped::from(CosmicWindow::new( let window = if state.as_ref().is_some_and(|s| s.was_stack()) {
surface, CosmicMapped::from(CosmicStack::new(
loop_handle.clone(), std::iter::once(surface),
self.theme.clone(), loop_handle.clone(),
self.appearance_conf, self.theme.clone(),
)); self.appearance_conf,
))
} else {
CosmicMapped::from(CosmicWindow::new(
surface,
loop_handle.clone(),
self.theme.clone(),
self.appearance_conf,
))
};
if let Some(FullscreenRestoreState::Sticky { output, state, .. }) = &state { if let Some(FullscreenRestoreState::Sticky { output, state, .. }) = &state {
let output = output let output = output
@ -3267,6 +3279,7 @@ impl Shell {
state: None, state: None,
was_maximized: previous.was_maximized(), was_maximized: previous.was_maximized(),
}, },
was_stack: previous.was_stack(),
}; };
} else if let FullscreenRestoreState::Tiling { workspace, .. } } else if let FullscreenRestoreState::Tiling { workspace, .. }
| FullscreenRestoreState::Floating { workspace, .. } = previous | FullscreenRestoreState::Floating { workspace, .. } = previous
@ -4808,6 +4821,7 @@ impl Shell {
let mut from = set.sticky_layer.element_geometry(&mapped).unwrap(); let mut from = set.sticky_layer.element_geometry(&mapped).unwrap();
let mut was_maximized = false; let mut was_maximized = false;
let mut restore_state = None; let mut restore_state = None;
let was_stack = mapped.is_stack();
window = if let Some(stack) = mapped.stack_ref() window = if let Some(stack) = mapped.stack_ref()
&& stack.len() > 1 && stack.len() > 1
{ {
@ -4859,6 +4873,7 @@ impl Shell {
was_maximized, was_maximized,
was_snapped: None, was_snapped: None,
}, },
was_stack,
})), })),
Some(from), Some(from),
); );
@ -4893,12 +4908,14 @@ impl Shell {
Some(FullscreenRestoreState::Floating { Some(FullscreenRestoreState::Floating {
workspace: handle, workspace: handle,
state: floating_state, state: floating_state,
was_stack: mapped.is_stack(),
}) })
} }
WorkspaceRestoreData::Tiling(tiling_state) => { WorkspaceRestoreData::Tiling(tiling_state) => {
Some(FullscreenRestoreState::Tiling { Some(FullscreenRestoreState::Tiling {
workspace: handle, workspace: handle,
state: tiling_state, state: tiling_state,
was_stack: mapped.is_stack(),
}) })
} }
WorkspaceRestoreData::Stack(stack_state) => { WorkspaceRestoreData::Stack(stack_state) => {

View file

@ -254,14 +254,17 @@ pub enum FullscreenRestoreState {
Tiling { Tiling {
workspace: WorkspaceHandle, workspace: WorkspaceHandle,
state: TilingRestoreData, state: TilingRestoreData,
was_stack: bool,
}, },
Floating { Floating {
workspace: WorkspaceHandle, workspace: WorkspaceHandle,
state: FloatingRestoreData, state: FloatingRestoreData,
was_stack: bool,
}, },
Sticky { Sticky {
output: WeakOutput, output: WeakOutput,
state: FloatingRestoreData, state: FloatingRestoreData,
was_stack: bool,
}, },
Stack { Stack {
state: StackRestoreData, state: StackRestoreData,
@ -277,6 +280,17 @@ impl FullscreenRestoreState {
FullscreenRestoreState::Stack { .. } => false, FullscreenRestoreState::Stack { .. } => false,
} }
} }
// Surface was previously a single-window stack
pub fn was_stack(&self) -> bool {
match self {
FullscreenRestoreState::Floating { was_stack, .. }
| FullscreenRestoreState::Sticky { was_stack, .. } => *was_stack,
FullscreenRestoreState::Tiling { was_stack, .. } => *was_stack,
// Stack wasn't removed; surface was removed from the stack
FullscreenRestoreState::Stack { .. } => false,
}
}
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]