SDL
SDL copied to clipboard
SDL_SetWindowResizable seemingly ignored
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;
}
Setting the window as resizeable in the flags, then disabling resizing seems to fix the issue.
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
);
These functions seem to work as expected after creating the renderer...
I think this is fixed in the latest SDL2 code, can you try the latest release?
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
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;
}
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.
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.
do as XavierCS-dev said -- call it AFTER creating the renderer
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.