mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-08-27 00:51:34 +00:00
wayland: Add support for setting window icons via the xdg-toplevel-icon-v1 protocol
This commit is contained in:
@@ -59,6 +59,7 @@
|
||||
#include "primary-selection-unstable-v1-client-protocol.h"
|
||||
#include "fractional-scale-v1-client-protocol.h"
|
||||
#include "cursor-shape-v1-client-protocol.h"
|
||||
#include "xdg-toplevel-icon-v1-client-protocol.h"
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
#include <libdecor.h>
|
||||
@@ -276,6 +277,7 @@ static SDL_VideoDevice *Wayland_CreateDevice(void)
|
||||
device->SetWindowMaximumSize = Wayland_SetWindowMaximumSize;
|
||||
device->SetWindowModalFor = Wayland_SetWindowModalFor;
|
||||
device->SetWindowTitle = Wayland_SetWindowTitle;
|
||||
device->SetWindowIcon = Wayland_SetWindowIcon;
|
||||
device->GetWindowSizeInPixels = Wayland_GetWindowSizeInPixels;
|
||||
device->DestroyWindow = Wayland_DestroyWindow;
|
||||
device->SetWindowHitTest = Wayland_SetWindowHitTest;
|
||||
@@ -880,6 +882,8 @@ static void display_handle_global(void *data, struct wl_registry *registry, uint
|
||||
if (d->input) {
|
||||
Wayland_CreateCursorShapeDevice(d->input);
|
||||
}
|
||||
} else if (SDL_strcmp(interface, "xdg_toplevel_icon_manager_v1") == 0) {
|
||||
d->xdg_toplevel_icon_manager_v1 = wl_registry_bind(d->registry, id, &xdg_toplevel_icon_manager_v1_interface, 1);
|
||||
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
|
||||
} else if (SDL_strcmp(interface, "qt_touch_extension") == 0) {
|
||||
Wayland_touch_create(d, id);
|
||||
@@ -1128,6 +1132,11 @@ static void Wayland_VideoCleanup(_THIS)
|
||||
data->cursor_shape_manager = NULL;
|
||||
}
|
||||
|
||||
if (data->xdg_toplevel_icon_manager_v1) {
|
||||
xdg_toplevel_icon_manager_v1_destroy(data->xdg_toplevel_icon_manager_v1);
|
||||
data->xdg_toplevel_icon_manager_v1 = NULL;
|
||||
}
|
||||
|
||||
if (data->compositor) {
|
||||
wl_compositor_destroy(data->compositor);
|
||||
data->compositor = NULL;
|
||||
|
||||
@@ -78,6 +78,7 @@ typedef struct
|
||||
struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager;
|
||||
struct xdg_activation_v1 *activation_manager;
|
||||
struct zwp_text_input_manager_v3 *text_input_manager;
|
||||
struct xdg_toplevel_icon_manager_v1 *xdg_toplevel_icon_manager_v1;
|
||||
struct zxdg_output_manager_v1 *xdg_output_manager;
|
||||
struct wp_viewporter *viewporter;
|
||||
struct wp_fractional_scale_manager_v1 *fractional_scale_manager;
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "SDL_waylandwindow.h"
|
||||
#include "SDL_waylandvideo.h"
|
||||
#include "SDL_waylandtouch.h"
|
||||
#include "SDL_waylandshmbuffer.h"
|
||||
#include "SDL_hints.h"
|
||||
#include "../../SDL_hints_c.h"
|
||||
#include "SDL_events.h"
|
||||
@@ -41,6 +42,7 @@
|
||||
#include "xdg-activation-v1-client-protocol.h"
|
||||
#include "viewporter-client-protocol.h"
|
||||
#include "fractional-scale-v1-client-protocol.h"
|
||||
#include "xdg-toplevel-icon-v1-client-protocol.h"
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
#include <libdecor.h>
|
||||
@@ -1273,6 +1275,12 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
|
||||
} else {
|
||||
libdecor_frame_set_app_id(data->shell_surface.libdecor.frame, c->classname);
|
||||
libdecor_frame_map(data->shell_surface.libdecor.frame);
|
||||
|
||||
if (c->xdg_toplevel_icon_manager_v1 && data->xdg_toplevel_icon_v1) {
|
||||
xdg_toplevel_icon_manager_v1_set_icon(c->xdg_toplevel_icon_manager_v1,
|
||||
libdecor_frame_get_xdg_toplevel(data->shell_surface.libdecor.frame),
|
||||
data->xdg_toplevel_icon_v1);
|
||||
}
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
@@ -1317,6 +1325,12 @@ 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);
|
||||
|
||||
if (c->xdg_toplevel_icon_manager_v1 && data->xdg_toplevel_icon_v1) {
|
||||
xdg_toplevel_icon_manager_v1_set_icon(c->xdg_toplevel_icon_manager_v1,
|
||||
data->shell_surface.xdg.roleobj.toplevel,
|
||||
data->xdg_toplevel_icon_v1);
|
||||
}
|
||||
|
||||
SetMinMaxDimensions(window, SDL_FALSE);
|
||||
}
|
||||
}
|
||||
@@ -2172,6 +2186,46 @@ void Wayland_SetWindowTitle(_THIS, SDL_Window *window)
|
||||
WAYLAND_wl_display_flush(viddata->display);
|
||||
}
|
||||
|
||||
void Wayland_SetWindowIcon(SDL_VideoDevice *_this, SDL_Window *window, SDL_Surface *icon)
|
||||
{
|
||||
SDL_WindowData *wind = window->driverdata;
|
||||
SDL_VideoData *viddata = _this->driverdata;
|
||||
struct xdg_toplevel *toplevel = NULL;
|
||||
|
||||
if (!viddata->xdg_toplevel_icon_manager_v1) {
|
||||
SDL_SetError("wayland: cannot set icon; xdg_toplevel_icon_v1 protocol not supported");
|
||||
return;
|
||||
}
|
||||
if (icon->w != icon->h) {
|
||||
SDL_SetError("wayland: icon width and height must be equal, got %ix%i", icon->w, icon->h);
|
||||
return;
|
||||
}
|
||||
if (wind->xdg_toplevel_icon_v1) {
|
||||
xdg_toplevel_icon_v1_destroy(wind->xdg_toplevel_icon_v1);
|
||||
wind->xdg_toplevel_icon_v1 = NULL;
|
||||
}
|
||||
|
||||
Wayland_ReleaseSHMBuffer(&wind->icon);
|
||||
if (Wayland_AllocSHMBuffer(icon->w, icon->h, &wind->icon) != 0) {
|
||||
SDL_SetError("wayland: failed to allocate SHM buffer for the icon");
|
||||
return;
|
||||
}
|
||||
SDL_PremultiplyAlpha(icon->w, icon->h, icon->format->format, icon->pixels, icon->pitch, SDL_PIXELFORMAT_ARGB8888, wind->icon.shm_data, icon->w * 4);
|
||||
wind->xdg_toplevel_icon_v1 = xdg_toplevel_icon_manager_v1_create_icon(viddata->xdg_toplevel_icon_manager_v1);
|
||||
xdg_toplevel_icon_v1_add_buffer(wind->xdg_toplevel_icon_v1, wind->icon.wl_buffer, 1);
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
if (wind->shell_surface_type == WAYLAND_SURFACE_LIBDECOR && wind->shell_surface.libdecor.frame) {
|
||||
toplevel = libdecor_frame_get_xdg_toplevel(wind->shell_surface.libdecor.frame);
|
||||
} else
|
||||
#endif
|
||||
if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_TOPLEVEL && wind->shell_surface.xdg.roleobj.toplevel) {
|
||||
toplevel = wind->shell_surface.xdg.roleobj.toplevel;
|
||||
}
|
||||
if (toplevel) {
|
||||
xdg_toplevel_icon_manager_v1_set_icon(viddata->xdg_toplevel_icon_manager_v1, toplevel, wind->xdg_toplevel_icon_v1);
|
||||
}
|
||||
}
|
||||
|
||||
void Wayland_SuspendScreenSaver(_THIS)
|
||||
{
|
||||
SDL_VideoData *data = (SDL_VideoData *)_this->driverdata;
|
||||
@@ -2240,6 +2294,12 @@ void Wayland_DestroyWindow(_THIS, SDL_Window *window)
|
||||
wp_fractional_scale_v1_destroy(wind->fractional_scale);
|
||||
}
|
||||
|
||||
if (wind->xdg_toplevel_icon_v1) {
|
||||
xdg_toplevel_icon_v1_destroy(wind->xdg_toplevel_icon_v1);
|
||||
}
|
||||
|
||||
Wayland_ReleaseSHMBuffer(&wind->icon);
|
||||
|
||||
SDL_free(wind->outputs);
|
||||
|
||||
if (wind->gles_swap_frame_callback) {
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "../../events/SDL_touch_c.h"
|
||||
|
||||
#include "SDL_waylandvideo.h"
|
||||
#include "SDL_waylandshmbuffer.h"
|
||||
|
||||
struct SDL_WaylandInput;
|
||||
|
||||
@@ -89,6 +90,9 @@ typedef struct
|
||||
struct xdg_activation_token_v1 *activation_token;
|
||||
struct wp_viewport *draw_viewport;
|
||||
struct wp_fractional_scale_v1 *fractional_scale;
|
||||
struct xdg_toplevel_icon_v1 *xdg_toplevel_icon_v1;
|
||||
|
||||
struct Wayland_SHMBuffer icon;
|
||||
|
||||
/* floating dimensions for restoring from maximized and fullscreen */
|
||||
int floating_width, floating_height;
|
||||
@@ -142,6 +146,7 @@ extern int Wayland_SetWindowModalFor(_THIS, SDL_Window *modal_window, SDL_Window
|
||||
extern void Wayland_SetWindowTitle(_THIS, SDL_Window *window);
|
||||
extern void Wayland_DestroyWindow(_THIS, SDL_Window *window);
|
||||
extern void Wayland_SuspendScreenSaver(_THIS);
|
||||
extern void Wayland_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon);
|
||||
|
||||
extern SDL_bool
|
||||
Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info);
|
||||
|
||||
Reference in New Issue
Block a user