Skip to content

Commit fb12896

Browse files
committed
Enable support for wlshell
Sailfish still uses old wlshell and hasno support for modern xdg-shell. Thispatch allows SDL to work on Sailfish. Uplifted from github.com:savegame/SDL.git which in turn takes it from https://github.com/sailfishos/libsdl/blob/master/rpm/0001-wayland-Bring-back-wl_shell-support.patch
1 parent c9f3cbe commit fb12896

File tree

8 files changed

+117
-1
lines changed

8 files changed

+117
-1
lines changed

include/SDL_syswm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ struct SDL_SysWMinfo
294294
{
295295
struct wl_display *display; /**< Wayland display */
296296
struct wl_surface *surface; /**< Wayland surface */
297-
void *shell_surface; /**< DEPRECATED Wayland shell_surface (window manager handle) */
297+
struct wl_shell_surface *shell_surface; /**< DEPRECATED Wayland shell_surface (window manager handle) */
298298
struct wl_egl_window *egl_window; /**< Wayland EGL window (native window) */
299299
struct xdg_surface *xdg_surface; /**< Wayland xdg surface (window manager handle) */
300300
struct xdg_toplevel *xdg_toplevel; /**< Wayland xdg toplevel role */

src/video/wayland/SDL_waylanddyn.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,13 @@ void SDL_WAYLAND_UnloadSymbols(void);
111111
#define wl_shm_pool_interface (*WAYLAND_wl_shm_pool_interface)
112112
#define wl_buffer_interface (*WAYLAND_wl_buffer_interface)
113113
#define wl_registry_interface (*WAYLAND_wl_registry_interface)
114+
#define wl_shell_surface_interface (*WAYLAND_wl_shell_surface_interface)
114115
#define wl_region_interface (*WAYLAND_wl_region_interface)
115116
#define wl_pointer_interface (*WAYLAND_wl_pointer_interface)
116117
#define wl_keyboard_interface (*WAYLAND_wl_keyboard_interface)
117118
#define wl_compositor_interface (*WAYLAND_wl_compositor_interface)
118119
#define wl_output_interface (*WAYLAND_wl_output_interface)
120+
#define wl_shell_interface (*WAYLAND_wl_shell_interface)
119121
#define wl_shm_interface (*WAYLAND_wl_shm_interface)
120122
#define wl_data_device_interface (*WAYLAND_wl_data_device_interface)
121123
#define wl_data_offer_interface (*WAYLAND_wl_data_offer_interface)

src/video/wayland/SDL_waylandevents.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,10 @@ static SDL_bool ProcessHitTest(struct SDL_WaylandInput *input, uint32_t serial)
543543
input->seat,
544544
serial);
545545
}
546+
} else {
547+
if (window_data->shell_surface.wl) {
548+
wl_shell_surface_move(window_data->shell_surface.wl, input->seat, serial);
549+
}
546550
}
547551
return SDL_TRUE;
548552

@@ -568,6 +572,10 @@ static SDL_bool ProcessHitTest(struct SDL_WaylandInput *input, uint32_t serial)
568572
serial,
569573
directions[rc - SDL_HITTEST_RESIZE_TOPLEFT]);
570574
}
575+
} else {
576+
if (window_data->shell_surface.wl) {
577+
wl_shell_surface_resize(window_data->shell_surface.wl, input->seat, serial, directions[rc - SDL_HITTEST_RESIZE_TOPLEFT]);
578+
}
571579
}
572580
return SDL_TRUE;
573581

src/video/wayland/SDL_waylandsym.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,13 @@ SDL_WAYLAND_INTERFACE(wl_surface_interface)
101101
SDL_WAYLAND_INTERFACE(wl_shm_pool_interface)
102102
SDL_WAYLAND_INTERFACE(wl_buffer_interface)
103103
SDL_WAYLAND_INTERFACE(wl_registry_interface)
104+
SDL_WAYLAND_INTERFACE(wl_shell_surface_interface)
104105
SDL_WAYLAND_INTERFACE(wl_region_interface)
105106
SDL_WAYLAND_INTERFACE(wl_pointer_interface)
106107
SDL_WAYLAND_INTERFACE(wl_keyboard_interface)
107108
SDL_WAYLAND_INTERFACE(wl_compositor_interface)
108109
SDL_WAYLAND_INTERFACE(wl_output_interface)
110+
SDL_WAYLAND_INTERFACE(wl_shell_interface)
109111
SDL_WAYLAND_INTERFACE(wl_shm_interface)
110112
SDL_WAYLAND_INTERFACE(wl_data_device_interface)
111113
SDL_WAYLAND_INTERFACE(wl_data_source_interface)

src/video/wayland/SDL_waylandvideo.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,8 @@ static void display_handle_global(void *data, struct wl_registry *registry, uint
844844
} else if (SDL_strcmp(interface, "xdg_wm_base") == 0) {
845845
d->shell.xdg = wl_registry_bind(d->registry, id, &xdg_wm_base_interface, SDL_min(version, 3));
846846
xdg_wm_base_add_listener(d->shell.xdg, &shell_listener_xdg, NULL);
847+
} else if (SDL_strcmp(interface, "wl_shell") == 0) {
848+
d->shell.wl = wl_registry_bind(d->registry, id, &wl_shell_interface, 1);
847849
} else if (SDL_strcmp(interface, "wl_shm") == 0) {
848850
d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
849851
} else if (SDL_strcmp(interface, "zwp_relative_pointer_manager_v1") == 0) {
@@ -1093,6 +1095,11 @@ static void Wayland_VideoCleanup(_THIS)
10931095
data->shm = NULL;
10941096
}
10951097

1098+
if (data->shell.wl) {
1099+
wl_shell_destroy(data->shell.wl);
1100+
data->shell.wl = NULL;
1101+
}
1102+
10961103
if (data->shell.xdg) {
10971104
xdg_wm_base_destroy(data->shell.xdg);
10981105
data->shell.xdg = NULL;

src/video/wayland/SDL_waylandvideo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ typedef struct
6464
struct
6565
{
6666
struct xdg_wm_base *xdg;
67+
struct wl_shell *wl;
6768
#ifdef HAVE_LIBDECOR_H
6869
struct libdecor *libdecor;
6970
#endif

src/video/wayland/SDL_waylandwindow.c

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,20 @@ static void SetFullscreen(SDL_Window *window, struct wl_output *output)
383383
} else {
384384
xdg_toplevel_unset_fullscreen(wind->shell_surface.xdg.roleobj.toplevel);
385385
}
386+
} else {
387+
if (wind->shell_surface.wl == NULL) {
388+
return; /* Can't do anything yet, wait for ShowWindow */
389+
}
390+
391+
wl_surface_commit(wind->surface);
392+
393+
if (output) {
394+
wl_shell_surface_set_fullscreen(wind->shell_surface.wl,
395+
WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
396+
0, output);
397+
} else {
398+
wl_shell_surface_set_toplevel(wind->shell_surface.wl);
399+
}
386400
}
387401
}
388402

@@ -478,6 +492,62 @@ static const struct wl_callback_listener gles_swap_frame_listener = {
478492

479493
static void Wayland_HandleResize(SDL_Window *window, int width, int height, float scale);
480494

495+
/* On modern desktops, we probably will use the xdg-shell protocol instead
496+
of wl_shell, but wl_shell might be useful on older Wayland installs that
497+
don't have the newer protocol, or embedded things that don't have a full
498+
window manager. */
499+
500+
static void
501+
handle_ping_wl_shell_surface(void *data, struct wl_shell_surface *shell_surface,
502+
uint32_t serial)
503+
{
504+
wl_shell_surface_pong(shell_surface, serial);
505+
}
506+
507+
static void
508+
handle_configure_wl_shell_surface(void *data, struct wl_shell_surface *shell_surface,
509+
uint32_t edges, int32_t width, int32_t height)
510+
{
511+
SDL_WindowData *wind = (SDL_WindowData *)data;
512+
SDL_Window *window = wind->sdlwindow;
513+
514+
/* wl_shell_surface spec states that this is a suggestion.
515+
Ignore if less than or greater than max/min size. */
516+
517+
if (width == 0 || height == 0) {
518+
return;
519+
}
520+
521+
if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
522+
if ((window->flags & SDL_WINDOW_RESIZABLE)) {
523+
if (window->max_w > 0) {
524+
width = SDL_min(width, window->max_w);
525+
}
526+
width = SDL_max(width, window->min_w);
527+
528+
if (window->max_h > 0) {
529+
height = SDL_min(height, window->max_h);
530+
}
531+
height = SDL_max(height, window->min_h);
532+
} else {
533+
return;
534+
}
535+
}
536+
537+
Wayland_HandleResize(window, width, height, wind->scale_factor);
538+
}
539+
540+
static void
541+
handle_popup_done_wl_shell_surface(void *data, struct wl_shell_surface *shell_surface)
542+
{
543+
}
544+
545+
static const struct wl_shell_surface_listener shell_surface_listener_wl = {
546+
handle_ping_wl_shell_surface,
547+
handle_configure_wl_shell_surface,
548+
handle_popup_done_wl_shell_surface
549+
};
550+
481551
static void handle_configure_xdg_shell_surface(void *data, struct xdg_surface *xdg, uint32_t serial)
482552
{
483553
SDL_WindowData *wind = (SDL_WindowData *)data;
@@ -1319,6 +1389,11 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
13191389

13201390
SetMinMaxDimensions(window, SDL_FALSE);
13211391
}
1392+
} else {
1393+
data->shell_surface.wl = wl_shell_get_shell_surface(c->shell.wl, data->surface);
1394+
wl_shell_surface_set_class(data->shell_surface.wl, c->classname);
1395+
wl_shell_surface_set_user_data(data->shell_surface.wl, data);
1396+
wl_shell_surface_add_listener(data->shell_surface.wl, &shell_surface_listener_wl, data);
13221397
}
13231398

13241399
/* Restore state that was set prior to this call */
@@ -1494,6 +1569,11 @@ void Wayland_HideWindow(_THIS, SDL_Window *window)
14941569
xdg_surface_destroy(wind->shell_surface.xdg.surface);
14951570
wind->shell_surface.xdg.surface = NULL;
14961571
}
1572+
} else {
1573+
if (wind->shell_surface.wl) {
1574+
wl_shell_surface_destroy(wind->shell_surface.wl);
1575+
wind->shell_surface.wl = NULL;
1576+
}
14971577
}
14981578

14991579
/*
@@ -1774,6 +1854,11 @@ void Wayland_RestoreWindow(_THIS, SDL_Window *window)
17741854
return; /* Can't do anything yet, wait for ShowWindow */
17751855
}
17761856
xdg_toplevel_unset_maximized(wind->shell_surface.xdg.roleobj.toplevel);
1857+
} else {
1858+
if (wind->shell_surface.wl == NULL) {
1859+
return; /* Can't do anything yet, wait for ShowWindow */
1860+
}
1861+
wl_shell_surface_set_toplevel(wind->shell_surface.wl);
17771862
}
17781863

17791864
WAYLAND_wl_display_roundtrip(viddata->display);
@@ -1853,6 +1938,11 @@ void Wayland_MaximizeWindow(_THIS, SDL_Window *window)
18531938
return; /* Can't do anything yet, wait for ShowWindow */
18541939
}
18551940
xdg_toplevel_set_maximized(wind->shell_surface.xdg.roleobj.toplevel);
1941+
} else {
1942+
if (wind->shell_surface.wl == NULL) {
1943+
return; /* Can't do anything yet, wait for ShowWindow */
1944+
}
1945+
wl_shell_surface_set_maximized(wind->shell_surface.wl, NULL);
18561946
}
18571947

18581948
WAYLAND_wl_display_roundtrip(viddata->display);
@@ -2174,6 +2264,11 @@ void Wayland_SetWindowTitle(_THIS, SDL_Window *window)
21742264
return; /* Can't do anything yet, wait for ShowWindow */
21752265
}
21762266
xdg_toplevel_set_title(wind->shell_surface.xdg.roleobj.toplevel, title);
2267+
} else {
2268+
if (wind->shell_surface.wl == NULL) {
2269+
return; /* Can'd do anything yet, wait for ShowWindow */
2270+
}
2271+
wl_shell_surface_set_title(wind->shell_surface.wl, title);
21772272
}
21782273

21792274
WAYLAND_wl_display_flush(viddata->display);

src/video/wayland/SDL_waylandwindow.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ typedef struct
6767
} roleobj;
6868
SDL_bool initial_configure_seen;
6969
} xdg;
70+
struct wl_shell_surface *wl;
7071
} shell_surface;
7172
enum
7273
{

0 commit comments

Comments
 (0)