Initial commit
This commit is contained in:
@@ -0,0 +1,288 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Matti=20Lehtim=C3=A4ki?= <matti.lehtimaki@jolla.com>
|
||||
Date: Wed, 20 Apr 2022 18:03:42 +0300
|
||||
Subject: [PATCH] wayland: Bring back wl_shell support
|
||||
|
||||
---
|
||||
include/SDL_syswm.h | 2 +-
|
||||
src/video/wayland/SDL_waylanddyn.h | 2 +
|
||||
src/video/wayland/SDL_waylandevents.c | 8 +++
|
||||
src/video/wayland/SDL_waylandsym.h | 2 +
|
||||
src/video/wayland/SDL_waylandvideo.c | 7 ++
|
||||
src/video/wayland/SDL_waylandvideo.h | 1 +
|
||||
src/video/wayland/SDL_waylandwindow.c | 95 +++++++++++++++++++++++++++
|
||||
src/video/wayland/SDL_waylandwindow.h | 1 +
|
||||
8 files changed, 117 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/include/SDL_syswm.h b/include/SDL_syswm.h
|
||||
index 7b8bd6ef996571bbba2e5f1e139a0c9292c88146..671a26ee945bdac99de9f07b57aef9cc893f4cec 100644
|
||||
--- a/include/SDL_syswm.h
|
||||
+++ b/include/SDL_syswm.h
|
||||
@@ -294,7 +294,7 @@ struct SDL_SysWMinfo
|
||||
{
|
||||
struct wl_display *display; /**< Wayland display */
|
||||
struct wl_surface *surface; /**< Wayland surface */
|
||||
- void *shell_surface; /**< DEPRECATED Wayland shell_surface (window manager handle) */
|
||||
+ struct wl_shell_surface *shell_surface; /**< DEPRECATED Wayland shell_surface (window manager handle) */
|
||||
struct wl_egl_window *egl_window; /**< Wayland EGL window (native window) */
|
||||
struct xdg_surface *xdg_surface; /**< Wayland xdg surface (window manager handle) */
|
||||
struct xdg_toplevel *xdg_toplevel; /**< Wayland xdg toplevel role */
|
||||
diff --git a/src/video/wayland/SDL_waylanddyn.h b/src/video/wayland/SDL_waylanddyn.h
|
||||
index 6feb343912b15a6a9360a11b66a08c0c4e36f882..2c93149cd2dcbff5a69c20606c028aa13905dced 100644
|
||||
--- a/src/video/wayland/SDL_waylanddyn.h
|
||||
+++ b/src/video/wayland/SDL_waylanddyn.h
|
||||
@@ -111,11 +111,13 @@ void SDL_WAYLAND_UnloadSymbols(void);
|
||||
#define wl_shm_pool_interface (*WAYLAND_wl_shm_pool_interface)
|
||||
#define wl_buffer_interface (*WAYLAND_wl_buffer_interface)
|
||||
#define wl_registry_interface (*WAYLAND_wl_registry_interface)
|
||||
+#define wl_shell_surface_interface (*WAYLAND_wl_shell_surface_interface)
|
||||
#define wl_region_interface (*WAYLAND_wl_region_interface)
|
||||
#define wl_pointer_interface (*WAYLAND_wl_pointer_interface)
|
||||
#define wl_keyboard_interface (*WAYLAND_wl_keyboard_interface)
|
||||
#define wl_compositor_interface (*WAYLAND_wl_compositor_interface)
|
||||
#define wl_output_interface (*WAYLAND_wl_output_interface)
|
||||
+#define wl_shell_interface (*WAYLAND_wl_shell_interface)
|
||||
#define wl_shm_interface (*WAYLAND_wl_shm_interface)
|
||||
#define wl_data_device_interface (*WAYLAND_wl_data_device_interface)
|
||||
#define wl_data_offer_interface (*WAYLAND_wl_data_offer_interface)
|
||||
diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c
|
||||
index a8382812ab149c4377441d46a693f736f5430cad..45d679abdafb94708e478745d4f1db57922c37b7 100644
|
||||
--- a/src/video/wayland/SDL_waylandevents.c
|
||||
+++ b/src/video/wayland/SDL_waylandevents.c
|
||||
@@ -518,6 +518,10 @@ static SDL_bool ProcessHitTest(struct SDL_WaylandInput *input, uint32_t serial)
|
||||
input->seat,
|
||||
serial);
|
||||
}
|
||||
+ } else {
|
||||
+ if (window_data->shell_surface.wl) {
|
||||
+ wl_shell_surface_move(window_data->shell_surface.wl, input->seat, serial);
|
||||
+ }
|
||||
}
|
||||
return SDL_TRUE;
|
||||
|
||||
@@ -543,6 +547,10 @@ static SDL_bool ProcessHitTest(struct SDL_WaylandInput *input, uint32_t serial)
|
||||
serial,
|
||||
directions[rc - SDL_HITTEST_RESIZE_TOPLEFT]);
|
||||
}
|
||||
+ } else {
|
||||
+ if (window_data->shell_surface.wl) {
|
||||
+ wl_shell_surface_resize(window_data->shell_surface.wl, input->seat, serial, directions[rc - SDL_HITTEST_RESIZE_TOPLEFT]);
|
||||
+ }
|
||||
}
|
||||
return SDL_TRUE;
|
||||
|
||||
diff --git a/src/video/wayland/SDL_waylandsym.h b/src/video/wayland/SDL_waylandsym.h
|
||||
index 1b02b01c6691bd2df30508ab88bbd990586594d0..27ff34a31a77c970300790697204594d24e11a1f 100644
|
||||
--- a/src/video/wayland/SDL_waylandsym.h
|
||||
+++ b/src/video/wayland/SDL_waylandsym.h
|
||||
@@ -101,11 +101,13 @@ SDL_WAYLAND_INTERFACE(wl_surface_interface)
|
||||
SDL_WAYLAND_INTERFACE(wl_shm_pool_interface)
|
||||
SDL_WAYLAND_INTERFACE(wl_buffer_interface)
|
||||
SDL_WAYLAND_INTERFACE(wl_registry_interface)
|
||||
+SDL_WAYLAND_INTERFACE(wl_shell_surface_interface)
|
||||
SDL_WAYLAND_INTERFACE(wl_region_interface)
|
||||
SDL_WAYLAND_INTERFACE(wl_pointer_interface)
|
||||
SDL_WAYLAND_INTERFACE(wl_keyboard_interface)
|
||||
SDL_WAYLAND_INTERFACE(wl_compositor_interface)
|
||||
SDL_WAYLAND_INTERFACE(wl_output_interface)
|
||||
+SDL_WAYLAND_INTERFACE(wl_shell_interface)
|
||||
SDL_WAYLAND_INTERFACE(wl_shm_interface)
|
||||
SDL_WAYLAND_INTERFACE(wl_data_device_interface)
|
||||
SDL_WAYLAND_INTERFACE(wl_data_source_interface)
|
||||
diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c
|
||||
index 2cae471792cd692129f193fac2100d7d98ab6705..70e9d7306a8fcc60a4b8b1a9289c18f88a8de990 100644
|
||||
--- a/src/video/wayland/SDL_waylandvideo.c
|
||||
+++ b/src/video/wayland/SDL_waylandvideo.c
|
||||
@@ -846,6 +846,8 @@ static void display_handle_global(void *data, struct wl_registry *registry, uint
|
||||
} else if (SDL_strcmp(interface, "xdg_wm_base") == 0) {
|
||||
d->shell.xdg = wl_registry_bind(d->registry, id, &xdg_wm_base_interface, SDL_min(version, 3));
|
||||
xdg_wm_base_add_listener(d->shell.xdg, &shell_listener_xdg, NULL);
|
||||
+ } else if (SDL_strcmp(interface, "wl_shell") == 0) {
|
||||
+ d->shell.wl = wl_registry_bind(d->registry, id, &wl_shell_interface, 1);
|
||||
} else if (SDL_strcmp(interface, "wl_shm") == 0) {
|
||||
d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
|
||||
} else if (SDL_strcmp(interface, "zwp_relative_pointer_manager_v1") == 0) {
|
||||
@@ -1097,6 +1099,11 @@ static void Wayland_VideoCleanup(_THIS)
|
||||
data->shm = NULL;
|
||||
}
|
||||
|
||||
+ if (data->shell.wl) {
|
||||
+ wl_shell_destroy(data->shell.wl);
|
||||
+ data->shell.wl = NULL;
|
||||
+ }
|
||||
+
|
||||
if (data->shell.xdg) {
|
||||
xdg_wm_base_destroy(data->shell.xdg);
|
||||
data->shell.xdg = NULL;
|
||||
diff --git a/src/video/wayland/SDL_waylandvideo.h b/src/video/wayland/SDL_waylandvideo.h
|
||||
index b7b3348c6d4d9285971d5a2416f7d123f303c7f8..e57ab2bd21a3064c257d704b4912c22d5c49074e 100644
|
||||
--- a/src/video/wayland/SDL_waylandvideo.h
|
||||
+++ b/src/video/wayland/SDL_waylandvideo.h
|
||||
@@ -64,6 +64,7 @@ typedef struct
|
||||
struct
|
||||
{
|
||||
struct xdg_wm_base *xdg;
|
||||
+ struct wl_shell *wl;
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
struct libdecor *libdecor;
|
||||
#endif
|
||||
diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c
|
||||
index 08df3638c2e795ecdf4cd5f4972bd5d4f866653d..4cb20afbda9aef1edad59b3cf2bd73a7f6e3d289 100644
|
||||
--- a/src/video/wayland/SDL_waylandwindow.c
|
||||
+++ b/src/video/wayland/SDL_waylandwindow.c
|
||||
@@ -446,6 +446,20 @@ static void SetFullscreen(SDL_Window *window, struct wl_output *output)
|
||||
} else {
|
||||
xdg_toplevel_unset_fullscreen(wind->shell_surface.xdg.roleobj.toplevel);
|
||||
}
|
||||
+ } else {
|
||||
+ if (wind->shell_surface.wl == NULL) {
|
||||
+ return; /* Can't do anything yet, wait for ShowWindow */
|
||||
+ }
|
||||
+
|
||||
+ wl_surface_commit(wind->surface);
|
||||
+
|
||||
+ 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);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -541,6 +555,62 @@ static const struct wl_callback_listener gles_swap_frame_listener = {
|
||||
|
||||
static void Wayland_HandleResize(SDL_Window *window, int width, int height, float scale);
|
||||
|
||||
+/* 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
|
||||
+ window manager. */
|
||||
+
|
||||
+static void
|
||||
+handle_ping_wl_shell_surface(void *data, struct wl_shell_surface *shell_surface,
|
||||
+ uint32_t serial)
|
||||
+{
|
||||
+ wl_shell_surface_pong(shell_surface, serial);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+handle_configure_wl_shell_surface(void *data, struct wl_shell_surface *shell_surface,
|
||||
+ uint32_t edges, int32_t width, int32_t height)
|
||||
+{
|
||||
+ SDL_WindowData *wind = (SDL_WindowData *)data;
|
||||
+ SDL_Window *window = wind->sdlwindow;
|
||||
+
|
||||
+ /* wl_shell_surface spec states that this is a suggestion.
|
||||
+ Ignore if less than or greater than max/min size. */
|
||||
+
|
||||
+ if (width == 0 || height == 0) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
|
||||
+ if ((window->flags & SDL_WINDOW_RESIZABLE)) {
|
||||
+ if (window->max_w > 0) {
|
||||
+ width = SDL_min(width, window->max_w);
|
||||
+ }
|
||||
+ width = SDL_max(width, window->min_w);
|
||||
+
|
||||
+ if (window->max_h > 0) {
|
||||
+ height = SDL_min(height, window->max_h);
|
||||
+ }
|
||||
+ height = SDL_max(height, window->min_h);
|
||||
+ } else {
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ Wayland_HandleResize(window, width, height, wind->scale_factor);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+handle_popup_done_wl_shell_surface(void *data, struct wl_shell_surface *shell_surface)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static const struct wl_shell_surface_listener shell_surface_listener_wl = {
|
||||
+ handle_ping_wl_shell_surface,
|
||||
+ handle_configure_wl_shell_surface,
|
||||
+ handle_popup_done_wl_shell_surface
|
||||
+};
|
||||
+
|
||||
static void handle_configure_xdg_shell_surface(void *data, struct xdg_surface *xdg, uint32_t serial)
|
||||
{
|
||||
SDL_WindowData *wind = (SDL_WindowData *)data;
|
||||
@@ -1374,6 +1444,11 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
|
||||
xdg_toplevel_set_app_id(data->shell_surface.xdg.roleobj.toplevel, c->classname);
|
||||
xdg_toplevel_add_listener(data->shell_surface.xdg.roleobj.toplevel, &toplevel_listener_xdg, data);
|
||||
}
|
||||
+ } else {
|
||||
+ 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_user_data(data->shell_surface.wl, data);
|
||||
+ wl_shell_surface_add_listener(data->shell_surface.wl, &shell_surface_listener_wl, data);
|
||||
}
|
||||
|
||||
/* Restore state that was set prior to this call */
|
||||
@@ -1549,6 +1624,11 @@ void Wayland_HideWindow(_THIS, SDL_Window *window)
|
||||
xdg_surface_destroy(wind->shell_surface.xdg.surface);
|
||||
wind->shell_surface.xdg.surface = NULL;
|
||||
}
|
||||
+ } else {
|
||||
+ if (wind->shell_surface.wl) {
|
||||
+ wl_shell_surface_destroy(wind->shell_surface.wl);
|
||||
+ wind->shell_surface.wl = NULL;
|
||||
+ }
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1829,6 +1909,11 @@ void Wayland_RestoreWindow(_THIS, SDL_Window *window)
|
||||
return; /* Can't do anything yet, wait for ShowWindow */
|
||||
}
|
||||
xdg_toplevel_unset_maximized(wind->shell_surface.xdg.roleobj.toplevel);
|
||||
+ } else {
|
||||
+ if (wind->shell_surface.wl == NULL) {
|
||||
+ return; /* Can't do anything yet, wait for ShowWindow */
|
||||
+ }
|
||||
+ wl_shell_surface_set_toplevel(wind->shell_surface.wl);
|
||||
}
|
||||
|
||||
WAYLAND_wl_display_roundtrip(viddata->display);
|
||||
@@ -1908,6 +1993,11 @@ void Wayland_MaximizeWindow(_THIS, SDL_Window *window)
|
||||
return; /* Can't do anything yet, wait for ShowWindow */
|
||||
}
|
||||
xdg_toplevel_set_maximized(wind->shell_surface.xdg.roleobj.toplevel);
|
||||
+ } else {
|
||||
+ if (wind->shell_surface.wl == NULL) {
|
||||
+ return; /* Can't do anything yet, wait for ShowWindow */
|
||||
+ }
|
||||
+ wl_shell_surface_set_maximized(wind->shell_surface.wl, NULL);
|
||||
}
|
||||
|
||||
WAYLAND_wl_display_roundtrip(viddata->display);
|
||||
@@ -2209,6 +2299,11 @@ void Wayland_SetWindowTitle(_THIS, SDL_Window *window)
|
||||
return; /* Can't do anything yet, wait for ShowWindow */
|
||||
}
|
||||
xdg_toplevel_set_title(wind->shell_surface.xdg.roleobj.toplevel, title);
|
||||
+ } else {
|
||||
+ if (wind->shell_surface.wl == NULL) {
|
||||
+ return; /* Can'd do anything yet, wait for ShowWindow */
|
||||
+ }
|
||||
+ wl_shell_surface_set_title(wind->shell_surface.wl, title);
|
||||
}
|
||||
|
||||
WAYLAND_wl_display_flush(viddata->display);
|
||||
diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h
|
||||
index 36600a4d2783e5205d0e1d2faf8422b54e1f7848..0951126949879d863cde175684a3605367428824 100644
|
||||
--- a/src/video/wayland/SDL_waylandwindow.h
|
||||
+++ b/src/video/wayland/SDL_waylandwindow.h
|
||||
@@ -67,6 +67,7 @@ typedef struct
|
||||
} roleobj;
|
||||
SDL_bool initial_configure_seen;
|
||||
} xdg;
|
||||
+ struct wl_shell_surface *wl;
|
||||
} shell_surface;
|
||||
enum
|
||||
{
|
||||
@@ -0,0 +1,49 @@
|
||||
commit 7dd1cdd4656e0bdbf0f851392f644b2a05c32d64
|
||||
Author: Vladimir Serbinenko <phcoder@gmail.com>
|
||||
Date: Thu Sep 26 17:19:14 2024 +0300
|
||||
|
||||
Handle wayland touch cancel message
|
||||
|
||||
Suppose host has some three-finger gesture. Then we get the following sequence
|
||||
of events:
|
||||
DOWN-DOWN-DOWN-MOTION-CANCEL
|
||||
|
||||
Note that there is no UP in this sequence. So if we don't handle CANCEL then
|
||||
we end up thinking that fingers are still touching the screen. Ideally we
|
||||
should inform the application that cancel has happened as not to trigger
|
||||
spurious taps but still this is way better than being stuck with phantom
|
||||
finger touch.
|
||||
|
||||
diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c
|
||||
index 65838f480..236dc3232 100644
|
||||
--- a/src/video/wayland/SDL_waylandevents.c
|
||||
+++ b/src/video/wayland/SDL_waylandevents.c
|
||||
@@ -932,6 +932,28 @@ static void touch_handler_frame(void *data, struct wl_touch *touch)
|
||||
|
||||
static void touch_handler_cancel(void *data, struct wl_touch *touch)
|
||||
{
|
||||
+ struct SDL_WaylandTouchPoint *tp;
|
||||
+ while ((tp = touch_points.head)) {
|
||||
+ wl_fixed_t fx = 0, fy = 0;
|
||||
+ struct wl_surface *surface = NULL;
|
||||
+ int id = tp->id;
|
||||
+
|
||||
+ touch_del(id, &fx, &fy, &surface);
|
||||
+
|
||||
+ if (surface) {
|
||||
+ SDL_WindowData *window_data = (SDL_WindowData *)wl_surface_get_user_data(surface);
|
||||
+
|
||||
+ if (window_data) {
|
||||
+ const double dblx = wl_fixed_to_double(fx) * window_data->pointer_scale_x;
|
||||
+ const double dbly = wl_fixed_to_double(fy) * window_data->pointer_scale_y;
|
||||
+ const float x = dblx / window_data->sdlwindow->w;
|
||||
+ const float y = dbly / window_data->sdlwindow->h;
|
||||
+
|
||||
+ SDL_SendTouch((SDL_TouchID)(intptr_t)touch, (SDL_FingerID)id,
|
||||
+ window_data->sdlwindow, SDL_FALSE, x, y, 1.0f);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
static const struct wl_touch_listener touch_listener = {
|
||||
@@ -0,0 +1,12 @@
|
||||
--- a/sdl2-config.in 2024-10-06 01:45:09.683556034 +0300
|
||||
+++ b/sdl2-config.in 2024-10-06 01:56:47.497325450 +0300
|
||||
@@ -53,8 +53,8 @@
|
||||
@ENABLE_SHARED_TRUE@ ;;
|
||||
@ENABLE_STATIC_TRUE@@ENABLE_SHARED_TRUE@ --static-libs)
|
||||
@ENABLE_STATIC_TRUE@@ENABLE_SHARED_FALSE@ --libs|--static-libs)
|
||||
-@ENABLE_STATIC_TRUE@ sdl_static_libs=$(echo "@SDL_LIBS@ @SDL_STATIC_LIBS@" | sed -E "s#-lSDL2[ $]#$libdir/libSDL2.a #g")
|
||||
+@ENABLE_STATIC_TRUE@ sdl_static_libs=$(echo "@SDL_LIBS@ @SDL_STATIC_LIBS@" | sed "s#-lSDL2[ $]#$libdir/libSDL2.a #g")
|
||||
@ENABLE_STATIC_TRUE@ echo -L@libdir@ $sdl_static_libs
|
||||
@ENABLE_STATIC_TRUE@ ;;
|
||||
*)
|
||||
echo "${usage}" 1>&2
|
||||
Reference in New Issue
Block a user