2021-09-24 21:45:48 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
2023-03-23 20:55:14 +01:00
|
|
|
#include <wlr/types/wlr_xdg_decoration_v1.h>
|
2022-09-16 18:41:02 -04:00
|
|
|
#include "common/mem.h"
|
2025-08-17 16:01:50 -04:00
|
|
|
#include "config/rcxml.h"
|
2023-03-23 20:55:14 +01:00
|
|
|
#include "decorations.h"
|
2021-03-02 20:53:03 +00:00
|
|
|
#include "labwc.h"
|
2022-11-21 10:10:39 -05:00
|
|
|
#include "view.h"
|
2021-03-02 20:53:03 +00:00
|
|
|
|
|
|
|
|
struct xdg_deco {
|
2023-03-23 20:55:14 +01:00
|
|
|
struct wlr_xdg_toplevel_decoration_v1 *wlr_xdg_decoration;
|
2024-04-23 23:37:08 +02:00
|
|
|
enum wlr_xdg_toplevel_decoration_v1_mode client_mode;
|
2021-10-20 16:03:27 +00:00
|
|
|
struct view *view;
|
2021-03-02 20:53:03 +00:00
|
|
|
struct wl_listener destroy;
|
|
|
|
|
struct wl_listener request_mode;
|
2024-04-23 23:37:08 +02:00
|
|
|
struct wl_listener surface_commit;
|
2021-03-02 20:53:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
xdg_deco_destroy(struct wl_listener *listener, void *data)
|
|
|
|
|
{
|
2023-03-23 20:55:14 +01:00
|
|
|
struct xdg_deco *xdg_deco = wl_container_of(listener, xdg_deco, destroy);
|
2021-03-02 20:53:03 +00:00
|
|
|
wl_list_remove(&xdg_deco->destroy.link);
|
|
|
|
|
wl_list_remove(&xdg_deco->request_mode.link);
|
2024-04-23 23:37:08 +02:00
|
|
|
if (xdg_deco->surface_commit.notify) {
|
|
|
|
|
wl_list_remove(&xdg_deco->surface_commit.link);
|
|
|
|
|
xdg_deco->surface_commit.notify = NULL;
|
|
|
|
|
}
|
2021-03-02 20:53:03 +00:00
|
|
|
free(xdg_deco);
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-23 23:37:08 +02:00
|
|
|
static void
|
|
|
|
|
handle_surface_commit(struct wl_listener *listener, void *data)
|
|
|
|
|
{
|
|
|
|
|
struct xdg_deco *xdg_deco = wl_container_of(listener, xdg_deco, surface_commit);
|
|
|
|
|
struct wlr_xdg_toplevel_decoration_v1 *deco = xdg_deco->wlr_xdg_decoration;
|
|
|
|
|
|
|
|
|
|
if (deco->toplevel->base->initial_commit) {
|
|
|
|
|
wlr_xdg_toplevel_decoration_v1_set_mode(deco, xdg_deco->client_mode);
|
|
|
|
|
wl_list_remove(&xdg_deco->surface_commit.link);
|
|
|
|
|
xdg_deco->surface_commit.notify = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-02 20:53:03 +00:00
|
|
|
static void
|
|
|
|
|
xdg_deco_request_mode(struct wl_listener *listener, void *data)
|
|
|
|
|
{
|
2021-10-20 16:03:27 +00:00
|
|
|
struct xdg_deco *xdg_deco = wl_container_of(listener, xdg_deco, request_mode);
|
|
|
|
|
enum wlr_xdg_toplevel_decoration_v1_mode client_mode =
|
2023-03-23 20:55:14 +01:00
|
|
|
xdg_deco->wlr_xdg_decoration->requested_mode;
|
2021-11-13 21:45:12 +00:00
|
|
|
|
2023-03-22 19:53:17 +01:00
|
|
|
switch (client_mode) {
|
|
|
|
|
case WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE:
|
|
|
|
|
xdg_deco->view->ssd_preference = LAB_SSD_PREF_SERVER;
|
|
|
|
|
break;
|
|
|
|
|
case WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE:
|
|
|
|
|
xdg_deco->view->ssd_preference = LAB_SSD_PREF_CLIENT;
|
|
|
|
|
break;
|
|
|
|
|
case WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_NONE:
|
|
|
|
|
xdg_deco->view->ssd_preference = LAB_SSD_PREF_UNSPEC;
|
2021-10-20 16:03:27 +00:00
|
|
|
client_mode = rc.xdg_shell_server_side_deco
|
|
|
|
|
? WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE
|
|
|
|
|
: WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE;
|
2023-03-22 19:53:17 +01:00
|
|
|
break;
|
|
|
|
|
default:
|
2023-03-23 20:55:14 +01:00
|
|
|
wlr_log(WLR_ERROR, "Unspecified xdg decoration variant "
|
|
|
|
|
"requested: %u", client_mode);
|
2021-03-02 20:53:03 +00:00
|
|
|
}
|
2021-10-20 16:03:27 +00:00
|
|
|
|
2024-04-23 23:37:08 +02:00
|
|
|
/*
|
2025-01-08 23:35:23 -04:00
|
|
|
* We may get multiple request_mode calls in an uninitialized state.
|
2024-04-23 23:37:08 +02:00
|
|
|
* Just update the last requested mode and only add the commit
|
|
|
|
|
* handler on the first uninitialized state call.
|
|
|
|
|
*/
|
|
|
|
|
xdg_deco->client_mode = client_mode;
|
|
|
|
|
|
|
|
|
|
if (xdg_deco->wlr_xdg_decoration->toplevel->base->initialized) {
|
|
|
|
|
wlr_xdg_toplevel_decoration_v1_set_mode(xdg_deco->wlr_xdg_decoration,
|
|
|
|
|
client_mode);
|
|
|
|
|
} else if (!xdg_deco->surface_commit.notify) {
|
|
|
|
|
xdg_deco->surface_commit.notify = handle_surface_commit;
|
|
|
|
|
wl_signal_add(
|
|
|
|
|
&xdg_deco->wlr_xdg_decoration->toplevel->base->surface->events.commit,
|
|
|
|
|
&xdg_deco->surface_commit);
|
|
|
|
|
}
|
2024-04-18 09:46:36 +02:00
|
|
|
if (client_mode == WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE) {
|
|
|
|
|
view_set_ssd_mode(xdg_deco->view, LAB_SSD_MODE_FULL);
|
|
|
|
|
} else {
|
|
|
|
|
view_set_ssd_mode(xdg_deco->view, LAB_SSD_MODE_NONE);
|
|
|
|
|
}
|
2021-03-02 20:53:03 +00:00
|
|
|
}
|
|
|
|
|
|
2023-03-23 20:55:14 +01:00
|
|
|
static void
|
2021-03-02 20:53:03 +00:00
|
|
|
xdg_toplevel_decoration(struct wl_listener *listener, void *data)
|
|
|
|
|
{
|
2023-03-23 20:55:14 +01:00
|
|
|
struct wlr_xdg_toplevel_decoration_v1 *wlr_xdg_decoration = data;
|
2023-08-21 17:59:22 +02:00
|
|
|
struct wlr_xdg_surface *xdg_surface = wlr_xdg_decoration->toplevel->base;
|
2023-03-23 20:55:14 +01:00
|
|
|
if (!xdg_surface || !xdg_surface->data) {
|
|
|
|
|
wlr_log(WLR_ERROR,
|
|
|
|
|
"Invalid surface supplied for xdg decorations");
|
|
|
|
|
return;
|
|
|
|
|
}
|
2021-10-20 16:03:27 +00:00
|
|
|
|
2023-03-23 20:55:14 +01:00
|
|
|
struct xdg_deco *xdg_deco = znew(*xdg_deco);
|
|
|
|
|
xdg_deco->wlr_xdg_decoration = wlr_xdg_decoration;
|
|
|
|
|
xdg_deco->view = (struct view *)xdg_surface->data;
|
|
|
|
|
|
|
|
|
|
wl_signal_add(&wlr_xdg_decoration->events.destroy, &xdg_deco->destroy);
|
|
|
|
|
xdg_deco->destroy.notify = xdg_deco_destroy;
|
|
|
|
|
|
|
|
|
|
wl_signal_add(&wlr_xdg_decoration->events.request_mode,
|
|
|
|
|
&xdg_deco->request_mode);
|
|
|
|
|
xdg_deco->request_mode.notify = xdg_deco_request_mode;
|
|
|
|
|
|
|
|
|
|
xdg_deco_request_mode(&xdg_deco->request_mode, wlr_xdg_decoration);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
tree-wide: auto-replace of (struct server *)
#!/bin/bash
read -r -d '' EXPRS << EOF
s/xwayland->server/xwayland->svr/g;
s/\t*struct server \*server;\n//g;
s/\t*struct server \*server =.*?;\n//gs;
s/\t*.* = ([a-z_]*->)*server[;,]\n//g;
s/\{\n\n/\{\n/g;
s/\n\n+/\n\n/g;
s/\(\s*struct server \*server\)/(void)/g;
s/\(\s*struct server \*server,\s*/(/g;
s/,\s*struct server \*server\)/)/g;
s/,\s*struct server \*server,\s*/, /g;
s/\(\s*([a-z_]*->)*server\)/()/g;
s/\(\s*([a-z_]*->)*server,\s*/(/g;
s/,\s*([a-z_]*->)*server\)/)/g;
s/,\s*([a-z_]*->)*server,\s*/, /g;
s/([a-z_]*->)*server->/g_server./g;
s/xwayland->svr/xwayland->server/g;
EOF
find src include \( -name \*.c -o -name \*.h \) -exec \
perl -0777 -i -pe "$EXPRS" \{\} \;
2026-02-23 11:56:39 -05:00
|
|
|
xdg_server_decoration_init(void)
|
2023-03-23 20:55:14 +01:00
|
|
|
{
|
|
|
|
|
struct wlr_xdg_decoration_manager_v1 *xdg_deco_mgr = NULL;
|
tree-wide: auto-replace of (struct server *)
#!/bin/bash
read -r -d '' EXPRS << EOF
s/xwayland->server/xwayland->svr/g;
s/\t*struct server \*server;\n//g;
s/\t*struct server \*server =.*?;\n//gs;
s/\t*.* = ([a-z_]*->)*server[;,]\n//g;
s/\{\n\n/\{\n/g;
s/\n\n+/\n\n/g;
s/\(\s*struct server \*server\)/(void)/g;
s/\(\s*struct server \*server,\s*/(/g;
s/,\s*struct server \*server\)/)/g;
s/,\s*struct server \*server,\s*/, /g;
s/\(\s*([a-z_]*->)*server\)/()/g;
s/\(\s*([a-z_]*->)*server,\s*/(/g;
s/,\s*([a-z_]*->)*server\)/)/g;
s/,\s*([a-z_]*->)*server,\s*/, /g;
s/([a-z_]*->)*server->/g_server./g;
s/xwayland->svr/xwayland->server/g;
EOF
find src include \( -name \*.c -o -name \*.h \) -exec \
perl -0777 -i -pe "$EXPRS" \{\} \;
2026-02-23 11:56:39 -05:00
|
|
|
xdg_deco_mgr = wlr_xdg_decoration_manager_v1_create(g_server.wl_display);
|
2023-03-23 20:55:14 +01:00
|
|
|
if (!xdg_deco_mgr) {
|
|
|
|
|
wlr_log(WLR_ERROR, "unable to create the XDG deco manager");
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wl_signal_add(&xdg_deco_mgr->events.new_toplevel_decoration,
|
tree-wide: auto-replace of (struct server *)
#!/bin/bash
read -r -d '' EXPRS << EOF
s/xwayland->server/xwayland->svr/g;
s/\t*struct server \*server;\n//g;
s/\t*struct server \*server =.*?;\n//gs;
s/\t*.* = ([a-z_]*->)*server[;,]\n//g;
s/\{\n\n/\{\n/g;
s/\n\n+/\n\n/g;
s/\(\s*struct server \*server\)/(void)/g;
s/\(\s*struct server \*server,\s*/(/g;
s/,\s*struct server \*server\)/)/g;
s/,\s*struct server \*server,\s*/, /g;
s/\(\s*([a-z_]*->)*server\)/()/g;
s/\(\s*([a-z_]*->)*server,\s*/(/g;
s/,\s*([a-z_]*->)*server\)/)/g;
s/,\s*([a-z_]*->)*server,\s*/, /g;
s/([a-z_]*->)*server->/g_server./g;
s/xwayland->svr/xwayland->server/g;
EOF
find src include \( -name \*.c -o -name \*.h \) -exec \
perl -0777 -i -pe "$EXPRS" \{\} \;
2026-02-23 11:56:39 -05:00
|
|
|
&g_server.xdg_toplevel_decoration);
|
|
|
|
|
g_server.xdg_toplevel_decoration.notify = xdg_toplevel_decoration;
|
2021-03-02 20:53:03 +00:00
|
|
|
}
|
2025-02-08 15:48:50 +01:00
|
|
|
|
|
|
|
|
void
|
tree-wide: auto-replace of (struct server *)
#!/bin/bash
read -r -d '' EXPRS << EOF
s/xwayland->server/xwayland->svr/g;
s/\t*struct server \*server;\n//g;
s/\t*struct server \*server =.*?;\n//gs;
s/\t*.* = ([a-z_]*->)*server[;,]\n//g;
s/\{\n\n/\{\n/g;
s/\n\n+/\n\n/g;
s/\(\s*struct server \*server\)/(void)/g;
s/\(\s*struct server \*server,\s*/(/g;
s/,\s*struct server \*server\)/)/g;
s/,\s*struct server \*server,\s*/, /g;
s/\(\s*([a-z_]*->)*server\)/()/g;
s/\(\s*([a-z_]*->)*server,\s*/(/g;
s/,\s*([a-z_]*->)*server\)/)/g;
s/,\s*([a-z_]*->)*server,\s*/, /g;
s/([a-z_]*->)*server->/g_server./g;
s/xwayland->svr/xwayland->server/g;
EOF
find src include \( -name \*.c -o -name \*.h \) -exec \
perl -0777 -i -pe "$EXPRS" \{\} \;
2026-02-23 11:56:39 -05:00
|
|
|
xdg_server_decoration_finish(void)
|
2025-02-08 15:48:50 +01:00
|
|
|
{
|
tree-wide: auto-replace of (struct server *)
#!/bin/bash
read -r -d '' EXPRS << EOF
s/xwayland->server/xwayland->svr/g;
s/\t*struct server \*server;\n//g;
s/\t*struct server \*server =.*?;\n//gs;
s/\t*.* = ([a-z_]*->)*server[;,]\n//g;
s/\{\n\n/\{\n/g;
s/\n\n+/\n\n/g;
s/\(\s*struct server \*server\)/(void)/g;
s/\(\s*struct server \*server,\s*/(/g;
s/,\s*struct server \*server\)/)/g;
s/,\s*struct server \*server,\s*/, /g;
s/\(\s*([a-z_]*->)*server\)/()/g;
s/\(\s*([a-z_]*->)*server,\s*/(/g;
s/,\s*([a-z_]*->)*server\)/)/g;
s/,\s*([a-z_]*->)*server,\s*/, /g;
s/([a-z_]*->)*server->/g_server./g;
s/xwayland->svr/xwayland->server/g;
EOF
find src include \( -name \*.c -o -name \*.h \) -exec \
perl -0777 -i -pe "$EXPRS" \{\} \;
2026-02-23 11:56:39 -05:00
|
|
|
wl_list_remove(&g_server.xdg_toplevel_decoration.link);
|
2025-02-08 15:48:50 +01:00
|
|
|
}
|