Skip to content

SDL has unexpected behavior when switching window sizes (X11/Wayland) #7070

@madebr

Description

@madebr

(using SDL2)
Consider the source at the bottom of this post.
It should switch between maximized and windowed mode every second while also changing the window draw color.
I expect the log to be the following:

INFO: Window Size    : width: 120, height: 200
INFO: Maximized Size : width: 1920, height: 1048
INFO: Window Size    : width: 120, height: 200
INFO: Maximized Size : width: 1920, height: 1048
INFO: Window Size    : width: 120, height: 200
INFO: Maximized Size : width: 1920, height: 1048
INFO: Window Size    : width: 120, height: 200
INFO: Maximized Size : width: 1920, height: 1048
...

Instead, it is the following (for X11):

INFO: Window Size    : width: 120, height: 200
INFO: Maximized Size : width: 128, height: 200
INFO: Window Size    : width: 1920, height: 1048
INFO: Maximized Size : width: 1920, height: 1048
INFO: Window Size    : width: 1920, height: 1048
INFO: Maximized Size : width: 128, height: 200
INFO: Window Size    : width: 1920, height: 1048
INFO: Maximized Size : width: 1920, height: 1048
INFO: Window Size    : width: 1920, height: 1048
INFO: Maximized Size : width: 128, height: 200
INFO: Window Size    : width: 1920, height: 1048
INFO: Maximized Size : width: 1920, height: 1048
INFO: Window Size    : width: 1920, height: 1048
INFO: Maximized Size : width: 128, height: 200
...

For wayland, the startup logs are slightly different, but it ends in the same steady state.

INFO: Window Size    : width: 120, height: 200
INFO: Maximized Size : width: 120, height: 200
INFO: Window Size    : width: 1920, height: 1048
INFO: Maximized Size : width: 120, height: 200
INFO: Window Size    : width: 1920, height: 1048
INFO: Maximized Size : width: 1920, height: 1048
INFO: Window Size    : width: 1920, height: 1048
INFO: Maximized Size : width: 120, height: 200
...

Sprinkling more calls to handle_events in the main loop does not solve the issue. In contrary, it makes the behavior more erratic.

source:

#include "SDL.h"
#include <stdio.h>

static void SetNextColor(SDL_Renderer *renderer) {
    static int c = 0;
    SDL_SetRenderDrawColor(renderer, (c&0x1)*0xff, (c&0x2)*0xff, (c&0x4)*0xff, 0xff);
    c += 1;
}

static int handle_events(void) {
    int res = 0;
    SDL_Event event;
    while (SDL_PollEvent(&event)) {
        switch (event.type) {
        case SDL_QUIT:
            res = 1;
            break;
        default:
            break;
        }
    }
    return 0;
}

int main(int argc, char *argv[]) {
    SDL_assert(SDL_Init(SDL_INIT_VIDEO) == 0);

    SDL_Window *window = SDL_CreateWindow("title", 0, 0, 120, 200, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS);
    SDL_assert(window != NULL);
    SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
    SDL_assert(renderer != NULL);

    int w=0;
    int h=0;
    
    while (1) {
        SetNextColor(renderer);
        SDL_RenderClear(renderer);
        SDL_RenderPresent(renderer);
        SDL_GetWindowSize(window, &w, &h);
        SDL_Log("Window Size    : width: %d, height: %d", w, h);
        SDL_Delay(1000);

        SDL_MaximizeWindow(window);
        if (handle_events()) {break;}
        SetNextColor(renderer);
        SDL_RenderClear(renderer);
        SDL_RenderPresent(renderer);
        SDL_GetWindowSize(window, &w, &h);
        SDL_Log("Maximized Size : width: %d, height: %d", w, h);
        SDL_Delay(1000);
        
        SDL_RestoreWindow(window);
        if (handle_events()) {break;}
    }
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
}

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions