From 19236b462a8af09670c9fd5490cea293d3fc2b75 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 21 Jan 2021 21:49:13 -0600 Subject: [PATCH] Implement support for minimizing windows on Wayland This required a bit of extra code to deal with the transition from minimized back to fullscreen --- src/video/wayland/SDL_waylandvideo.c | 1 + src/video/wayland/SDL_waylandwindow.c | 93 +++++++++++++++++---------- src/video/wayland/SDL_waylandwindow.h | 1 + 3 files changed, 62 insertions(+), 33 deletions(-) diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index 73f181a1f..e5be532cf 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -197,6 +197,7 @@ Wayland_CreateDevice(int devindex) device->ShowWindow = Wayland_ShowWindow; device->SetWindowFullscreen = Wayland_SetWindowFullscreen; device->MaximizeWindow = Wayland_MaximizeWindow; + device->MinimizeWindow = Wayland_MinimizeWindow; device->SetWindowGrab = Wayland_SetWindowGrab; device->RestoreWindow = Wayland_RestoreWindow; device->SetWindowBordered = Wayland_SetWindowBordered; diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index 89fb40328..cba97fd48 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -42,6 +42,37 @@ static float get_window_scale_factor(SDL_Window *window) { return ((SDL_WindowData*)window->driverdata)->scale_factor; } +static void +SetFullscreen(SDL_Window *window, struct wl_output *output) +{ + SDL_WindowData *wind = window->driverdata; + SDL_VideoData *viddata = wind->waylandData; + + if (viddata->shell.xdg) { + if (output) { + xdg_toplevel_set_fullscreen(wind->shell_surface.xdg.roleobj.toplevel, output); + } else { + xdg_toplevel_unset_fullscreen(wind->shell_surface.xdg.roleobj.toplevel); + } + } else if (viddata->shell.zxdg) { + if (output) { + zxdg_toplevel_v6_set_fullscreen(wind->shell_surface.zxdg.roleobj.toplevel, output); + } else { + zxdg_toplevel_v6_unset_fullscreen(wind->shell_surface.zxdg.roleobj.toplevel); + } + } else { + if (output) { + wl_shell_surface_set_fullscreen(wind->shell_surface.wl, + WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, + 0, output); + } else { + wl_shell_surface_set_toplevel(wind->shell_surface.wl); + } + } + + WAYLAND_wl_display_flush(viddata->display); +} + /* On modern desktops, we probably will use the xdg-shell protocol instead of wl_shell, but wl_shell might be useful on older Wayland installs that don't have the newer protocol, or embedded things that don't have a full @@ -168,6 +199,12 @@ handle_configure_zxdg_toplevel(void *data, } if (!fullscreen) { + if (window->flags & SDL_WINDOW_FULLSCREEN) { + /* We might need to re-enter fullscreen after being restored from minimized */ + struct wl_output *output = (struct wl_output *) window->fullscreen_mode.driverdata; + SetFullscreen(window, output); + } + if (width == 0 || height == 0) { width = window->windowed.w; height = window->windowed.h; @@ -278,6 +315,12 @@ handle_configure_xdg_toplevel(void *data, } if (!fullscreen) { + if (window->flags & SDL_WINDOW_FULLSCREEN) { + /* We might need to re-enter fullscreen after being restored from minimized */ + struct wl_output *output = (struct wl_output *) window->fullscreen_mode.driverdata; + SetFullscreen(window, output); + } + if (width == 0 || height == 0) { width = window->windowed.w; height = window->windowed.h; @@ -474,41 +517,10 @@ Wayland_SetWindowHitTest(SDL_Window *window, SDL_bool enabled) return 0; /* just succeed, the real work is done elsewhere. */ } -static void -SetFullscreen(_THIS, SDL_Window * window, struct wl_output *output) -{ - const SDL_VideoData *viddata = (const SDL_VideoData *) _this->driverdata; - SDL_WindowData *wind = window->driverdata; - - if (viddata->shell.xdg) { - if (output) { - xdg_toplevel_set_fullscreen(wind->shell_surface.xdg.roleobj.toplevel, output); - } else { - xdg_toplevel_unset_fullscreen(wind->shell_surface.xdg.roleobj.toplevel); - } - } else if (viddata->shell.zxdg) { - if (output) { - zxdg_toplevel_v6_set_fullscreen(wind->shell_surface.zxdg.roleobj.toplevel, output); - } else { - zxdg_toplevel_v6_unset_fullscreen(wind->shell_surface.zxdg.roleobj.toplevel); - } - } else { - if (output) { - wl_shell_surface_set_fullscreen(wind->shell_surface.wl, - WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, - 0, output); - } else { - wl_shell_surface_set_toplevel(wind->shell_surface.wl); - } - } - - WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); -} - void Wayland_ShowWindow(_THIS, SDL_Window *window) { struct wl_output *output = (struct wl_output *) window->fullscreen_mode.driverdata; - SetFullscreen(_this, window, (window->flags & SDL_WINDOW_FULLSCREEN) ? output : NULL); + SetFullscreen(window, (window->flags & SDL_WINDOW_FULLSCREEN) ? output : NULL); } #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH @@ -582,7 +594,7 @@ Wayland_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen) { struct wl_output *output = ((SDL_WaylandOutputData*) _display->driverdata)->output; - SetFullscreen(_this, window, fullscreen ? output : NULL); + SetFullscreen(window, fullscreen ? output : NULL); } void @@ -631,6 +643,21 @@ Wayland_MaximizeWindow(_THIS, SDL_Window * window) WAYLAND_wl_display_flush( viddata->display ); } +void +Wayland_MinimizeWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *wind = window->driverdata; + SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; + + if (viddata->shell.xdg) { + xdg_toplevel_set_minimized(wind->shell_surface.xdg.roleobj.toplevel); + } else if (viddata->shell.zxdg) { + zxdg_toplevel_v6_set_minimized(wind->shell_surface.zxdg.roleobj.toplevel); + } + + WAYLAND_wl_display_flush(viddata->display); +} + void Wayland_SetWindowGrab(_THIS, SDL_Window *window, SDL_bool grabbed) { diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h index 6e3306255..4a7472ccc 100644 --- a/src/video/wayland/SDL_waylandwindow.h +++ b/src/video/wayland/SDL_waylandwindow.h @@ -89,6 +89,7 @@ extern void Wayland_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen); extern void Wayland_MaximizeWindow(_THIS, SDL_Window * window); +extern void Wayland_MinimizeWindow(_THIS, SDL_Window * window); extern void Wayland_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); extern void Wayland_RestoreWindow(_THIS, SDL_Window * window); extern void Wayland_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered);