CNA-BUG-177: The Headless and Terminal window constructors accept BorderlessFullscreen although their own SetFullscreenMode refuses it

CNA snapshot c1c316b9  ·  Known Issues › Current bugs  ·  source links pinned to c1c316b9

✓

Evidence basis: source-verified at the pinned commit; tests exist (not executed for this page). Claims on this page were checked by reading the CNA source at commit c1c316b9; unless a sentence says otherwise, nothing here was built or executed. Nothing on this page was executed unless the Evidence section says so.

Both capability-minimal windows store WindowDescription::fullscreenMode directly at construction instead of routing it through SetFullscreenMode, so a window created in BorderlessFullscreen reports that mode though the platform's capability is false.

Identifier
CNA-BUG-177
Category
Bug
Subsystem
Platforms
Status
Open
Verified against
CNA c1c316b9 (c1c316b9c7a846ce8002809c151fcd1af14942c9)
Severity
Low (a triage suggestion, not a project priority)
Evidence basis
Source-verified: read at TARGET, not executed
Tests touching this area
Yes: see Current tests
Affected contract
CNA::Platform::IPlatform::CreateWindow(const WindowDescription&) and IPlatformWindow::GetFullscreenMode()/SetFullscreenMode() on the Headless and Terminal platforms

Expected behaviour

platform-abstraction.md and IPlatformWindow::SetFullscreenMode state that “a window with no borderlessFullscreen capability must refuse that mode”, and the SDL3 platform enforces it: its CreateWindow (Sdl3Platform.cpp) funnels a non-Windowed WindowDescription::fullscreenMode through SetFullscreenMode right after construction, so the refusal path runs. Headless and Terminal report borderlessFullscreen = false and their SetFullscreenMode throws PlatformNotSupportedException(BorderlessFullscreen).

Actual behaviour at TARGET

HeadlessWindow and TerminalWindow initialise mode_(description.fullscreenMode) in their constructors and never call their own SetFullscreenMode. A window created with fullscreenMode = BorderlessFullscreen is therefore accepted, and GetFullscreenMode() returns BorderlessFullscreen, even though the platform's capability is false and a later SetFullscreenMode(BorderlessFullscreen) on the same window throws. The window is left in a mode the platform says it cannot provide.

Source locations

Evidence

Checked by reading the Headless and Terminal window classes, the SDL3 platform's CreateWindow (which does route creation through SetFullscreenMode) and the conformance suite at c1c316b9. Not executed. The defect is that the two capability-minimal backends bypass their own refusal at construction; the SDL3 platform does not.

Independent re-verification: Checked by reading the Headless and Terminal window classes and CreateWindow functions, the SDL3 CreateWindow function and the conformance suite at c1c316b9. Not executed. The defect is that the two capability-minimal backends bypass their own refusal at construction; the SDL3 platform does not. The XNA-facing runtime cannot reach it: GraphicsDevice creates its window with the default Windowed mode and later calls SetFullscreenMode with ExclusiveFullscreen or Windowed only, so the path is reached only by code that calls IPlatform::CreateWindow directly with BorderlessFullscreen.

Focused reproduction

Illustrative (not compiled for this entry):

WindowDescription d;
d.fullscreenMode = WindowFullscreenMode::BorderlessFullscreen;
auto platform = PlatformFactory::Create("Headless");
auto window = platform->CreateWindow(d);                 // accepted
assert(!platform->GetCapabilities().borderlessFullscreen);
assert(window->GetFullscreenMode() == WindowFullscreenMode::BorderlessFullscreen);  // holds
window->SetFullscreenMode(WindowFullscreenMode::BorderlessFullscreen);              // now it throws

Current tests

PlatformConformanceTests.cpp's PlatformWindowConformance.BorderlessFullscreenFollowsItsCapability creates the window with the default (Windowed) mode and then calls SetFullscreenMode. No case creates a window with fullscreenMode = BorderlessFullscreen on a platform whose capability is false.

Regression test

Extend the window conformance suite: creating a window with a fullscreen mode the platform's capability forbids must either refuse (as the setter does) or clamp to Windowed, and GetFullscreenMode() must never report a mode the capability denies. The fix is to route the constructor's mode through the same SetFullscreenMode the other backends use.

Blast radius

Games that create a window in BorderlessFullscreen on the Headless or Terminal platform and read GetFullscreenMode(); the SDL3 platform already applies or refuses the mode at creation and is unaffected.

Workaround

On Headless and Terminal, create windows with the default Windowed mode.

The same subject is explained at several altitudes. These are the neighbouring pages at each one.

Known issues
Bug index