wayland: Explicitly set min/max size for xdg-shell

This commit is contained in:
Ethan Lee 2021-02-12 14:27:58 -05:00 committed by Sam Lantinga
parent 33598563b3
commit 57a927e8d7
3 changed files with 110 additions and 5 deletions

View File

@ -206,6 +206,8 @@ Wayland_CreateDevice(int devindex)
device->SetWindowBordered = Wayland_SetWindowBordered; device->SetWindowBordered = Wayland_SetWindowBordered;
device->SetWindowResizable = Wayland_SetWindowResizable; device->SetWindowResizable = Wayland_SetWindowResizable;
device->SetWindowSize = Wayland_SetWindowSize; device->SetWindowSize = Wayland_SetWindowSize;
device->SetWindowMinimumSize = Wayland_SetWindowMinimumSize;
device->SetWindowMaximumSize = Wayland_SetWindowMaximumSize;
device->SetWindowTitle = Wayland_SetWindowTitle; device->SetWindowTitle = Wayland_SetWindowTitle;
device->DestroyWindow = Wayland_DestroyWindow; device->DestroyWindow = Wayland_DestroyWindow;
device->SetWindowHitTest = Wayland_SetWindowHitTest; device->SetWindowHitTest = Wayland_SetWindowHitTest;

View File

@ -634,11 +634,40 @@ Wayland_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
void void
Wayland_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable) Wayland_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable)
{ {
/* No-op, this is handled by the xdg-shell/wl_shell callbacks. int min_width, min_height, max_width, max_height;
* Also note that we do NOT implement SetMaximumSize/SetMinimumSize, as SDL_VideoData *data = _this->driverdata;
* those are also no-ops for the same reason, but SDL_video.c does not SDL_WindowData *wind = window->driverdata;
* require a driver implementation.
*/ if (resizable) {
/* FIXME: Is there a better way to get max window size from Wayland? -flibit */
const int maxsize = 0x7FFFFFFF;
min_width = window->min_w;
min_height = window->min_h;
max_width = (window->max_w == 0) ? maxsize : window->max_w;
max_height = (window->max_h == 0) ? maxsize : window->max_h;
} else {
min_width = window->w;
min_height = window->h;
max_width = window->w;
max_height = window->h;
}
/* Note that this is also handled by the xdg-shell/wl_shell callbacks! */
if (data->shell.xdg) {
xdg_toplevel_set_min_size(wind->shell_surface.xdg.roleobj.toplevel,
min_width,
min_height);
xdg_toplevel_set_max_size(wind->shell_surface.xdg.roleobj.toplevel,
max_width,
max_height);
} else if (data->shell.zxdg) {
zxdg_toplevel_v6_set_min_size(wind->shell_surface.zxdg.roleobj.toplevel,
min_width,
min_height);
zxdg_toplevel_v6_set_max_size(wind->shell_surface.zxdg.roleobj.toplevel,
max_width,
max_height);
}
} }
void void
@ -757,12 +786,28 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window)
data->shell_surface.xdg.roleobj.toplevel = xdg_surface_get_toplevel(data->shell_surface.xdg.surface); data->shell_surface.xdg.roleobj.toplevel = xdg_surface_get_toplevel(data->shell_surface.xdg.surface);
xdg_toplevel_add_listener(data->shell_surface.xdg.roleobj.toplevel, &toplevel_listener_xdg, data); xdg_toplevel_add_listener(data->shell_surface.xdg.roleobj.toplevel, &toplevel_listener_xdg, data);
xdg_toplevel_set_app_id(data->shell_surface.xdg.roleobj.toplevel, c->classname); xdg_toplevel_set_app_id(data->shell_surface.xdg.roleobj.toplevel, c->classname);
if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
xdg_toplevel_set_min_size(data->shell_surface.xdg.roleobj.toplevel,
window->w,
window->h);
xdg_toplevel_set_max_size(data->shell_surface.xdg.roleobj.toplevel,
window->w,
window->h);
}
} else if (c->shell.zxdg) { } else if (c->shell.zxdg) {
data->shell_surface.zxdg.surface = zxdg_shell_v6_get_xdg_surface(c->shell.zxdg, data->surface); data->shell_surface.zxdg.surface = zxdg_shell_v6_get_xdg_surface(c->shell.zxdg, data->surface);
/* !!! FIXME: add popup role */ /* !!! FIXME: add popup role */
data->shell_surface.zxdg.roleobj.toplevel = zxdg_surface_v6_get_toplevel(data->shell_surface.zxdg.surface); data->shell_surface.zxdg.roleobj.toplevel = zxdg_surface_v6_get_toplevel(data->shell_surface.zxdg.surface);
zxdg_toplevel_v6_add_listener(data->shell_surface.zxdg.roleobj.toplevel, &toplevel_listener_zxdg, data); zxdg_toplevel_v6_add_listener(data->shell_surface.zxdg.roleobj.toplevel, &toplevel_listener_zxdg, data);
zxdg_toplevel_v6_set_app_id(data->shell_surface.zxdg.roleobj.toplevel, c->classname); zxdg_toplevel_v6_set_app_id(data->shell_surface.zxdg.roleobj.toplevel, c->classname);
if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
zxdg_toplevel_v6_set_min_size(data->shell_surface.zxdg.roleobj.toplevel,
window->w,
window->h);
zxdg_toplevel_v6_set_max_size(data->shell_surface.zxdg.roleobj.toplevel,
window->w,
window->h);
}
} else { } else {
data->shell_surface.wl = wl_shell_get_shell_surface(c->shell.wl, data->surface); data->shell_surface.wl = wl_shell_get_shell_surface(c->shell.wl, data->surface);
wl_shell_surface_set_class(data->shell_surface.wl, c->classname); wl_shell_surface_set_class(data->shell_surface.wl, c->classname);
@ -906,12 +951,68 @@ Wayland_HandlePendingResize(SDL_Window *window)
} }
} }
void
Wayland_SetWindowMinimumSize(_THIS, SDL_Window * window)
{
SDL_VideoData *data = _this->driverdata;
SDL_WindowData *wind = window->driverdata;
if (window->flags & SDL_WINDOW_RESIZABLE) {
if (data->shell.xdg) {
xdg_toplevel_set_min_size(wind->shell_surface.xdg.roleobj.toplevel,
window->min_w,
window->min_h);
} else if (data->shell.zxdg) {
zxdg_toplevel_v6_set_min_size(wind->shell_surface.zxdg.roleobj.toplevel,
window->min_w,
window->min_h);
}
}
}
void
Wayland_SetWindowMaximumSize(_THIS, SDL_Window * window)
{
SDL_VideoData *data = _this->driverdata;
SDL_WindowData *wind = window->driverdata;
if (window->flags & SDL_WINDOW_RESIZABLE) {
if (data->shell.xdg) {
xdg_toplevel_set_max_size(wind->shell_surface.xdg.roleobj.toplevel,
window->max_w,
window->max_h);
} else if (data->shell.zxdg) {
zxdg_toplevel_v6_set_max_size(wind->shell_surface.zxdg.roleobj.toplevel,
window->max_w,
window->max_h);
}
}
}
void Wayland_SetWindowSize(_THIS, SDL_Window * window) void Wayland_SetWindowSize(_THIS, SDL_Window * window)
{ {
SDL_VideoData *data = _this->driverdata; SDL_VideoData *data = _this->driverdata;
SDL_WindowData *wind = window->driverdata; SDL_WindowData *wind = window->driverdata;
struct wl_region *region; struct wl_region *region;
if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
if (data->shell.xdg) {
xdg_toplevel_set_min_size(wind->shell_surface.xdg.roleobj.toplevel,
window->w,
window->h);
xdg_toplevel_set_max_size(wind->shell_surface.xdg.roleobj.toplevel,
window->w,
window->h);
} else if (data->shell.zxdg) {
zxdg_toplevel_v6_set_min_size(wind->shell_surface.zxdg.roleobj.toplevel,
window->w,
window->h);
zxdg_toplevel_v6_set_max_size(wind->shell_surface.zxdg.roleobj.toplevel,
window->w,
window->h);
}
}
wl_surface_set_buffer_scale(wind->surface, get_window_scale_factor(window)); wl_surface_set_buffer_scale(wind->surface, get_window_scale_factor(window));
if (wind->egl_window) { if (wind->egl_window) {

View File

@ -98,6 +98,8 @@ extern void Wayland_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool borde
extern void Wayland_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable); extern void Wayland_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable);
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_SetWindowMinimumSize(_THIS, SDL_Window * window);
extern void Wayland_SetWindowMaximumSize(_THIS, SDL_Window * window);
extern void Wayland_SetWindowTitle(_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 void Wayland_SuspendScreenSaver(_THIS); extern void Wayland_SuspendScreenSaver(_THIS);