Fixed bug 3063 - Wayland: SDL resizes EGL surface to 0x0.

x414e54

Wayland will sometimes send empty resize events (0 width and 0 height) to the client. I have not worked out the exact conditions a client would receive these but I can assume it might be if the window is offscreen or not mapped yet.

This causes issues with some SDL clients as they receive the 0x0 event and unexpected resize event or might not request to resize back to the correct size.

As per the wl_shell Wayland spec configure events are only a suggestion and the client is free to ignore or pick a different size (this is how min/max and fixed aspect ratio is supped to be implemented).

A patch is attached but is just the first iteration and I will fix any issues such as checking for FULLSCREEN/MAXIMIZED or RESIZABLE flags unless someone else fixes this first.

I have update to take into account non resizable and fullscreen windows. Also adding in maximize/restore and title functions for Wayland.
This commit is contained in:
Sam Lantinga 2016-10-07 18:11:03 -07:00
parent 62b9e1c797
commit eea76fc199
3 changed files with 64 additions and 0 deletions

View File

@ -169,7 +169,10 @@ Wayland_CreateDevice(int devindex)
device->CreateWindow = Wayland_CreateWindow; device->CreateWindow = Wayland_CreateWindow;
device->ShowWindow = Wayland_ShowWindow; device->ShowWindow = Wayland_ShowWindow;
device->SetWindowFullscreen = Wayland_SetWindowFullscreen; device->SetWindowFullscreen = Wayland_SetWindowFullscreen;
device->MaximizeWindow = Wayland_MaximizeWindow;
device->RestoreWindow = Wayland_RestoreWindow;
device->SetWindowSize = Wayland_SetWindowSize; device->SetWindowSize = Wayland_SetWindowSize;
device->SetWindowTitle = Wayland_SetWindowTitle;
device->DestroyWindow = Wayland_DestroyWindow; device->DestroyWindow = Wayland_DestroyWindow;
device->SetWindowHitTest = Wayland_SetWindowHitTest; device->SetWindowHitTest = Wayland_SetWindowHitTest;

View File

@ -47,6 +47,33 @@ handle_configure(void *data, struct wl_shell_surface *shell_surface,
SDL_Window *window = wind->sdlwindow; SDL_Window *window = wind->sdlwindow;
struct wl_region *region; struct wl_region *region;
/* wl_shell_surface spec states that this is a suggestion.
Ignore if less than or greater than max/min size. */
if (width == 0 || height == 0) {
return;
}
if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
if ((window->flags & SDL_WINDOW_RESIZABLE)) {
if (window->max_w > 0) {
width = SDL_min(width, window->max_w);
}
width = SDL_max(width, window->min_w);
if (window->max_h > 0) {
height = SDL_min(height, window->max_h);
}
height = SDL_max(height, window->min_h);
} else {
return;
}
}
if (width == window->w && height == window->h) {
return;
}
window->w = width; window->w = width;
window->h = height; window->h = height;
WAYLAND_wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0); WAYLAND_wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0);
@ -146,6 +173,26 @@ Wayland_SetWindowFullscreen(_THIS, SDL_Window * window,
WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
} }
void
Wayland_RestoreWindow(_THIS, SDL_Window * window)
{
SDL_WindowData *wind = window->driverdata;
wl_shell_surface_set_toplevel(wind->shell_surface);
WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
}
void
Wayland_MaximizeWindow(_THIS, SDL_Window * window)
{
SDL_WindowData *wind = window->driverdata;
wl_shell_surface_set_maximized(wind->shell_surface, NULL);
WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
}
int Wayland_CreateWindow(_THIS, SDL_Window *window) int Wayland_CreateWindow(_THIS, SDL_Window *window)
{ {
SDL_WindowData *data; SDL_WindowData *data;
@ -239,6 +286,17 @@ void Wayland_SetWindowSize(_THIS, SDL_Window * window)
wl_region_destroy(region); wl_region_destroy(region);
} }
void Wayland_SetWindowTitle(_THIS, SDL_Window * window)
{
SDL_WindowData *wind = window->driverdata;
if (window->title != NULL) {
wl_shell_surface_set_title(wind->shell_surface, window->title);
}
WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
}
void Wayland_DestroyWindow(_THIS, SDL_Window *window) void Wayland_DestroyWindow(_THIS, SDL_Window *window)
{ {
SDL_VideoData *data = _this->driverdata; SDL_VideoData *data = _this->driverdata;

View File

@ -50,8 +50,11 @@ extern void Wayland_ShowWindow(_THIS, SDL_Window *window);
extern void Wayland_SetWindowFullscreen(_THIS, SDL_Window * window, extern void Wayland_SetWindowFullscreen(_THIS, SDL_Window * window,
SDL_VideoDisplay * _display, SDL_VideoDisplay * _display,
SDL_bool fullscreen); SDL_bool fullscreen);
extern void Wayland_MaximizeWindow(_THIS, SDL_Window * window);
extern void Wayland_RestoreWindow(_THIS, SDL_Window * window);
extern int Wayland_CreateWindow(_THIS, SDL_Window *window); extern int Wayland_CreateWindow(_THIS, SDL_Window *window);
extern void Wayland_SetWindowSize(_THIS, SDL_Window * window); extern void Wayland_SetWindowSize(_THIS, SDL_Window * window);
extern void Wayland_SetWindowTitle(_THIS, SDL_Window * window);
extern void Wayland_DestroyWindow(_THIS, SDL_Window *window); extern void Wayland_DestroyWindow(_THIS, SDL_Window *window);
extern SDL_bool extern SDL_bool