Skip to content

Commit

Permalink
Enable support for wlshell
Browse files Browse the repository at this point in the history
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
  • Loading branch information
phcoder committed Sep 26, 2024
1 parent c9f3cbe commit fb12896
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 1 deletion.
2 changes: 1 addition & 1 deletion include/SDL_syswm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
2 changes: 2 additions & 0 deletions src/video/wayland/SDL_waylanddyn.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
8 changes: 8 additions & 0 deletions src/video/wayland/SDL_waylandevents.c
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,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;

Expand All @@ -568,6 +572,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;

Expand Down
2 changes: 2 additions & 0 deletions src/video/wayland/SDL_waylandsym.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
7 changes: 7 additions & 0 deletions src/video/wayland/SDL_waylandvideo.c
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,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) {
Expand Down Expand Up @@ -1093,6 +1095,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;
Expand Down
1 change: 1 addition & 0 deletions src/video/wayland/SDL_waylandvideo.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ typedef struct
struct
{
struct xdg_wm_base *xdg;
struct wl_shell *wl;
#ifdef HAVE_LIBDECOR_H
struct libdecor *libdecor;
#endif
Expand Down
95 changes: 95 additions & 0 deletions src/video/wayland/SDL_waylandwindow.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,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);
}
}
}

Expand Down Expand Up @@ -478,6 +492,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;
Expand Down Expand Up @@ -1319,6 +1389,11 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)

SetMinMaxDimensions(window, SDL_FALSE);
}
} 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 */
Expand Down Expand Up @@ -1494,6 +1569,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;
}
}

/*
Expand Down Expand Up @@ -1774,6 +1854,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);
Expand Down Expand Up @@ -1853,6 +1938,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);
Expand Down Expand Up @@ -2174,6 +2264,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);
Expand Down
1 change: 1 addition & 0 deletions src/video/wayland/SDL_waylandwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ typedef struct
} roleobj;
SDL_bool initial_configure_seen;
} xdg;
struct wl_shell_surface *wl;
} shell_surface;
enum
{
Expand Down

0 comments on commit fb12896

Please sign in to comment.