We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 5534

Summary: [Wayland] Be more explicit about min/max size for xdg-shell
Product: SDL Reporter: Ethan Lee <flibitijibibo>
Component: videoAssignee: Sam Lantinga <slouken>
Status: NEW --- QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2    
Version: HG 2.0   
Hardware: All   
OS: Linux   
Attachments: Min/Max patch for xdg-shell

Description Ethan Lee 2021-02-06 23:22:42 UTC
As of the latest SDL revision, Wayland support with compositors that support XDG-Shell is nearly at feature parity - two notable absences are window position and border sizes, which we probably won't ever get Because Wayland, but a third notable issue is that the desktop has no way of knowing what our window bounds really are. As a result, a fixed-size window will still have resize UI at the borders and a maximize button that does some really strange things to the window when you click it.

Luckily this is very easy for us to fix: Much like X11 we can explicitly set the min/max size via toplevel_set_min/max_size, and the desktop will know to avoid the resize UI (on KDE it still shows a maximize button but it thankfully does nothing, not sure if making this button disappear is something for KDE to fix or what...).

I believe the places we have to add this are identical to X11, and for the most part the logic will also be the same minus skipping a few X quirks here and there:

- CreateWindow
- SetWindowSize
- SetWindowResizable
- SetWindowFullscreen
- New SetWindowMinimum/SetWindowMaximum implementations

The callbacks should be able to stay as they are with no problems.
Comment 1 Ethan Lee 2021-02-07 06:20:03 UTC
Created attachment 4770 [details]
Min/Max patch for xdg-shell

This patch does the work to set min/max as described in the OP. Functionally it seems fine but Plasma's having trouble with it for some reason. I suspect we're just missing a message somewhere that will fix it, if you toggle the border (either via SetWindowBordered or SetWindowFullscreen) it correctly toggles the maximize button once it's been refreshed.

To make testing easier, here's a quick program... mind the uninitialized framebuffer:

--------------------------------------------------------------------------------

#include <SDL.h>

int main(int argc, char **argv)
{
	SDL_Window *window;
	SDL_GLContext context;
	SDL_Event evt;
	int w;
	Uint8 run = 1;

	SDL_Init(SDL_INIT_VIDEO);
	window = SDL_CreateWindow(
		"Shell Test",
		SDL_WINDOWPOS_CENTERED,
		SDL_WINDOWPOS_CENTERED,
		800,
		600,
		SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL
	);
	context = SDL_GL_CreateContext(window);

	while (run)
	{
		const Uint32 flags = SDL_GetWindowFlags(window);
		while (SDL_PollEvent(&evt) > 0)
		{
			if (evt.type == SDL_QUIT)
			{
				run = 0;
			}
			if (evt.type == SDL_KEYDOWN)
			{
				if (evt.key.keysym.sym == SDLK_1)
				{
					SDL_SetWindowResizable(
						window,
						(flags & SDL_WINDOW_RESIZABLE) != SDL_WINDOW_RESIZABLE
					);
				}
				else if (evt.key.keysym.sym == SDLK_2)
				{
					SDL_SetWindowBordered(
						window,
						(flags & SDL_WINDOW_BORDERLESS) == SDL_WINDOW_BORDERLESS
					);
				}
				else if (evt.key.keysym.sym == SDLK_3)
				{
					SDL_SetWindowFullscreen(
						window,
						(flags & SDL_WINDOW_FULLSCREEN_DESKTOP) ?
							0 :
							SDL_WINDOW_FULLSCREEN_DESKTOP
					);
					SDL_SetWindowSize(window, 800, 600);
					SDL_SetWindowPosition(
						window,
						SDL_WINDOWPOS_CENTERED,
						SDL_WINDOWPOS_CENTERED
					);
				}
				else if (evt.key.keysym.sym == SDLK_4)
				{
					SDL_GetWindowMinimumSize(window, &w, NULL);
					if (w < 2)
					{
						SDL_SetWindowMinimumSize(window, 600, 400);
						SDL_SetWindowMaximumSize(window, 1000, 800);
					}
					else
					{
						SDL_SetWindowMinimumSize(window, 1, 1);
						SDL_SetWindowMaximumSize(window, 0x7FFFFFFF, 0x7FFFFFFF);
					}
				}
				else if (evt.key.keysym.sym == SDLK_5)
				{
					SDL_SetWindowSize(window, 800, 600);
					SDL_SetWindowPosition(
						window,
						SDL_WINDOWPOS_CENTERED,
						SDL_WINDOWPOS_CENTERED
					);
				}
			}
		}
		SDL_GL_SwapWindow(window);
	}

	SDL_GL_DeleteContext(context);
	SDL_DestroyWindow(window);
	SDL_Quit();
	return 0;
}

--------------------------------------------------------------------------------