|
@@ -32,6 +32,7 @@
|
|
#include "SDL_waylandvideo.h"
|
|
#include "SDL_waylandvideo.h"
|
|
#include "../../SDL_hints_c.h"
|
|
#include "../../SDL_hints_c.h"
|
|
|
|
|
|
|
|
+#include "alpha-modifier-v1-client-protocol.h"
|
|
#include "xdg-shell-client-protocol.h"
|
|
#include "xdg-shell-client-protocol.h"
|
|
#include "xdg-decoration-unstable-v1-client-protocol.h"
|
|
#include "xdg-decoration-unstable-v1-client-protocol.h"
|
|
#include "idle-inhibit-unstable-v1-client-protocol.h"
|
|
#include "idle-inhibit-unstable-v1-client-protocol.h"
|
|
@@ -279,10 +280,24 @@ static void RepositionPopup(SDL_Window *window, SDL_bool use_current_position)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void SetSurfaceOpaqueRegion(SDL_WindowData *wind, SDL_bool is_opaque)
|
|
|
|
+{
|
|
|
|
+ SDL_VideoData *viddata = wind->waylandData;
|
|
|
|
+
|
|
|
|
+ if (is_opaque) {
|
|
|
|
+ struct wl_region *region = wl_compositor_create_region(viddata->compositor);
|
|
|
|
+ wl_region_add(region, 0, 0,
|
|
|
|
+ wind->current.logical_width, wind->current.logical_height);
|
|
|
|
+ wl_surface_set_opaque_region(wind->surface, region);
|
|
|
|
+ wl_region_destroy(region);
|
|
|
|
+ } else {
|
|
|
|
+ wl_surface_set_opaque_region(wind->surface, NULL);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
static void ConfigureWindowGeometry(SDL_Window *window)
|
|
static void ConfigureWindowGeometry(SDL_Window *window)
|
|
{
|
|
{
|
|
SDL_WindowData *data = window->driverdata;
|
|
SDL_WindowData *data = window->driverdata;
|
|
- SDL_VideoData *viddata = data->waylandData;
|
|
|
|
const int old_pixel_width = data->current.pixel_width;
|
|
const int old_pixel_width = data->current.pixel_width;
|
|
const int old_pixel_height = data->current.pixel_height;
|
|
const int old_pixel_height = data->current.pixel_height;
|
|
int window_width, window_height;
|
|
int window_width, window_height;
|
|
@@ -391,20 +406,12 @@ static void ConfigureWindowGeometry(SDL_Window *window)
|
|
* need to be recalculated if the output size has changed.
|
|
* need to be recalculated if the output size has changed.
|
|
*/
|
|
*/
|
|
if (window_size_changed) {
|
|
if (window_size_changed) {
|
|
- struct wl_region *region;
|
|
|
|
-
|
|
|
|
/* libdecor does this internally on frame commits, so it's only needed for xdg surfaces. */
|
|
/* libdecor does this internally on frame commits, so it's only needed for xdg surfaces. */
|
|
if (data->shell_surface_type != WAYLAND_SURFACE_LIBDECOR && data->shell_surface.xdg.surface) {
|
|
if (data->shell_surface_type != WAYLAND_SURFACE_LIBDECOR && data->shell_surface.xdg.surface) {
|
|
xdg_surface_set_window_geometry(data->shell_surface.xdg.surface, 0, 0, data->current.logical_width, data->current.logical_height);
|
|
xdg_surface_set_window_geometry(data->shell_surface.xdg.surface, 0, 0, data->current.logical_width, data->current.logical_height);
|
|
}
|
|
}
|
|
|
|
|
|
- if (!(window->flags & SDL_WINDOW_TRANSPARENT)) {
|
|
|
|
- region = wl_compositor_create_region(viddata->compositor);
|
|
|
|
- wl_region_add(region, 0, 0,
|
|
|
|
- data->current.logical_width, data->current.logical_height);
|
|
|
|
- wl_surface_set_opaque_region(data->surface, region);
|
|
|
|
- wl_region_destroy(region);
|
|
|
|
- }
|
|
|
|
|
|
+ SetSurfaceOpaqueRegion(data, !(window->flags & SDL_WINDOW_TRANSPARENT) && window->opacity == 1.0f);
|
|
|
|
|
|
/* Ensure that child popup windows are still in bounds. */
|
|
/* Ensure that child popup windows are still in bounds. */
|
|
for (SDL_Window *child = window->first_child; child; child = child->next_sibling) {
|
|
for (SDL_Window *child = window->first_child; child; child = child->next_sibling) {
|
|
@@ -2302,6 +2309,11 @@ int Wayland_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_Propert
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (!custom_surface_role && c->wp_alpha_modifier_v1) {
|
|
|
|
+ data->wp_alpha_modifier_surface_v1 = wp_alpha_modifier_v1_get_surface(c->wp_alpha_modifier_v1, data->surface);
|
|
|
|
+ wp_alpha_modifier_surface_v1_set_multiplier(data->wp_alpha_modifier_surface_v1, SDL_MAX_UINT32);
|
|
|
|
+ }
|
|
|
|
+
|
|
/* Must be called before EGL configuration to set the drawable backbuffer size. */
|
|
/* Must be called before EGL configuration to set the drawable backbuffer size. */
|
|
ConfigureWindowGeometry(window);
|
|
ConfigureWindowGeometry(window);
|
|
|
|
|
|
@@ -2494,6 +2506,20 @@ SDL_DisplayID Wayland_GetDisplayForWindow(SDL_VideoDevice *_this, SDL_Window *wi
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+int Wayland_SetWindowOpacity(SDL_VideoDevice *_this, SDL_Window *window, float opacity)
|
|
|
|
+{
|
|
|
|
+ SDL_WindowData *wind = window->driverdata;
|
|
|
|
+
|
|
|
|
+ if (wind->wp_alpha_modifier_surface_v1) {
|
|
|
|
+ SetSurfaceOpaqueRegion(wind, !(window->flags & SDL_WINDOW_TRANSPARENT) && opacity == 1.0f);
|
|
|
|
+ wp_alpha_modifier_surface_v1_set_multiplier(wind->wp_alpha_modifier_surface_v1, (Uint32)((double)SDL_MAX_UINT32 * (double)opacity));
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return SDL_SetError("wayland: set window opacity failed; compositor lacks support for the required wp_alpha_modifier_v1 protocol");
|
|
|
|
+}
|
|
|
|
+
|
|
void Wayland_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window)
|
|
void Wayland_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window)
|
|
{
|
|
{
|
|
SDL_WindowData *wind = window->driverdata;
|
|
SDL_WindowData *wind = window->driverdata;
|
|
@@ -2614,6 +2640,10 @@ void Wayland_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
|
wp_fractional_scale_v1_destroy(wind->fractional_scale);
|
|
wp_fractional_scale_v1_destroy(wind->fractional_scale);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (wind->wp_alpha_modifier_surface_v1) {
|
|
|
|
+ wp_alpha_modifier_surface_v1_destroy(wind->wp_alpha_modifier_surface_v1);
|
|
|
|
+ }
|
|
|
|
+
|
|
SDL_free(wind->outputs);
|
|
SDL_free(wind->outputs);
|
|
SDL_free(wind->app_id);
|
|
SDL_free(wind->app_id);
|
|
|
|
|