Taggagii
Taggagii

Reputation: 81

Why does my window only get shown after I use SDL_PollEvent()?

I'm using SDL2 in C and wanted to show something to the screen without the need for taking in inputs. But when I ran the code to present a black screen the window would not open. I proceeded to do what I knew would make it pop up and added a SDL_Event variable and used SDL_PollEvent(). I would like to know why I had to do this, and if there would be a way for me to use a SDL_Window without polling any events.

(For example: something like an animation).

The code in question is as follows:

#include <stdio.h>
#include <stdlib.h>
#include <SDL2/SDL.h>

int main()
{
    if (SDL_Init(SDL_INIT_VIDEO))
    {
        fprintf(stderr, "Error while Initalizing SDL2: %s\n", SDL_GetError());
        return EXIT_FAILURE;
    }
    SDL_Window *window = SDL_CreateWindow("Connect Four", 100, 100, 500, 500, SDL_WINDOW_SHOWN);
    if (!window)
    {
        fprintf(stderr, "Error while Initalizing window: %s\n", SDL_GetError());
        return EXIT_FAILURE;
    }
    SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    if (!renderer)
    {
        SDL_DestroyWindow(window);
        fprintf(stderr, "Error while Initalizing renderer: %s\n", SDL_GetError());
        return EXIT_FAILURE;
    }
    SDL_Event events; //without these two lines
    SDL_PollEvent(&events); //the window will not open on screen
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    SDL_RenderClear(renderer);    
    SDL_RenderPresent(renderer);
    SDL_Delay(3000);

    SDL_DestroyWindow(window);
    SDL_Quit();
    return EXIT_SUCCESS;
}

Upvotes: 1

Views: 438

Answers (1)

keltar
keltar

Reputation: 18409

It may be confusing because some SDL examples (including SDL doc wiki) uses "draw&delay" code without event processing, but that is not a reliable way to display things on screen. That examples are overly simplified and was written long time ago when it kind of worked, but only for simplest things, as 3 seconds is probably not long enough for window manager to kill unresponsive program, or for user to notice window image collapses if it is minimised or covered by other windows.

Short answer to your question is no, your program have to communicate with window manager (side note - it may not be necessary on some operating/graphics systems); you have to get events and react to special window events (e.g. your window becoming visible or user requesting resize). In SDL, this is done with SDL_PumpEvents call, which internally does this communication and generates event queue that you can inspect later, so you need to call that frequently, either directly or indirectly via SDL_PollEvent or SDL_WaitEvent. If you don't, window manager probably will not be nice to you - depending on window manager, you may get "application not responding, let's kill it" dialog, greyed out window or, as in your case, no window at all (that particular case is because you've presented your rendering result before "your window is now visible" event was received, so your image is discarded; that's why processing events before rendering changed how things go).

But even so, processing events once is not correct either. What you have is still optimistic "let's hope nothing breaking will happen in 3 seconds". If you do animation, process events on every frame; but if you have static display code - it may be good idea to treat it like it is animated too. Basically you need rendering loop, with event processing at start, and redraw code to re-generate your image when you have to. This "have to" may be either unconditional (full redraw on every iteration), or, if you really don't want to (e.g. for processing cost reasons - most GUI programs don't do full redraw when idle) you still have to redraw when window manager says your previous image is no longer valid - SDL notifies you of that via SDL_WindowEvent of SDL_WINDOWEVENT_EXPOSED type. In that case you may want to use blocking SDL_WaitEvent to avoid unnecessary iterations.

Upvotes: 2

Related Questions