Skip to content

fix: preserve fullscreen state when moving window between workspaces#2135

Open
mayakwd wants to merge 3 commits intopop-os:masterfrom
mayakwd:fix/fullscreen-workspace-transfer
Open

fix: preserve fullscreen state when moving window between workspaces#2135
mayakwd wants to merge 3 commits intopop-os:masterfrom
mayakwd:fix/fullscreen-workspace-transfer

Conversation

@mayakwd
Copy link
Contributor

@mayakwd mayakwd commented Feb 24, 2026

Following up #2099.
Fixes the issue where moving a full-screen window (e.g., Chrome with a full-screen video) between workspaces causes the client to exit full-screen.

Root cause: move_window calls unmap_surface, which internally calls remove_fullscreen(). This sends an intermediate configure with set_fullscreen(false) before map_fullscreen(), and then map_fullscreen () re-applies it on the destination workspace.
Chrome sees the intermediate "not a full-screen" configure and cancels video full-screen.

Fix explanation:

  • Added Workspace::take_fullscreen() — a silent counterpart to remove_fullscreen() that extracts the fullscreen state without notifying the client (no set_fullscreen(false), no send_configure(), no exit animation).
  • In move_window, fullscreen windows are detected and handled via take_fullscreen() instead of unmap_surface(). The destination workspace's map_fullscreen() then sends a single configure with fullscreen state preserved.
  • remove_fullscreen() and unmap_surface() remain unchanged — all other code paths (close, minimize, unfullscreen, drag-move) still go through the original flow with proper client notification and exit animation.

What I tested:

  • Chrome with fullscreen video > Move to another workspace > Video stays full-screen
  • Firefox with fullscreen video > Move to another workspace > Video stays full-screen (regression test)
  • Fullscreen game (Death Stranding) and Steam in Big-Picture mode successfully moved through workspaces without losing full-screen state

What I didn't test:

  • Moving windows through workspaces attached to different displays (I don't have such hw setup), but it still should work, since toplevel_leave_output and toplevel_enter_output handle this case.

UPD
Added agreement section from PR template:

  • I have disclosed use of any AI generated code in my commit messages.
  • I understand these changes in full and will be able to respond to review comments.
  • My change is accurately described in the commit message.
  • My contribution is tested and working as described.
  • I have read the Developer Certificate of Origin and certify my contribution under its conditions.

@mayakwd mayakwd force-pushed the fix/fullscreen-workspace-transfer branch from d6c1ab9 to d6a94c3 Compare February 24, 2026 17:11
Copy link
Member

@Drakulix Drakulix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. This looks good apart from some nitpicks.

Option<FullscreenRestoreState>,
Option<Rectangle<i32, Local>>,
)> {
let surface = self.fullscreen.take()?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let surface = self.fullscreen.take()?;
let surface = self.fullscreen.take_if(|s| s.ended_at.is_none())?;

Would be a bit cleaner here and avoid the whole condition.

Copy link
Contributor Author

@mayakwd mayakwd Mar 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point! Done.

focus_stack.retain(|t| t != &surface.surface);
}

Some((surface.previous_state, surface.previous_geometry))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this for symmetry with remove_fullscreen please also return the surface. That is easy enough to skip over in move_window.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@mayakwd mayakwd force-pushed the fix/fullscreen-workspace-transfer branch from c0eec5f to 1e4594f Compare March 14, 2026 12:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants