Skip to content

Viewports, SDL3: Fix secondary viewports uncollapse incorrect sizing - #9529

Open
SuperRonan wants to merge 1 commit into
ocornut:dockingfrom
SuperRonan:fix/sdl3-secondary-viewport-collapse-sizing
Open

Viewports, SDL3: Fix secondary viewports uncollapse incorrect sizing#9529
SuperRonan wants to merge 1 commit into
ocornut:dockingfrom
SuperRonan:fix/sdl3-secondary-viewport-collapse-sizing

Conversation

@SuperRonan

Copy link
Copy Markdown
Contributor

The same issue as #2756 is manifesting for me with SDL3 (on Windows 11).
63692779-1bf19480-c81b-11e9-9886-b1448badc5f9
When uncollapsing a window in a secondary viewport, its size (more precisely its height) is not properly restored.

Problem detail:

Although the problem appears to happen when uncollapsing the window in a secondary viewport, its actual origin happens when collapsing in a secondary viewport.

collapse_ok Collapsing in the main viewport then uncollapsing in a secondary viewport: no problem. collapse_not_ok Collapsing in a secondary viewport then uncollapsing in the main viewport: incorrect height restored.

Note that the wrongly restored height (32px) is not the same as the collapsed height (19px).

This is due to a chain of event between ImGui's and SDL3 when collapsing:

  • [0] The window is in a secondary viewport.
  • [1] Click on the collapse button -> ImGui_ImplSDL3_SetWindowSize(viewport, collapsed_size (h = 19)) is called, which adds an SDL_EVENT_WINDOW_RESIZED to SDL3's event queue.
  • [2] Next frame, the SDL_EVENT_WINDOW_RESIZED mentionned above is processed (with the same resolution as above (collapsed size)) -> viewport->PlatformRequestResize is set to true (in ImGui_ImplSDL3_ProcessEvent(), case SDL_EVENT_WINDOW_RESIZED:)
  • [3] During the following ImGui::UpdateViewportsNewFrame(), viewport->PlatformRequestResize is treated as if the viewport was manually resized (to the collapsed size), windows attached to the viewport are set with .Size = collapsed_size (h = 19)
  • [4] During the ImGui::Begin() of the window, window->SizeFull = CalcWindowSizeAfterConstraint(window, window->SizeFull);, which sets window.SizeFull.y = 32; (from g.Style.WindowMinSize.y).
  • [5] Later, when uncollapsing, the window size is restored from window->SizeFull, which was "corrupted" by the previous events.

Fix:

The issue comes from step [2].
#2756 Proposed to keep a frame index when ImGui_ImplGlfw_SetWindowSize() is called, and ignore the next resize event during the next frame, but I don't think it is the best solution.

The SDL_EVENT_WINDOW_RESIZED event triggered by SDL_SetWindowSize() might provide some useful data according to the SDL3 doc:

When the window size changes, an SDL_EVENT_WINDOW_RESIZED event will be emitted with the new window dimensions. Note that the new dimensions may not match the exact size requested, as some windowing systems can restrict the window size in certain scenarios (e.g. constraining the size of the content area to remain within the usable desktop bounds). Additionally, as this is just a request, it can be denied by the windowing system.

Here I am proposing to 'accept' the event only if it is relevent: its resized resolution is different from viewport's current one. It is important to set viewport->PlatformRequestResize = true; if the resolution is not the same.

About SDL2:

Surprisingly, this issue does not arise with SDL2!
The difference is that SDL2's SDL_SetWindowSize() triggers a SDL_WINDOWEVENT_SIZE_CHANGED instead of a SDL_WINDOWEVENT_RESIZED, and ImGui_ImplSDL2_ProcessEvent() only processes the latter.
SDL3 did replace SDL_WINDOWEVENT_SIZE_CHANGED by SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED, but I don't know why it is not triggered by SDL3's SDL_SetWindowSize() instead of SDL_WINDOWEVENT_RESIZED...

Moving viewports:

A similar behaviour happens when moving a window with ImGui_ImplSDL3_SetWindowPos() which triggers a SDL_EVENT_WINDOW_MOVED (the SDL3 backend thinks the window was moved during the next frame). So it might be worth adding a similar check before setting viewport->PlatformRequestMove = true;.
I haven't had any issue with this yet (maybe it could trigger with SetWindowPosVal / SetWindowPosPivot?).

One more case:

Maybe window->SizeFull = CalcWindowSizeAfterConstraint(window, window->SizeFull); should not apply to the collapsed axis (.y in our case, but it could be .x if we were to have side collapsing) if the window is collapsed.
This case could arise if the windowing system were to return a different resolution with the SDL_WINDOWEVENT_RESIZED than the one requested by SDL_SetWindowSize(), then viewport->PlatformRequestResize would be set and nothing could prevent a wrong height from being restored when uncollapsing.

- Fixes incorrect reduced size when un-collapsing window in secondary viewport
- SImilar to ocornut#2756
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants