wayland: Set/unset the opaque regions on surfaces when transparency is toggled Caches the SDL_HINT_VIDEO_EGL_ALLOW_TRANSPARENCY hint at init time and registers a callback, which is fired when the hint is changed during runtime and toggles the opaque region for existing surfaces.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c
index b9b1ce2..2a54d28 100644
--- a/src/video/wayland/SDL_waylandvideo.c
+++ b/src/video/wayland/SDL_waylandvideo.c
@@ -992,6 +992,7 @@ Wayland_VideoInit(_THIS)
WAYLAND_wl_display_flush(data->display);
Wayland_InitKeyboard(_this);
+ Wayland_InitWin(data);
data->initializing = SDL_FALSE;
@@ -1033,6 +1034,7 @@ Wayland_VideoQuit(_THIS)
SDL_VideoData *data = _this->driverdata;
int i, j;
+ Wayland_QuitWin(data);
Wayland_FiniMouse(data);
for (i = 0; i < _this->num_displays; ++i) {
diff --git a/src/video/wayland/SDL_waylandvideo.h b/src/video/wayland/SDL_waylandvideo.h
index 3e7b363..e1825cb 100644
--- a/src/video/wayland/SDL_waylandvideo.h
+++ b/src/video/wayland/SDL_waylandvideo.h
@@ -95,6 +95,7 @@ typedef struct {
char *classname;
int relative_mouse_mode;
+ SDL_bool egl_transparency_enabled;
} SDL_VideoData;
struct SDL_WaylandOutputData {
diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c
index a4e9f59..f949c20 100644
--- a/src/video/wayland/SDL_waylandwindow.c
+++ b/src/video/wayland/SDL_waylandwindow.c
@@ -32,6 +32,7 @@
#include "SDL_waylandvideo.h"
#include "SDL_waylandtouch.h"
#include "SDL_hints.h"
+#include "../../SDL_hints_c.h"
#include "SDL_events.h"
#include "xdg-shell-client-protocol.h"
@@ -47,12 +48,6 @@
#define FULLSCREEN_MASK (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_FULLSCREEN_DESKTOP)
SDL_FORCE_INLINE SDL_bool
-EGLTransparencyEnabled()
-{
- return SDL_GetHintBoolean(SDL_HINT_VIDEO_EGL_ALLOW_TRANSPARENCY, SDL_FALSE);
-}
-
-SDL_FORCE_INLINE SDL_bool
FloatEqual(float a, float b)
{
const float diff = SDL_fabsf(a - b);
@@ -296,7 +291,7 @@ ConfigureWindowGeometry(SDL_Window *window)
* if the output size has changed.
*/
if (window_size_changed) {
- if (!EGLTransparencyEnabled()) {
+ if (!viddata->egl_transparency_enabled) {
region = wl_compositor_create_region(viddata->compositor);
wl_region_add(region, 0, 0,
data->window_width, data->window_height);
@@ -2310,6 +2305,48 @@ void Wayland_DestroyWindow(_THIS, SDL_Window *window)
window->driverdata = NULL;
}
+static void
+EGLTransparencyChangedCallback(void *userdata, const char *name, const char *oldValue, const char *newValue)
+{
+ const SDL_bool oldval = SDL_GetStringBoolean(oldValue, SDL_FALSE);
+ const SDL_bool newval = SDL_GetStringBoolean(newValue, SDL_FALSE);
+
+ if (oldval != newval) {
+ SDL_Window *window;
+ SDL_VideoData *viddata = (SDL_VideoData *) userdata;
+ SDL_VideoDevice *dev = SDL_GetVideoDevice();
+
+ viddata->egl_transparency_enabled = newval;
+
+ /* Iterate over all windows and update the surface opaque regions */
+ for (window = dev->windows; window != NULL; window = window->next) {
+ SDL_WindowData *wind = (SDL_WindowData *) window->driverdata;
+
+ if (!newval) {
+ struct wl_region *region = wl_compositor_create_region(wind->waylandData->compositor);
+ wl_region_add(region, 0, 0, wind->window_width, wind->window_height);
+ wl_surface_set_opaque_region(wind->surface, region);
+ wl_region_destroy(region);
+ } else {
+ wl_surface_set_opaque_region(wind->surface, NULL);
+ }
+ }
+ }
+}
+
+void
+Wayland_InitWin(SDL_VideoData *data)
+{
+ data->egl_transparency_enabled = SDL_GetHintBoolean(SDL_HINT_VIDEO_EGL_ALLOW_TRANSPARENCY, SDL_FALSE);
+ SDL_AddHintCallback(SDL_HINT_VIDEO_EGL_ALLOW_TRANSPARENCY, EGLTransparencyChangedCallback, data);
+}
+
+void
+Wayland_QuitWin(SDL_VideoData *data)
+{
+ SDL_DelHintCallback(SDL_HINT_VIDEO_EGL_ALLOW_TRANSPARENCY, EGLTransparencyChangedCallback, data);
+}
+
#endif /* SDL_VIDEO_DRIVER_WAYLAND */
/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h
index a14ba13..87d10eb 100644
--- a/src/video/wayland/SDL_waylandwindow.h
+++ b/src/video/wayland/SDL_waylandwindow.h
@@ -142,6 +142,9 @@ Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info);
extern int Wayland_SetWindowHitTest(SDL_Window *window, SDL_bool enabled);
extern int Wayland_FlashWindow(_THIS, SDL_Window * window, SDL_FlashOperation operation);
+extern void Wayland_InitWin(SDL_VideoData *data);
+extern void Wayland_QuitWin(SDL_VideoData *data);
+
#endif /* SDL_waylandwindow_h_ */
/* vi: set ts=4 sw=4 expandtab: */