Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable support for wlshell #10951

Open
wants to merge 1 commit into
base: SDL2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading