SDL Wiki
[ front page | index | search | recent changes | git repo | offline html ]

Why does my app freeze while the window is being resized or dragged/moved?

On some operating systems (notably Windows, but others as well), your call into SDL_PollEvent, SDL_WaitEvent, SDL_WaitEventTimeout, or SDL_PumpEvents may block during resizing or dragging. This means these functions will not return and yield control to your code, until the OS is done with this operation, so new frames of video won't render, and other tasks, like game logic and multiplayer network upkeep, will not have a chance to run. The delay will last as long as the user is dragging or resizing the window in this case, which might be several seconds or more!

The operating systems do provide ways for a user application to still do work during these operations, but they do so through callbacks: a function the user provides and the OS will call at appropriate times.

SDL provides two ways to get called during these blocking operations.

For further context, even when blocked the OS gives your application time slices during these operations, but they do so through callbacks themselves, not by returning back to user code. So the only solution is for SDL or similar to give you a callback as well.

This doesn't guarantee perfectly smooth resizing but greatly improves the situation.

Here's a program that demonstrates using the main callbacks, still allowing user code to run during Window resize and move operations:

#include <SDL3/SDL.h>

#define SDL_MAIN_USE_CALLBACKS
#include <SDL3/SDL_main.h>

SDL_Window* g_window;
SDL_Renderer* g_renderer;
SDL_FRect g_rect = {
    100.f, 100.f, 100.f, 100.f
};

SDL_AppResult SDL_AppInit(void** appstate, int argc, char** argv)
{
    SDL_CreateWindowAndRenderer("Test", 300, 300, SDL_WINDOW_RESIZABLE, &g_window, &g_renderer);
    return SDL_APP_CONTINUE;
}

SDL_AppResult SDL_AppIterate(void* appstate)
{
    SDL_SetRenderDrawColor(g_renderer, 0, 0, 0, 255);
    SDL_RenderClear(g_renderer);

    SDL_FRect rect = g_rect;
    rect.x += 50 * SDL_sinf(SDL_GetTicksNS() / 1000000000.f);


    SDL_SetRenderDrawColor(g_renderer, 255, 255, 255, 255);
    SDL_RenderFillRect(g_renderer, &rect);


    SDL_RenderPresent(g_renderer);
    return SDL_APP_CONTINUE;
}

SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
{
    if (event->common.type == SDL_EVENT_QUIT) {
        return SDL_APP_SUCCESS;
    }
    return SDL_APP_CONTINUE;
}

void SDL_AppQuit(void* appstate, SDL_AppResult result)
{ 
}

[ edit | delete | history | feedback | raw ]

All wiki content is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0).
Wiki powered by ghwikipp.