From 72607feb9180c76bf8f9d149100af0e8fbefb32d Mon Sep 17 00:00:00 2001 From: Christian Rauch Date: Sat, 22 May 2021 18:20:35 +0100 Subject: GHOST/wayland: add 'xdg-decoration' support --- intern/ghost/CMakeLists.txt | 5 +++++ intern/ghost/intern/GHOST_SystemWayland.cpp | 14 ++++++++++++++ intern/ghost/intern/GHOST_SystemWayland.h | 3 +++ intern/ghost/intern/GHOST_WindowWayland.cpp | 26 ++++++++++++++++++++++++++ 4 files changed, 48 insertions(+) (limited to 'intern') diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt index 16929a13840..1b5cdb3cda0 100644 --- a/intern/ghost/CMakeLists.txt +++ b/intern/ghost/CMakeLists.txt @@ -322,6 +322,11 @@ elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND) xdg-shell "${WAYLAND_PROTOCOLS_DIR}/stable/xdg-shell/xdg-shell.xml" ) + # xdg-decoration. + generate_protocol_bindings( + xdg-decoration + "${WAYLAND_PROTOCOLS_DIR}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml" + ) # Pointer-constraints. generate_protocol_bindings( pointer-constraints diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index 1e9a2940c32..02785181b52 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -140,6 +140,7 @@ struct display_t { struct wl_display *display; struct wl_compositor *compositor = nullptr; struct xdg_wm_base *xdg_shell = nullptr; + struct zxdg_decoration_manager_v1 *xdg_decoration_manager = nullptr; struct wl_shm *shm = nullptr; std::vector outputs; std::vector inputs; @@ -240,6 +241,10 @@ static void display_destroy(display_t *d) wl_compositor_destroy(d->compositor); } + if (d->xdg_decoration_manager) { + zxdg_decoration_manager_v1_destroy(d->xdg_decoration_manager); + } + if (d->xdg_shell) { xdg_wm_base_destroy(d->xdg_shell); } @@ -1331,6 +1336,10 @@ static void global_add(void *data, wl_registry_bind(wl_registry, name, &xdg_wm_base_interface, 1)); xdg_wm_base_add_listener(display->xdg_shell, &shell_listener, nullptr); } + else if (!strcmp(interface, zxdg_decoration_manager_v1_interface.name)) { + display->xdg_decoration_manager = static_cast( + wl_registry_bind(wl_registry, name, &zxdg_decoration_manager_v1_interface, 1)); + } else if (!strcmp(interface, wl_output_interface.name)) { output_t *output = new output_t; output->scale = 1; @@ -1666,6 +1675,11 @@ xdg_wm_base *GHOST_SystemWayland::shell() return d->xdg_shell; } +zxdg_decoration_manager_v1 *GHOST_SystemWayland::decoration_manager() +{ + return d->xdg_decoration_manager; +} + const std::vector &GHOST_SystemWayland::outputs() const { return d->outputs; diff --git a/intern/ghost/intern/GHOST_SystemWayland.h b/intern/ghost/intern/GHOST_SystemWayland.h index 2457bed5def..3a08a0d3b16 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.h +++ b/intern/ghost/intern/GHOST_SystemWayland.h @@ -26,6 +26,7 @@ #include "GHOST_WindowWayland.h" #include +#include #include #include @@ -94,6 +95,8 @@ class GHOST_SystemWayland : public GHOST_System { xdg_wm_base *shell(); + zxdg_decoration_manager_v1 *decoration_manager(); + const std::vector &outputs() const; wl_shm *shm() const; diff --git a/intern/ghost/intern/GHOST_WindowWayland.cpp b/intern/ghost/intern/GHOST_WindowWayland.cpp index 70cfe35d628..cbac2d6eaa1 100644 --- a/intern/ghost/intern/GHOST_WindowWayland.cpp +++ b/intern/ghost/intern/GHOST_WindowWayland.cpp @@ -40,6 +40,8 @@ struct window_t { int scale = 1; struct xdg_surface *xdg_surface; struct xdg_toplevel *xdg_toplevel; + struct zxdg_toplevel_decoration_v1 *xdg_toplevel_decoration = nullptr; + enum zxdg_toplevel_decoration_v1_mode decoration_mode; wl_egl_window *egl_window; int32_t pending_width, pending_height; bool is_maximised; @@ -99,6 +101,18 @@ static const xdg_toplevel_listener toplevel_listener = { toplevel_close, }; +static void toplevel_decoration_configure( + void *data, + struct zxdg_toplevel_decoration_v1 * /*zxdg_toplevel_decoration_v1*/, + uint32_t mode) +{ + static_cast(data)->decoration_mode = zxdg_toplevel_decoration_v1_mode(mode); +} + +static const zxdg_toplevel_decoration_v1_listener toplevel_decoration_v1_listener = { + toplevel_decoration_configure, +}; + static void surface_configure(void *data, xdg_surface *xdg_surface, uint32_t serial) { window_t *win = static_cast(data); @@ -221,6 +235,15 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system, w->xdg_surface = xdg_wm_base_get_xdg_surface(m_system->shell(), w->surface); w->xdg_toplevel = xdg_surface_get_toplevel(w->xdg_surface); + if (m_system->decoration_manager()) { + w->xdg_toplevel_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration( + m_system->decoration_manager(), w->xdg_toplevel); + zxdg_toplevel_decoration_v1_add_listener( + w->xdg_toplevel_decoration, &toplevel_decoration_v1_listener, w); + zxdg_toplevel_decoration_v1_set_mode(w->xdg_toplevel_decoration, + ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); + } + wl_surface_set_user_data(w->surface, this); xdg_surface_add_listener(w->xdg_surface, &surface_listener, w); @@ -393,6 +416,9 @@ GHOST_WindowWayland::~GHOST_WindowWayland() releaseNativeHandles(); wl_egl_window_destroy(w->egl_window); + if (w->xdg_toplevel_decoration) { + zxdg_toplevel_decoration_v1_destroy(w->xdg_toplevel_decoration); + } xdg_toplevel_destroy(w->xdg_toplevel); xdg_surface_destroy(w->xdg_surface); wl_surface_destroy(w->surface); -- cgit v1.2.3