Problem
SDL3 supports multiple windows via SDL_ClaimWindowForGPUDevice, but GameKit has several single-window assumptions baked in.
1. Window is a hard singleton
GameKitAppBuilder registers one Window and aliases it as IWindow. There is no window collection or registry.
2. EventService ignores windowID when routing window events
SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED is forwarded unconditionally to the single _window without checking evt.window.windowID. With multiple windows, any resize would notify the wrong instance.
3. DefaultRenderContextProvider acquires a swapchain from one window per frame
Each window needs its own command buffer and swapchain texture acquired and submitted independently within the same frame.
4. GraphicsPipelineBuilder.AddColorFormatFromDisplay() queries the single window
It reads _window.ColorTargetFormat implicitly. Pipelines targeting a secondary window would use the wrong format.
5. ITextInputService.Start() / Stop() target a hardcoded window
TextInputService holds a fixed Window and passes it to SDL_StartTextInput / SDL_StopTextInput. PencuilRenderPhase already receives the correct IWindow for the window it renders to but has no way to pass it through.
Possible approach
- Introduce
IWindowManager with a PrimaryWindow, a window collection, and CreateWindow / DestroyWindow. The existing IWindow singleton remains valid for single-window apps.
- Route
SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED (and other window-specific events) through IWindowManager by windowID.
- Extend render orchestration to iterate all windows and acquire/submit a swapchain per window per frame.
- Add
IWindow parameters to ITextInputService.Start(IWindow) / Stop(IWindow) so Pencuil can pass the window it rendered to.
- Change
AddColorFormatFromDisplay() to accept an explicit IWindow.
Problem
SDL3 supports multiple windows via
SDL_ClaimWindowForGPUDevice, but GameKit has several single-window assumptions baked in.1.
Windowis a hard singletonGameKitAppBuilderregisters oneWindowand aliases it asIWindow. There is no window collection or registry.2.
EventServiceignoreswindowIDwhen routing window eventsSDL_EVENT_WINDOW_PIXEL_SIZE_CHANGEDis forwarded unconditionally to the single_windowwithout checkingevt.window.windowID. With multiple windows, any resize would notify the wrong instance.3.
DefaultRenderContextProvideracquires a swapchain from one window per frameEach window needs its own command buffer and swapchain texture acquired and submitted independently within the same frame.
4.
GraphicsPipelineBuilder.AddColorFormatFromDisplay()queries the single windowIt reads
_window.ColorTargetFormatimplicitly. Pipelines targeting a secondary window would use the wrong format.5.
ITextInputService.Start()/Stop()target a hardcoded windowTextInputServiceholds a fixedWindowand passes it toSDL_StartTextInput/SDL_StopTextInput.PencuilRenderPhasealready receives the correctIWindowfor the window it renders to but has no way to pass it through.Possible approach
IWindowManagerwith aPrimaryWindow, a window collection, andCreateWindow/DestroyWindow. The existingIWindowsingleton remains valid for single-window apps.SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED(and other window-specific events) throughIWindowManagerbywindowID.IWindowparameters toITextInputService.Start(IWindow)/Stop(IWindow)so Pencuil can pass the window it rendered to.AddColorFormatFromDisplay()to accept an explicitIWindow.