Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SDL_CreateWindowAndRenderer does not center window on creation at first in Debian GNU/Linux #12060

Closed
milq opened this issue Jan 22, 2025 · 5 comments · Fixed by #12068
Closed
Assignees
Milestone

Comments

@milq
Copy link

milq commented Jan 22, 2025

Description:

When using SDL_CreateWindowAndRenderer, the window does not start centered on the screen. Instead, it first appears in a default position and then centers itself shortly after. Additionally, there doesn't seem to be a way to set the initial window position directly through this function. In contrast, using SDL_CreateWindowWithProperties correctly centers the window from the moment it is created.

Steps to reproduce:

  1. Initialize SDL with video and audio support.
  2. Create a window and renderer using SDL_CreateWindowAndRenderer.
  3. Observe that the window first appears in a default position and then moves to the center.

Expected behavior:

The window should be centered on the screen immediately upon creation without any initial positioning offset.

Actual behavior:

The window initially appears at a default position and then moves to the center of the screen shortly after creation.

Code examples:

Issue Scenario (SDL_CreateWindowAndRenderer centers after creation):

SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
{
    SDL_Renderer * renderer = NULL;
    SDL_Window * window = NULL;

    SDL_SetAppMetadata("Game", "1.0", "io.itch.milq.game");

    if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) {
        SDL_Log("SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) failed: %s", SDL_GetError());
        return SDL_APP_FAILURE;
    }

    SDL_SetHint(SDL_HINT_VIDEO_WINDOW_POSITION, "center");

    if (!SDL_CreateWindowAndRenderer("Game", 1280, 720, 0, &window, &renderer)) {
        SDL_Log("SDL_CreateWindowAndRenderer() failed: %s", SDL_GetError());
        return SDL_APP_FAILURE;
    }

    // Additional initialization...
}

Expected behavior scenario (SDL_CreateWindowWithProperties centers immediately):

SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
{
    int logicalWidthResolution = 320;
    int logicalHeightResolution = 180;

    SDL_Renderer * renderer = NULL;
    SDL_Window * window = NULL;

    SDL_SetAppMetadata("Game", "1.0", "io.itch.milq.game");

    if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) {
        SDL_Log("SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) failed: %s", SDL_GetError());
        return SDL_APP_FAILURE;
    }

    SDL_PropertiesID props = SDL_CreateProperties();
    SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, "Game");
    SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, SDL_WINDOWPOS_CENTERED);
    SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, SDL_WINDOWPOS_CENTERED);
    SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, (int64_t)1280);
    SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, (int64_t)720);

    window = SDL_CreateWindowWithProperties(props);
    if (window == NULL) {
        SDL_Log("SDL_CreateWindow() failed: %s", SDL_GetError());
        return SDL_APP_FAILURE;
    }

    renderer = SDL_CreateRenderer(window, NULL);
    if (!renderer) {
        SDL_Log("SDL_CreateRenderer() failed: %s", SDL_GetError());
        return SDL_APP_FAILURE;
    }
    
    // Additional initialization...
}

Environment:

  • Operating System: Debian GNU/Linux 12 (Bookworm)
  • Kernel Version: 6.1.0-30
  • Custom Kernel Version: 6.1.124-1 (Debian customized)

Hardware:

  • Laptop:
    • CPU: 8th Gen Intel® Core™ i5-8365U @ 1.60GHz
    • GPU: Integrated Graphics
    • RAM: 16 GB

Videos:

@Kontrabant
Copy link
Contributor

SDL passes the position to XCreateWindow when initially creating the window, and will correct the window placement after the window is mapped if the window manager decides to initially position it somewhere else (Gnome on XWayland seems to ignore the initial coordinates and places the window in a default position). If the window manager isn't initially placing the window where it is told to, there is nothing SDL can do about that.

@milq
Copy link
Author

milq commented Jan 22, 2025

But then why are they different behaviors? If both are supposed to start centered, why do they behave differently? Something doesn’t add up.

@Kontrabant
Copy link
Contributor

Kontrabant commented Jan 22, 2025

SDL_CreateWindowAndRenderer creates the window in a hidden state, then creates a renderer, then shows the window. Doing it manually in your example creates the window, shows it, hides and destroys it when creating the renderer, then shows it again. Most likely the quick show->hide->show cycle in the latter case hides the initial repositioning.

If you add SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIDDEN_BOOLEAN, true) to the window properties, then call SDL_ShowWindow() after creating the renderer, does the flicker occur?

@milq
Copy link
Author

milq commented Jan 22, 2025

Yes, it works that way. But I thought the behavior of SDL_CreateWindowAndRenderer was to hide the window until the renderer was created and then show everything.

@Kontrabant
Copy link
Contributor

Hmm, it does seem that we are forcing the window position in a case where we shouldn't be in the X11 driver, as SDL_CreateWindowAndRenderer leaves the window position as "undefined". We request that it should be centered when creating the window in that case, but an undefined position means the window manager can ultimately put it where it wants, so it's being placed elsewhere first then later moved, which results in the flicker. We shouldn't be moving it to the center in that case.

In your second example, you explicitly tell it to center the window, so it's initially properly centered, resulting in no flicker.

Also, the hint in your first example, SDL_HINT_VIDEO_WINDOW_POSITION, doesn't exist, and that code won't compile.

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 a pull request may close this issue.

2 participants