Minimum resizeable window size?

There are some legacy posts about this, but I would like to know what is the modern solution.

I used SDL_SetWindowMinimumSize() right after creating a window with the SDL_WINDOW_RESIZABLE flag, and it did nothing. I can still resize my window to a completely unusable size (Like 1 x 1px (not including edges or the top bar)).

Should this be implemented as an event response that forcefully resizes the window back? Wouldn’t that waste a lot of cycles where you fight with your resize speed against the speed of the user resizing the window?

EDIT: SetWindowMaximumSize doesn’t work either. On Linux
EDIT2: Doesn’t work for maximize/minimize either :face_exhaling:

On Windows this function works as expected, so this problem can exists on Linux only.

No, these functions should use platform-specific functions to set minimum and maximum size of the window (if supported), so the OS can correctly control the behavior of the window. If something does not work as you expected, of course you can implement your own hack. But if you suspect that this is a bug, file an issue in SDL repository.

I wouldn’t want to bother the guys without being sure that it’s a bug. I currently can’t use a VM, so can’t test on other OSes besides mine.

I was hoping that it would be a known problem, or that my setup is wrong.

EDIT: Apparently, the window manager on Linux doesn’t have to respect X’s “hints”

Can confirm that SDL_SetWindowMinimumSize() works on macOS

Guys big update!

My program is wrong. I still don’t know what is wrong, but the test program works as intended. The resize events didn’t work, so I went to check, and then I also tested the minimum size function, and it all works fine. Should have done this first. Sorry!

#include "SDL.h"

void PrintWinEvent(const SDL_Event * event)
{
    if (event->type == SDL_WINDOWEVENT) {
        switch (event->window.event) {
        case SDL_WINDOWEVENT_SHOWN:
            SDL_Log("Window %d shown", event->window.windowID);
            break;
        case SDL_WINDOWEVENT_HIDDEN:
            SDL_Log("Window %d hidden", event->window.windowID);
            break;
        case SDL_WINDOWEVENT_EXPOSED:
            SDL_Log("Window %d exposed", event->window.windowID);
            break;
        case SDL_WINDOWEVENT_MOVED:
            SDL_Log("Window %d moved to %d,%d",
                    event->window.windowID, event->window.data1,
                    event->window.data2);
            break;
        case SDL_WINDOWEVENT_RESIZED:
            SDL_Log("Window %d resized to %dx%d",
                    event->window.windowID, event->window.data1,
                    event->window.data2);
            break;
        case SDL_WINDOWEVENT_SIZE_CHANGED:
            SDL_Log("Window %d size changed to %dx%d",
                    event->window.windowID, event->window.data1,
                    event->window.data2);
            break;
        case SDL_WINDOWEVENT_MINIMIZED:
            SDL_Log("Window %d minimized", event->window.windowID);
            break;
        case SDL_WINDOWEVENT_MAXIMIZED:
            SDL_Log("Window %d maximized", event->window.windowID);
            break;
        case SDL_WINDOWEVENT_RESTORED:
            SDL_Log("Window %d restored", event->window.windowID);
            break;
        case SDL_WINDOWEVENT_ENTER:
            SDL_Log("Mouse entered window %d",
                    event->window.windowID);
            break;
        case SDL_WINDOWEVENT_LEAVE:
            SDL_Log("Mouse left window %d", event->window.windowID);
            break;
        case SDL_WINDOWEVENT_FOCUS_GAINED:
            SDL_Log("Window %d gained keyboard focus",
                    event->window.windowID);
            break;
        case SDL_WINDOWEVENT_FOCUS_LOST:
            SDL_Log("Window %d lost keyboard focus",
                    event->window.windowID);
            break;
        case SDL_WINDOWEVENT_CLOSE:
            SDL_Log("Window %d closed", event->window.windowID);
            break;
#if SDL_VERSION_ATLEAST(2, 0, 5)
        case SDL_WINDOWEVENT_TAKE_FOCUS:
            SDL_Log("Window %d is offered a focus", event->window.windowID);
            break;
        case SDL_WINDOWEVENT_HIT_TEST:
            SDL_Log("Window %d has a special hit test", event->window.windowID);
            break;
#endif
        default:
            SDL_Log("Window %d got unknown event %d",
                    event->window.windowID, event->window.event);
            break;
        }
    }
}


int main()
{
	SDL_Init(SDL_INIT_EVERYTHING);
	SDL_Window * win = SDL_CreateWindow("title", 10, 10, 640, 480, SDL_WINDOW_RESIZABLE);
	SDL_Renderer * screen = SDL_CreateRenderer(win, -1, 0);

    SDL_SetWindowMinimumSize(win, 100, 100);

	SDL_Rect box = {0,0,32, 32};
	int run = 1;
	while(run)
	{
		SDL_Event ev;
		while(SDL_PollEvent(&ev))
		{
			switch(ev.type)
			{
				case SDL_MOUSEBUTTONDOWN:
					printf("mouse\n");
					break;
				case SDL_QUIT:
				    printf("quit\n");
					run = 0;
					break;
			}

            PrintWinEvent(&ev);
		}

		SDL_SetRenderDrawColor(screen, 50, 10, 10, 255);
		SDL_RenderClear(screen);

		SDL_SetRenderDrawColor(screen, 10, 200, 10, 255);
		SDL_RenderFillRect(screen, &box);
		SDL_RenderPresent(screen);
	}
	SDL_Quit();
}

I stole GuildedDougnout’s minimal exampel code

I don’t believe that code provided as tutorial/educational material can technically be “stolen” since it’s provided with the intent of you using it and modifying it. Thanks for the attribution, but I’m just happy it saw some use and you’ve made it your own. Just be careful not to use copy/paste if you’re in college, they play by a very strict rule-book.

I do see that you removed the wait loop from this version, just be aware that there were no other frame capping measures in place.
You might want to set the SDL_CreateRenderer flag to SDL_RENDERER_PRESENTVSYNC to get a constant frame rate. (Otherwise you will likely hear your CPU fans spin up after a minute or so of run-time).

Edit: Actually, it is possible that since there’s very little internal logic, the bottleneck of bus time to/from the GPU might act as a very light frame-rate limiter all on its own. I’m not spinning up over 12% CPU usage… Neat.

1 Like

In an older version of SDL2 I experience the same problem as you, multivita, but only if I call SDL_SetWindowMinimumSize before creating the renderer.

This bug seems to have been fixed pretty recently:

3 Likes

lol Peter I JUST found this exact error and came here to ask you guys for confirmation.

Yes, If I do it just after creating the window, but before creating the renderer, it doesn’t work.

Thanks!

1 Like