From 12321a88808e296b1c4b8d7475c5d914eaa559ae Mon Sep 17 00:00:00 2001 From: SytheZN Date: Mon, 4 Oct 2021 19:55:18 +0200 Subject: [PATCH] [client] wayland: implement resizing for libdecor --- AUTHORS | 1 + .../displayservers/Wayland/shell_libdecor.c | 57 ++++++++++++++----- client/displayservers/Wayland/shell_xdg.c | 7 ++- client/displayservers/Wayland/wayland.c | 2 +- client/displayservers/Wayland/wayland.h | 5 +- client/displayservers/Wayland/window.c | 6 +- 6 files changed, 56 insertions(+), 22 deletions(-) diff --git a/AUTHORS b/AUTHORS index ff31ac55..ded3599a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -53,3 +53,4 @@ orcephrye (orcephrye) thejavascriptman (thejavascriptman) vroad <396351+vroad@users.noreply.github.com> (vroad) williamvds (williamvds) +SytheZN (SytheZN) diff --git a/client/displayservers/Wayland/shell_libdecor.c b/client/displayservers/Wayland/shell_libdecor.c index f34093aa..a5a783af 100644 --- a/client/displayservers/Wayland/shell_libdecor.c +++ b/client/displayservers/Wayland/shell_libdecor.c @@ -51,29 +51,32 @@ static void libdecorHandleError(struct libdecor * context, enum libdecor_error e static void libdecorFrameConfigure(struct libdecor_frame * frame, struct libdecor_configuration * configuration, void * opaque) { + if (!wlWm.configured) + { + xdg_surface_ack_configure(libdecor_frame_get_xdg_surface(frame), configuration->serial); + wlWm.configured = true; + return; + } + int width, height; - if (libdecor_configuration_get_content_size(configuration, frame, &width, &height)) { + if (libdecor_configuration_get_content_size(configuration, frame, &width, &height)) + { wlWm.width = width; wlWm.height = height; + + struct libdecor_state * state = libdecor_state_new(wlWm.width, wlWm.height); + libdecor_frame_commit(wlWm.libdecorFrame, state, NULL); + libdecor_state_free(state); } 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; - app_invalidateWindow(true); - waylandStopWaitFrame(); - } - else - wlWm.configured = true; + wlWm.needsResize = true; + wlWm.resizeSerial = configuration->serial; + app_invalidateWindow(true); + waylandStopWaitFrame(); } static void libdecorFrameClose(struct libdecor_frame * frame, void * opaque) @@ -103,7 +106,7 @@ static void libdecorCallback(uint32_t events, void * opaque) libdecor_dispatch(wlWm.libdecor, 0); } -bool waylandShellInit(const char * title, bool fullscreen, bool maximize, bool borderless) +bool waylandShellInit(const char * title, bool fullscreen, bool maximize, bool borderless, bool resizable) { wlWm.libdecor = libdecor_new(wlWm.display, &libdecorListener); wlWm.libdecorFrame = libdecor_decorate(wlWm.libdecor, wlWm.surface, &libdecorFrameListener, NULL); @@ -112,6 +115,11 @@ bool waylandShellInit(const char * title, bool fullscreen, bool maximize, bool b libdecor_frame_set_title(wlWm.libdecorFrame, title); libdecor_frame_map(wlWm.libdecorFrame); + if (resizable) + libdecor_frame_set_capabilities(wlWm.libdecorFrame, LIBDECOR_ACTION_RESIZE); + else + libdecor_frame_unset_capabilities(wlWm.libdecorFrame, LIBDECOR_ACTION_RESIZE); + while (!wlWm.configured) libdecor_dispatch(wlWm.libdecor, 0); @@ -138,6 +146,8 @@ void waylandSetFullscreen(bool fs) libdecor_frame_set_fullscreen(wlWm.libdecorFrame, NULL); else libdecor_frame_unset_fullscreen(wlWm.libdecorFrame); + + libdecor_frame_set_visibility(wlWm.libdecorFrame, !fs); } bool waylandGetFullscreen(void) @@ -149,3 +159,20 @@ void waylandMinimize(void) { libdecor_frame_set_minimized(wlWm.libdecorFrame); } + +void waylandShellResize(int w, int h) +{ + if (!libdecor_frame_is_floating(wlWm.libdecorFrame)) + return; + + wlWm.width = w; + wlWm.height = h; + + struct libdecor_state * state = libdecor_state_new(w, h); + libdecor_frame_commit(wlWm.libdecorFrame, state, NULL); + libdecor_state_free(state); + + wlWm.needsResize = true; + app_invalidateWindow(true); + waylandStopWaitFrame(); +} diff --git a/client/displayservers/Wayland/shell_xdg.c b/client/displayservers/Wayland/shell_xdg.c index 17631c5d..96903c62 100644 --- a/client/displayservers/Wayland/shell_xdg.c +++ b/client/displayservers/Wayland/shell_xdg.c @@ -87,7 +87,7 @@ static const struct xdg_toplevel_listener xdgToplevelListener = { .close = xdgToplevelClose, }; -bool waylandShellInit(const char * title, bool fullscreen, bool maximize, bool borderless) +bool waylandShellInit(const char * title, bool fullscreen, bool maximize, bool borderless, bool resizable) { if (!wlWm.xdgWmBase) { @@ -153,3 +153,8 @@ void waylandMinimize(void) { xdg_toplevel_set_minimized(wlWm.xdgToplevel); } + +void waylandShellResize(int w, int h) +{ + //TODO: Implement resize for XDG. +} diff --git a/client/displayservers/Wayland/wayland.c b/client/displayservers/Wayland/wayland.c index 26abdfa8..05c3d469 100644 --- a/client/displayservers/Wayland/wayland.c +++ b/client/displayservers/Wayland/wayland.c @@ -98,7 +98,7 @@ static bool waylandInit(const LG_DSInitParams params) if (!waylandInputInit()) return false; - if (!waylandWindowInit(params.title, params.fullscreen, params.maximize, params.borderless)) + if (!waylandWindowInit(params.title, params.fullscreen, params.maximize, params.borderless, params.resizable)) return false; if (!waylandEGLInit(params.w, params.h)) diff --git a/client/displayservers/Wayland/wayland.h b/client/displayservers/Wayland/wayland.h index d4a4d086..ddc485af 100644 --- a/client/displayservers/Wayland/wayland.h +++ b/client/displayservers/Wayland/wayland.h @@ -306,14 +306,15 @@ bool waylandRegistryInit(void); void waylandRegistryFree(void); // shell module -bool waylandShellInit(const char * title, bool fullscreen, bool maximize, bool borderless); +bool waylandShellInit(const char * title, bool fullscreen, bool maximize, bool borderless, bool resizable); void waylandShellAckConfigureIfNeeded(void); void waylandSetFullscreen(bool fs); bool waylandGetFullscreen(void); void waylandMinimize(void); +void waylandShellResize(int w, int h); // window module -bool waylandWindowInit(const char * title, bool fullscreen, bool maximize, bool borderless); +bool waylandWindowInit(const char * title, bool fullscreen, bool maximize, bool borderless, bool resizable); void waylandWindowFree(void); void waylandWindowUpdateScale(void); void waylandSetWindowSize(int x, int y); diff --git a/client/displayservers/Wayland/window.c b/client/displayservers/Wayland/window.c index a9dc7372..1b3a9dd5 100644 --- a/client/displayservers/Wayland/window.c +++ b/client/displayservers/Wayland/window.c @@ -79,7 +79,7 @@ static const struct wl_surface_listener wlSurfaceListener = { .leave = wlSurfaceLeaveHandler, }; -bool waylandWindowInit(const char * title, bool fullscreen, bool maximize, bool borderless) +bool waylandWindowInit(const char * title, bool fullscreen, bool maximize, bool borderless, bool resizable) { wlWm.scale = wl_fixed_from_int(1); @@ -106,7 +106,7 @@ bool waylandWindowInit(const char * title, bool fullscreen, bool maximize, bool wl_surface_add_listener(wlWm.surface, &wlSurfaceListener, NULL); - if (!waylandShellInit(title, fullscreen, maximize, borderless)) + if (!waylandShellInit(title, fullscreen, maximize, borderless, resizable)) return false; wl_surface_commit(wlWm.surface); @@ -121,7 +121,7 @@ void waylandWindowFree(void) void waylandSetWindowSize(int x, int y) { - // FIXME: implement. + waylandShellResize(x, y); } bool waylandIsValidPointerPos(int x, int y)