SDL: wayland: Implement SetWindowModalFor

From fcbfe33ce506d5a7449c813372306d674eed7bb0 Mon Sep 17 00:00:00 2001
From: Ethan Lee <[EMAIL REDACTED]>
Date: Sun, 18 Apr 2021 09:45:22 -0400
Subject: [PATCH] wayland: Implement SetWindowModalFor

---
 src/video/wayland/SDL_waylandvideo.c  |  1 +
 src/video/wayland/SDL_waylandwindow.c | 21 +++++++++++++++++++++
 src/video/wayland/SDL_waylandwindow.h |  1 +
 3 files changed, 23 insertions(+)

diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c
index 615506229..381224529 100644
--- a/src/video/wayland/SDL_waylandvideo.c
+++ b/src/video/wayland/SDL_waylandvideo.c
@@ -205,6 +205,7 @@ Wayland_CreateDevice(int devindex)
     device->SetWindowSize = Wayland_SetWindowSize;
     device->SetWindowMinimumSize = Wayland_SetWindowMinimumSize;
     device->SetWindowMaximumSize = Wayland_SetWindowMaximumSize;
+    device->SetWindowModalFor = Wayland_SetWindowModalFor;
     device->SetWindowTitle = Wayland_SetWindowTitle;
     device->DestroyWindow = Wayland_DestroyWindow;
     device->SetWindowHitTest = Wayland_SetWindowHitTest;
diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c
index 54226981f..9a810479e 100644
--- a/src/video/wayland/SDL_waylandwindow.c
+++ b/src/video/wayland/SDL_waylandwindow.c
@@ -595,6 +595,27 @@ Wayland_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
     return 0;  /* just succeed, the real work is done elsewhere. */
 }
 
+int
+Wayland_SetWindowModalFor(_THIS, SDL_Window *modal_window, SDL_Window *parent_window)
+{
+    const SDL_VideoData *viddata = (const SDL_VideoData *) _this->driverdata;
+    SDL_WindowData *modal_data = modal_window->driverdata;
+    SDL_WindowData *parent_data = parent_window->driverdata;
+
+    if (viddata->shell.xdg) {
+        xdg_toplevel_set_parent(modal_data->shell_surface.xdg.roleobj.toplevel,
+                                parent_data->shell_surface.xdg.roleobj.toplevel);
+    } else if (viddata->shell.zxdg) {
+        zxdg_toplevel_v6_set_parent(modal_data->shell_surface.zxdg.roleobj.toplevel,
+                                    parent_data->shell_surface.zxdg.roleobj.toplevel);
+    } else {
+        return SDL_Unsupported();
+    }
+
+    WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
+    return 0;
+}
+
 void Wayland_ShowWindow(_THIS, SDL_Window *window)
 {
     SDL_WaylandOutputData *driverdata = (SDL_WaylandOutputData *) SDL_GetDisplayForWindow(window)->driverdata;
diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h
index 892be167a..a4c990257 100644
--- a/src/video/wayland/SDL_waylandwindow.h
+++ b/src/video/wayland/SDL_waylandwindow.h
@@ -99,6 +99,7 @@ extern int Wayland_CreateWindow(_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 int Wayland_SetWindowModalFor(_THIS, SDL_Window * modal_window, SDL_Window * parent_window);
 extern void Wayland_SetWindowTitle(_THIS, SDL_Window * window);
 extern void Wayland_DestroyWindow(_THIS, SDL_Window *window);
 extern void Wayland_SuspendScreenSaver(_THIS);