Skip to content

submit a WINDOW_EXPOSED event to match the non-libdecor path#15382

Closed
A1029384756 wants to merge 1 commit intolibsdl-org:mainfrom
A1029384756:wayland-expose-event
Closed

submit a WINDOW_EXPOSED event to match the non-libdecor path#15382
A1029384756 wants to merge 1 commit intolibsdl-org:mainfrom
A1029384756:wayland-expose-event

Conversation

@A1029384756
Copy link
Copy Markdown
Contributor

sends a WINDOW_EXPOSED event during resize operations to prevent blocking if listening to the WINDOW_EXPOSED events. before, WINDOW_EXPOSED would only fire after the resize event completed, requiring that rendering be unconditionally done every frame for smooth resizes. this matches the behavior in the non-libdecor path as well

@Kontrabant
Copy link
Copy Markdown
Contributor

Do you have an example case that this fixes? An exposure event is already sent from within ConfigureWindowGeometry() when starting an interactive resize on the libdecor path, as, unlike the native xdg-toplevel path, libdecor doesn't defer ack-ing the configure state and sending the new size when resizing (it can't, for reasons mentioned in the comment above).

What this is doing, is sending exposure events during the dropped resize events, which doesn't serve a purpose.

This is the case that the xdg-toplevel fix addressed, which works on the libdecor path without any fixes:

#include <SDL3/SDL.h>


int main()
{
    SDL_Window* window;
    SDL_Renderer* renderer;
    SDL_Init(SDL_INIT_VIDEO);

    SDL_CreateWindowAndRenderer("test", 300, 250, 0, &window, &renderer);

    SDL_SetWindowResizable(window, true);

    while(1)
    {
        SDL_Event event;
        SDL_WaitEvent(&event);
        switch(event.type)
        {
        case SDL_EVENT_QUIT:
            goto CLOSE;
        default:
            break;
        }
        SDL_SetRenderDrawColor(renderer, 255, 0, 0, SDL_ALPHA_OPAQUE);
        SDL_RenderClear(renderer);
        SDL_RenderPresent(renderer);
    }

    CLOSE:
        SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
}

@A1029384756
Copy link
Copy Markdown
Contributor Author

A1029384756 commented Apr 14, 2026

yes, this gist here should be a good example of how to repro it: https://gist.github.com/A1029384756/e051f966715ad1f632181c0ae6ff2c5e

this results in the following resize behavior before the fix:
https://github.com/user-attachments/assets/ea778208-c6f0-483a-8194-b32fa3b5c0d8

the program there isn't identical to that shown in the gist but the behavior is the same between it and the example. this just allows me to get access to some event that indicates the window resized so that i can actually trigger a rerender. in the current case, the resize events are only sent at the end of the drag action, giving me no indication that the renderable surface may have changed at all. this matters in the case of a UI library where i don't necessarily want to rerender every frame

without this, the resize operations will not be smooth if any code similar to the following is present:

if Renderer_should_redraw(ctx, &render_commands) {
  cmd_buffer := sdl.AcquireGPUCommandBuffer(ctx.device)
  Renderer_draw(ctx, cmd_buffer, &render_commands)
  _ = sdl.SubmitGPUCommandBuffer(cmd_buffer)
}

i did check to see if there were any other events i could listen for to achieve a similar effect but it seems that no events are produced at all during resize

@Kontrabant
Copy link
Copy Markdown
Contributor

Kontrabant commented Apr 14, 2026

Which desktop are you running? One KDE (forcing the libdecor path), your example runs smoothly with and without your change. On GNOME, it's laggy both with and without.

Also, are you using the master branch of libdecor? The code in your change won't actually be hit unless you are using the master branch (with the version manually patched to 0.3.0), as the resize status has yet to be exposed in a release version of libdecor. With all shipping 0.2.x versions of libdecor, the 'else' case with your change is never actually hit.

@A1029384756
Copy link
Copy Markdown
Contributor Author

A1029384756 commented Apr 14, 2026

i am testing on KDE in a fedora 43 distrobox container and a flatpak

as for the version i was testing, my bad, i noticed that i was only testing my code with the release-3.4.0 tag, not the tip of the main branch. main does in fact fire the WINDOW_EXPOSED events correctly

@A1029384756 A1029384756 deleted the wayland-expose-event branch April 14, 2026 17:58
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