diff --git a/client/displayservers/Wayland/registry.c b/client/displayservers/Wayland/registry.c index 622a26f4..3504ca0e 100644 --- a/client/displayservers/Wayland/registry.c +++ b/client/displayservers/Wayland/registry.c @@ -38,11 +38,13 @@ static void registryGlobalHandler(void * data, struct wl_registry * registry, wlWm.shm = wl_registry_bind(wlWm.registry, name, &wl_shm_interface, 1); else if (!strcmp(interface, wl_compositor_interface.name) && version >= 3) wlWm.compositor = wl_registry_bind(wlWm.registry, name, &wl_compositor_interface, 3); +#ifndef ENABLE_LIBDECOR else if (!strcmp(interface, xdg_wm_base_interface.name)) wlWm.xdgWmBase = wl_registry_bind(wlWm.registry, name, &xdg_wm_base_interface, 1); else if (!strcmp(interface, zxdg_decoration_manager_v1_interface.name)) wlWm.xdgDecorationManager = wl_registry_bind(wlWm.registry, name, &zxdg_decoration_manager_v1_interface, 1); +#endif else if (!strcmp(interface, zwp_relative_pointer_manager_v1_interface.name)) wlWm.relativePointerManager = wl_registry_bind(wlWm.registry, name, &zwp_relative_pointer_manager_v1_interface, 1); diff --git a/client/displayservers/Wayland/shell_libdecor.c b/client/displayservers/Wayland/shell_libdecor.c new file mode 100644 index 00000000..2c7bd4a8 --- /dev/null +++ b/client/displayservers/Wayland/shell_libdecor.c @@ -0,0 +1,129 @@ +/* +Looking Glass - KVM FrameRelay (KVMFR) Client +Copyright (C) 2021 Guanzhong Chen (quantum2048@gmail.com) +Copyright (C) 2021 Tudor Brindus (contact@tbrindus.ca) +https://looking-glass.io + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "wayland.h" + +#include +#include + +#include +#include + +#include "app.h" +#include "common/debug.h" + +struct libdecor_configuration { + uint32_t serial; + + bool has_window_state; + enum libdecor_window_state window_state; + + bool has_size; + int window_width; + int window_height; +}; + +static void libdecorHandleError(struct libdecor * context, enum libdecor_error error, + const char *message) +{ + DEBUG_ERROR("Got libdecor error (%d): %s", error, message); +} + +static struct libdecor_interface libdecorListener = { + libdecorHandleError, +}; + +static void libdecorFrameConfigure(struct libdecor_frame * frame, + struct libdecor_configuration * configuration, void * opaque) +{ + int width, height; + if (libdecor_configuration_get_content_size(configuration, frame, &width, &height)) { + wlWm.width = width; + wlWm.height = height; + } + + enum libdecor_window_state windowState; + if (libdecor_configuration_get_window_state(configuration, &windowState)) + wlWm.fullscreen = windowState & LIBDECOR_WINDOW_STATE_FULLSCREEN; + + struct libdecor_state * state = libdecor_state_new(wlWm.width, wlWm.height); + libdecor_frame_commit(frame, state, wlWm.configured ? NULL : configuration); + libdecor_state_free(state); + + if (wlWm.configured) + { + wlWm.needsResize = true; + wlWm.resizeSerial = configuration->serial; + } + else + wlWm.configured = true; +} + +static void libdecorFrameClose(struct libdecor_frame * frame, void * opaque) +{ + app_handleCloseEvent(); +} + +static void libdecorFrameCommit(void * opaque) +{ +} + +static struct libdecor_frame_interface libdecorFrameListener = { + libdecorFrameConfigure, + libdecorFrameClose, + libdecorFrameCommit, +}; + +bool waylandShellInit(const char * title, bool fullscreen, bool maximize, bool borderless) +{ + wlWm.libdecor = libdecor_new(wlWm.display, &libdecorListener); + wlWm.libdecorFrame = libdecor_decorate(wlWm.libdecor, wlWm.surface, &libdecorFrameListener, NULL); + + libdecor_frame_set_app_id(wlWm.libdecorFrame, "looking-glass-client"); + libdecor_frame_set_title(wlWm.libdecorFrame, title); + libdecor_frame_map(wlWm.libdecorFrame); + + while (!wlWm.configured) + wl_display_roundtrip(wlWm.display); + + return true; +} + +void waylandShellAckConfigureIfNeeded(void) +{ + if (wlWm.resizeSerial) + { + xdg_surface_ack_configure(libdecor_frame_get_xdg_surface(wlWm.libdecorFrame), wlWm.resizeSerial); + wlWm.resizeSerial = 0; + } +} + +void waylandSetFullscreen(bool fs) +{ + if (fs) + libdecor_frame_set_fullscreen(wlWm.libdecorFrame, NULL); + else + libdecor_frame_unset_fullscreen(wlWm.libdecorFrame); +} + +bool waylandGetFullscreen(void) +{ + return wlWm.fullscreen; +} diff --git a/client/displayservers/Wayland/wayland.c b/client/displayservers/Wayland/wayland.c index ea5172eb..9b8dadf2 100644 --- a/client/displayservers/Wayland/wayland.c +++ b/client/displayservers/Wayland/wayland.c @@ -68,6 +68,8 @@ static bool waylandInit(const LG_DSInitParams params) wlWm.warpSupport = option_get_bool("wayland", "warpSupport"); wlWm.display = wl_display_connect(NULL); + wlWm.width = params.w; + wlWm.height = params.h; if (!waylandPollInit()) return false; diff --git a/client/displayservers/Wayland/wayland.h b/client/displayservers/Wayland/wayland.h index baa43150..0d350f68 100644 --- a/client/displayservers/Wayland/wayland.h +++ b/client/displayservers/Wayland/wayland.h @@ -96,11 +96,16 @@ struct WaylandDSState EGLSurface glSurface; #endif +#ifdef ENABLE_LIBDECOR + struct libdecor * libdecor; + struct libdecor_frame * libdecorFrame; +#else struct xdg_wm_base * xdgWmBase; struct xdg_surface * xdgSurface; struct xdg_toplevel * xdgToplevel; struct zxdg_decoration_manager_v1 * xdgDecorationManager; struct zxdg_toplevel_decoration_v1 * xdgToplevelDecoration; +#endif struct wl_surface * cursor;