Skip to content

Linux/X11 (compositing WM): any window change after device creation wedges the Vulkan presenter inside CreateSwapChain — fullscreen toggle, border removal, even a bare SDL_SetWindowPosition #3320

Description

@jpenberthy

Release Type: Official Release
Version: 4.3.0.2507
Platform(s): Linux, X11, compositing WM (repro on Cinnamon/Muffin); Windows/D3D11 unaffected

Describe the bug
Every post-device window mutation we tried permanently wedges or crashes the game. Live stacks
(two independent variants) pin the hang inside
SwapChainGraphicsPresenter.Present()CreateSwapChain()CreateBackBuffers(), never
returning, ~37% CPU spin. Variants reproduced in one evening, each attempted as the "safer"
fallback for the previous:

  1. GameWindow.IsFullscreen = true pre-load → device presents to a black screen forever.
  2. Stride borderless path pre-load (FullscreenIsBorderlessWindow + Position + SetSize) →
    window never mapped, Present() at 0 fps, WM kills the "unresponsive" app in ~20 s.
  3. Same borderless transition post-load → immediate segfault at the transition frame.
  4. Raw SDL_SetWindowFullscreen(FULLSCREEN_DESKTOP) after the loop was pumping → permanent
    wedge with the stack above.
  5. Minimal case — SDL_SetWindowBordered(false) + SDL_SetWindowPosition, no size or mode
    change
    (backbuffer already equaled the display) → same wedge, same stack.

To Reproduce
Code-only Linux game on X11 under a compositing WM; after the first frame, perform any of the
five variants above.

Expected behavior
Fullscreen/borderless transitions work, or fail recoverably.

Additional context
Suspected: the swapchain rebuild waits on in-flight presentation that never completes once the
surface is invalidated under a compositing WM. Working pattern (ships today, worth
documenting for code-only games):
construct a fully-shaped GameFormSDL before
Game.Run — border style, final size, final position — so Stride maps the window exactly once
in its final state and builds the swapchain exactly once. Verified on a four-monitor X11
desktop. One repro caveat: poke SDL only through the engine's Silk.NET binding — a raw
DllImport("SDL2") loads a second SDL with uninitialized state and returns garbage bounds.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions