SDL icon indicating copy to clipboard operation
SDL copied to clipboard

SDL_SetWindowResizable seemingly ignored

Open XavierCS-dev opened this issue 10 months ago • 9 comments

OS: Fedora 39 Compositor: wl-roots (Hyprland) SDL version: 2.28.5 (from dnf package manager)

When setting SDL_SetWindowResizable(window, SDL_FALSE); The window should become no longer resizeable. This usually results in a floating window, as is the behaviour with winit. However this is not the case with SDL, the window can still be freely resized.

Here is the full code

#include <SDL2/SDL.h>
#include <SDL2/SDL_events.h>
#include <SDL2/SDL_video.h>

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

  SDL_Window *window = SDL_CreateWindow(
    "SDL2Test",
    SDL_WINDOWPOS_UNDEFINED,
    SDL_WINDOWPOS_UNDEFINED,
    640,
    480,
    0
  );

  SDL_SetWindowResizable(window, SDL_FALSE);

  SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE);
  SDL_Event event;
  int game_state = 1;
  while (game_state) {
    while (SDL_PollEvent(&event)) {
      SDL_SetRenderDrawColor(renderer, 255, 0, 0, SDL_ALPHA_OPAQUE);
      SDL_RenderClear(renderer);
      SDL_RenderPresent(renderer);
      int width;
      int height;
      SDL_GetWindowSize(window, &width, &height);
      printf("%d %d\n", width, height);
      switch (event.type) {
        case SDL_QUIT:
          game_state = 0;
          break;
        default:
          break;
      }
    }
  }

  SDL_DestroyWindow(window);
  SDL_Quit();

  return 0;
}

XavierCS-dev avatar Apr 29 '24 19:04 XavierCS-dev

Setting the window as resizeable in the flags, then disabling resizing seems to fix the issue.

XavierCS-dev avatar Apr 29 '24 19:04 XavierCS-dev

It seems setting any other flags along with RESIZEABLE also breaks the resizing

SDL_SetWindowResizable works:

  SDL_Window *window = SDL_CreateWindow(
    "SDL2Test",
    SDL_WINDOWPOS_UNDEFINED,
    SDL_WINDOWPOS_UNDEFINED,
    640,
    480,
    SDL_WINDOW_RESIZABLE
  );

SDL_SetWindowResizable doesn't work:

  SDL_Window *window = SDL_CreateWindow(
    "SDL2Test",
    SDL_WINDOWPOS_UNDEFINED,
    SDL_WINDOWPOS_UNDEFINED,
    640,
    480,
    SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE
  );

XavierCS-dev avatar Apr 29 '24 19:04 XavierCS-dev

These functions seem to work as expected after creating the renderer...

XavierCS-dev avatar Apr 29 '24 19:04 XavierCS-dev

I think this is fixed in the latest SDL2 code, can you try the latest release?

slouken avatar Apr 29 '24 20:04 slouken

I'm not seeing this on GNOME or KDE; the window in your sample is non-resizable in both X11 and Wayland.

Seems like Hyprland had a bug that allowed non-resizable windows to be resized that was fixed not too long ago: https://github.com/hyprwm/Hyprland/issues/4920

Kontrabant avatar Apr 29 '24 23:04 Kontrabant

Not sure, if this helps with the issue, but I noticed that rendering in the code example is inside the event-polling loop:

while (game_state) { // game loop start
    while (SDL_PollEvent(&event)) { // event polling start

        // rendering is here <------------

        switch (event.type) {
            // event handling
        }
    } // event polling end
} // game loop end

Can reordering it maybe help?:

while (game_state) { // game loop start
    while (SDL_PollEvent(&event)) { // event polling start
        switch (event.type) {
            // event handling
        }
    } // event polling end

    // rendering is here now <----------

} // game loop end

I'm not that familiar with Wayland and Hyprland and how everything works there. Just wanted to give my 2 cents :)

Edit: Here is the reordered code for easy copy and pasting:

#include <SDL2/SDL.h>
#include <SDL2/SDL_events.h>
#include <SDL2/SDL_video.h>

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

  SDL_Window *window = SDL_CreateWindow(
    "SDL2Test",
    SDL_WINDOWPOS_UNDEFINED,
    SDL_WINDOWPOS_UNDEFINED,
    640,
    480,
    0
  );

  SDL_SetWindowResizable(window, SDL_FALSE);

  SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE);
  
  SDL_Event event;
  int game_state = 1;
  while (game_state) {

    while (SDL_PollEvent(&event)) {
      switch (event.type) {
        case SDL_QUIT:
          game_state = 0;
          break;
        default:
          break;
      }
    }
    
    SDL_SetRenderDrawColor(renderer, 255, 0, 0, SDL_ALPHA_OPAQUE);
    SDL_RenderClear(renderer);
    SDL_RenderPresent(renderer);
    int width;
    int height;
    SDL_GetWindowSize(window, &width, &height);
    printf("%d %d\n", width, height);
  }

  SDL_DestroyWindow(window);
  SDL_Quit();

  return 0;
}

Sackzement avatar Apr 30 '24 00:04 Sackzement

I'm not seeing this on GNOME or KDE; the window in your sample is non-resizable in both X11 and Wayland.

Seems like Hyprland had a bug that allowed non-resizable windows to be resized that was fixed not too long ago: hyprwm/Hyprland#4920

It may be a combination of what you mentioned as well as what @slouken mentioned. I am not sure though, I guess I will have to wait for newer packages with Fedora, for now, locking the window size after the renderer is created seems to work, I am not sure how it will behave when using SDL with Vulkan though, will need to test it when I have time.

XavierCS-dev avatar Apr 30 '24 06:04 XavierCS-dev

Not sure, if this helps with the issue, but I noticed that rendering in the code example is inside the event-polling loop:

while (game_state) { // game loop start
    while (SDL_PollEvent(&event)) { // event polling start

        // rendering is here <------------

        switch (event.type) {
            // event handling
        }
    } // event polling end
} // game loop end

Can reordering it maybe help?:

while (game_state) { // game loop start
    while (SDL_PollEvent(&event)) { // event polling start
        switch (event.type) {
            // event handling
        }
    } // event polling end

    // rendering is here now <----------

} // game loop end

I'm not that familiar with Wayland and Hyprland and how everything works there. Just wanted to give my 2 cents :)

Edit: Here is the reordered code for easy copy and pasting:

#include <SDL2/SDL.h>
#include <SDL2/SDL_events.h>
#include <SDL2/SDL_video.h>

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

  SDL_Window *window = SDL_CreateWindow(
    "SDL2Test",
    SDL_WINDOWPOS_UNDEFINED,
    SDL_WINDOWPOS_UNDEFINED,
    640,
    480,
    0
  );

  SDL_SetWindowResizable(window, SDL_FALSE);

  SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE);
  
  SDL_Event event;
  int game_state = 1;
  while (game_state) {

    while (SDL_PollEvent(&event)) {
      switch (event.type) {
        case SDL_QUIT:
          game_state = 0;
          break;
        default:
          break;
      }
    }
    
    SDL_SetRenderDrawColor(renderer, 255, 0, 0, SDL_ALPHA_OPAQUE);
    SDL_RenderClear(renderer);
    SDL_RenderPresent(renderer);
    int width;
    int height;
    SDL_GetWindowSize(window, &width, &height);
    printf("%d %d\n", width, height);
  }

  SDL_DestroyWindow(window);
  SDL_Quit();

  return 0;
}

Hi, It doesn't affect the window sizing, but thanks for pointing it out! I had realised what I had done when MangoHUD was reporting 0 FPS apart from when I moved my mouse. I appreciate the easy copy pasting for testing.

XavierCS-dev avatar Apr 30 '24 06:04 XavierCS-dev

do as XavierCS-dev said -- call it AFTER creating the renderer

jamesl-github avatar May 09 '24 01:05 jamesl-github

Since we believe this bug is fixed upstream, I'm going to go ahead and close this for now. Please reopen if you find it's an issue with SDL.

slouken avatar May 23 '24 16:05 slouken