From 82bd0b66522dbdfcfe6274157bb2eaedd3c8051e Mon Sep 17 00:00:00 2001 From: ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> Date: Fri, 15 Mar 2024 09:43:35 +0100 Subject: [PATCH] Have FLTK use libdecor at version > 0.2.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - it's no longer necessary to take care of the change in the layout of "struct libdecor" between versions ≤ 0.2.2 and > 0.2.2 of libdecor - version > 0.2.2 contains MR131, that is, it defines LIBDECOR_WINDOW_STATE_RESIZING so the hack to emulate it is no longer necessary - CMake option FLTK_USE_SYSTEM_LIBDECOR now requires libdecor version > 0.2.2 to be activated, otherwise the bundled libdecor is used - what will be the libdecor version after 0.2.2 (0.2.3? 0.3.0?) is not known as of today --- CMake/options.cmake | 10 +-- README.CMake.txt | 8 +- README.Wayland.txt | 8 +- configure.ac | 2 +- documentation/src/wayland.dox | 16 ++-- libdecor/build/fl_libdecor-plugins.c | 28 +------ .../Wayland/Fl_Wayland_Window_Driver.cxx | 73 +------------------ 7 files changed, 18 insertions(+), 127 deletions(-) diff --git a/CMake/options.cmake b/CMake/options.cmake index 3f7369641..f4adee1a0 100644 --- a/CMake/options.cmake +++ b/CMake/options.cmake @@ -297,7 +297,7 @@ if(UNIX) endif() unset(FLTK_GRAPHICS_CAIRO CACHE) set(FLTK_GRAPHICS_CAIRO TRUE CACHE BOOL "all drawing to X11 windows uses Cairo") - option(FLTK_USE_SYSTEM_LIBDECOR "use libdecor from the system" ON) + option(FLTK_USE_SYSTEM_LIBDECOR "use libdecor from the system" OFF) set(USE_SYSTEM_LIBDECOR 1) unset(FLTK_USE_XRENDER CACHE) unset(FLTK_USE_XINERAMA CACHE) @@ -333,9 +333,9 @@ if(UNIX) unset(FLTK_USE_PANGO CACHE) set(FLTK_USE_PANGO TRUE CACHE BOOL "use lib Pango") if(FLTK_USE_SYSTEM_LIBDECOR) - pkg_check_modules(SYSTEM_LIBDECOR libdecor-0>=0.2.0 QUIET) + pkg_check_modules(SYSTEM_LIBDECOR libdecor-0>0.2.2 QUIET) if(NOT SYSTEM_LIBDECOR_FOUND) - message(STATUS "Warning: system libdecor doesn't satisfy version >= 0.2.0,") + message(STATUS "Warning: system libdecor doesn't satisfy version > 0.2.2,") message(STATUS " using bundled libdecor library instead.") set(USE_SYSTEM_LIBDECOR 0) else() @@ -355,10 +355,6 @@ if(UNIX) set(FLTK_USE_LIBDECOR_GTK ON) else() option(FLTK_USE_LIBDECOR_GTK "Allow to use libdecor's GTK plugin" ON) - # Temporarily, while built-in and system struct libdecor differ. - # Later, the version of the system libdecor will be required to have same - # struct libdecor as the built-in libdecor. - set(CMAKE_ENABLE_EXPORTS 1) endif(USE_SYSTEM_LIBDECOR) if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "FreeBSD") diff --git a/README.CMake.txt b/README.CMake.txt index f8768dc8b..b117b6b9f 100644 --- a/README.CMake.txt +++ b/README.CMake.txt @@ -282,12 +282,12 @@ FLTK_USE_PTHREADS - default ON except on Windows. This option is ignored (switched OFF internally) on Windows except when using Cygwin. -FLTK_USE_SYSTEM_LIBDECOR - default ON (Wayland only) +FLTK_USE_SYSTEM_LIBDECOR - default OFF (Wayland only) This option makes FLTK use package libdecor-0-dev to draw window titlebars - under Wayland. When OFF or when this package has a version < 0.2.0, FLTK + under Wayland. When OFF or when this package has a version ≤ 0.2.2, FLTK uses its bundled copy of libdecor to draw window titlebars. - As of november 2023, version 0.2.0 of package libdecor-0-dev is available - only in testing distributions. + As of early 2024, no version > 0.2.2 of package libdecor-0-dev is available + yet. FLTK_USE_SYSTEM_LIBJPEG - default ON (macOS and Windows: OFF) FLTK_USE_SYSTEM_LIBPNG - default ON (macOS and Windows: OFF) diff --git a/README.Wayland.txt b/README.Wayland.txt index 048994aa7..dc4c24c36 100644 --- a/README.Wayland.txt +++ b/README.Wayland.txt @@ -126,8 +126,8 @@ cross-compiling for systems that lack X11 headers and libraries. The FLTK Wayland platform uses a library called libdecor which handles window decorations (i.e., titlebars, shade). On very recent Linux distributions (e.g., Debian trixie) libdecor is available as Linux packages (libdecor-0-dev and libdecor-0-plugin-1-gtk). -FLTK requires version 0.2.0 of these packages or more. -In other situations, FLTK uses a copy of libdecor bundled in the FLTK source code. +FLTK requires a version > 0.2.2 of these packages that's not yet available. +Therefore, FLTK uses a copy of libdecor bundled in the FLTK source code. FLTK equipped with libdecor supports both the client-side decoration mode (CSD) and the server-side decoration mode (SSD) as determined by the active Wayland compositor. Mutter (gnome's Wayland compositor) and Weston use CSD mode, KWin and Sway use SSD mode. @@ -194,9 +194,6 @@ in section 2.1 of file README.Unix.txt : These packages allow to run FLTK apps under the Gnome-Wayland desktop: - gnome-core - libgtk-3-dev <== highly recommended, gives windows a Gnome-style titlebar -- libdecor-0-dev and libdecor-0-plugin-1-gtk in versions ≥ 0.2.0 - <== Recommended if available for the Linux version in use, - <== FLTK uses a bundled copy of these packages otherwise. These packages allow to run FLTK apps under the KDE/Plasma-Wayland desktop: - kde-plasma-desktop @@ -221,7 +218,6 @@ package groups listed in section 2.2 of file README.Unix.txt : - mesa-libGLU-devel - dbus-devel <== recommended to query current cursor theme - gtk3-devel <== highly recommended, gives windows a GTK-style titlebar -- libdecor-0.2.0 <== recommended, present in Fedora Rawhide, not in Fedora 39 - glew-devel <== necessary to use OpenGL version 3 or above - cmake <== if you plan to build with CMake - cmake-gui <== if you plan to use the GUI of CMake diff --git a/configure.ac b/configure.ac index fe9b7aeb6..6b64110b0 100644 --- a/configure.ac +++ b/configure.ac @@ -1074,7 +1074,7 @@ AS_CASE([$host_os_gui], [cygwin* | mingw*], [ BUILD="WAYLANDX11" graphics="Wayland or X11 with cairo" ]) - AS_IF([$PKGCONFIG --exists 'libdecor-0 >= 0.2.0'], + AS_IF([$PKGCONFIG --exists 'libdecor-0 > 0.2.2'], [ plugin_dir="$($PKGCONFIG --variable=libdir libdecor-0)/libdecor/plugins-1" CFLAGS="$CFLAGS -DUSE_SYSTEM_LIBDECOR" diff --git a/documentation/src/wayland.dox b/documentation/src/wayland.dox index 88f4d4dbf..8af4555de 100644 --- a/documentation/src/wayland.dox +++ b/documentation/src/wayland.dox @@ -1104,8 +1104,7 @@ and also to draw window titlebars when in CSD mode (see \ref bundled-libdecor). \c Libdecor is conceived to be present in a shared library linked to the Wayland client application which itself, and if the running Wayland compositor uses CSD mode, loads another shared library intended to draw titlebars in a way that best matches the -Desktop. As of late 2023, libdecor is at version 0.2.0 and contains two titlebar-drawing -plugins: +Desktop. As of late 2023, libdecor contains two titlebar-drawing plugins: - \c libdecor-gtk intended for the Gnome desktop; - \c libdecor-cairo for other situations. @@ -1114,15 +1113,10 @@ FLTK bundles the most recent source code of \c libdecor and its plugins. This co is included in libfltk. FLTK uses \c libdecor-gtk when software package \c libgtk-3-dev is present in the build system, and \c libdecor-cairo otherwise. -As of late 2023, libdecor version 0.2.0 is available in very recent Linux distributions -in packages \c libdecor-0-dev and \c libdecor-0-plugin-1-gtk. If they are installed on the -build system, preprocessor variable \c USE_SYSTEM_LIBDECOR is 1, -and both \c libdecor and its plugin are loaded at run-time from shared libraries. -When these packages are not available or are at an earlier version, FLTK uses the bundled -copy of \c libdecor. -When CMake \c FLTK_USE_SYSTEM_LIBDECOR is OFF, FLTK uses the bundled \c libdecor copy -even if shared libraries \c libdecor.so and \c libdecor-gtk.so are installed. -This option is ON by default. +As of early 2024, libdecor version 0.2.2 is available in very recent Linux distributions. +This version is not binary compatible with the libdecor version bundled by FLTK. +For this reason, CMake option \c FLTK_USE_SYSTEM_LIBDECOR is OFF by default, and +FLTK uses the bundled \c libdecor copy to draw titlebars. \c Libdecor uses the Wayland protocol XDG decoration diff --git a/libdecor/build/fl_libdecor-plugins.c b/libdecor/build/fl_libdecor-plugins.c index fbf4eb657..1e73d736a 100644 --- a/libdecor/build/fl_libdecor-plugins.c +++ b/libdecor/build/fl_libdecor-plugins.c @@ -301,23 +301,6 @@ unsigned char *fl_libdecor_titlebar_buffer(struct libdecor_frame *frame, } -// When the libdecor version after 0.2.2 will be released, support of older versions -// will be removed from FLTK. LIBDECOR_MR131 stuff also will be removed. -struct libdecor_022 { // for libdecor versions ≤ 0.2.2 - int ref_count; - const struct libdecor_interface *iface; - struct libdecor_plugin *plugin; - bool plugin_ready; - struct wl_display *wl_display; - struct wl_registry *wl_registry; - struct xdg_wm_base *xdg_wm_base; - struct zxdg_decoration_manager_v1 *decoration_manager; - struct wl_callback *init_callback; - bool init_done; - bool has_error; - struct wl_list frames; -}; - struct libdecor { // copied from libdecor.c, for libdecor versions > 0.2.2 int ref_count; const struct libdecor_interface *iface; @@ -338,18 +321,9 @@ struct libdecor { // copied from libdecor.c, for libdecor versions > 0.2.2 /* Returns whether surface is a GTK-titlebar created by libdecor-gtk */ bool fl_is_surface_gtk_titlebar(struct wl_surface *surface, struct libdecor *context) { if (!context || get_plugin_kind(NULL) != GTK3) return false; - static void *new_symbol = NULL; - static bool first = true; - if (first) { - first = false; - // new_symbol is NULL for libdecor versions ≤ 0.2.2 - new_symbol = dlsym(RTLD_DEFAULT, "libdecor_frame_get_user_data"); - } - struct wl_list *frames_addr = (new_symbol ? &context->frames : - &(((struct libdecor_022*)context)->frames) ); // loop over all decorations created by libdecor-gtk struct libdecor_frame *frame; - wl_list_for_each(frame, frames_addr, link) { + wl_list_for_each(frame, &context->frames, link) { struct libdecor_frame_gtk *frame_gtk = (struct libdecor_frame_gtk*)frame; if (frame_gtk->headerbar.wl_surface == surface) return true; } diff --git a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx index d86d713dc..b831b51b4 100644 --- a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx @@ -769,69 +769,6 @@ static struct Fl_Wayland_Screen_Driver::output *screen_num_to_output(int num_scr } -#define LIBDECOR_MR131 1 // this means libdecor does not include MR!131 yet - -#ifdef LIBDECOR_MR131 -/* === Beginning of hack that would become un-needed if libdecor accepted MR!131 === */ - -// true while the GUI is interactively resizing a decorated window -static bool in_decorated_window_resizing = false; - - -// libdecor's configure cb function for xdg_toplevel objects -static void (*decor_xdg_toplevel_configure)(void*, struct xdg_toplevel *, int32_t, - int32_t, struct wl_array *); - - -static void fltk_xdg_toplevel_configure(void *user_data, struct xdg_toplevel *xdg_toplevel, - int32_t width, int32_t height, - struct wl_array *states) { - uint32_t *p; - in_decorated_window_resizing = false; - // Replace wl_array_for_each(p, states) rejected by C++ - for (p = (uint32_t *)(states)->data; - (const char *) p < ((const char *) (states)->data + (states)->size); - (p)++) { - if (*p == XDG_TOPLEVEL_STATE_RESIZING) { - in_decorated_window_resizing = true; - break; - } - } - decor_xdg_toplevel_configure(user_data, xdg_toplevel, width, height, states); -} - - -struct wl_object { // copied from wayland-private.h - const struct wl_interface *interface; - const void *implementation; - uint32_t id; -}; - - -// replace libdecor's toplevel configure cb by FLTK's -static void use_FLTK_toplevel_configure_cb(struct libdecor_frame *frame) { - struct wl_object *object = (struct wl_object *)libdecor_frame_get_xdg_toplevel(frame); - static struct xdg_toplevel_listener *fltk_listener = NULL; - if (!fltk_listener) { - struct xdg_toplevel_listener *decor_listener = (struct xdg_toplevel_listener*) - object->implementation; - fltk_listener = (struct xdg_toplevel_listener*) - malloc(sizeof(struct xdg_toplevel_listener)); - // initialize FLTK's listener with libdecor's values - *fltk_listener = *decor_listener; - // memorize libdecor's toplevel configure cb - decor_xdg_toplevel_configure = decor_listener->configure; - // replace libdecor's toplevel configure cb by FLTK's - fltk_listener->configure = fltk_xdg_toplevel_configure; - } - // replace the toplevel listener by a copy whose configure member is FLTK's - object->implementation = fltk_listener; -} - -/* === End of hack that would become un-needed if libdecor accepted MR!131 === */ -#endif // LIBDECOR_MR131 - - static void handle_configure(struct libdecor_frame *frame, struct libdecor_configuration *configuration, void *user_data) { @@ -849,9 +786,6 @@ static void handle_configure(struct libdecor_frame *frame, if (!window->xdg_surface) window->xdg_surface = libdecor_frame_get_xdg_surface(frame); -#ifdef LIBDECOR_MR131 - if (is_1st_run) use_FLTK_toplevel_configure_cb(frame); -#endif struct wl_output *wl_output = NULL; if (window->fl_win->fullscreen_active()) { if (!(window->state & LIBDECOR_WINDOW_STATE_FULLSCREEN)) { @@ -905,16 +839,13 @@ static void handle_configure(struct libdecor_frame *frame, //fprintf(stderr,"handle_configure: using floating %dx%d\n",width,height); } -#ifndef LIBDECOR_MR131 - bool in_decorated_window_resizing = (window->state & LIBDECOR_WINDOW_STATE_RESIZING); -#endif - bool condition = in_decorated_window_resizing; + bool condition = (window->state & LIBDECOR_WINDOW_STATE_RESIZING); if (condition) { // see issue #878 condition = (window->covered ? (window->buffer && window->buffer->in_use) : (window->frame_cb != NULL)); } if (condition) { // Skip resizing & redrawing. The last resize request won't be skipped because - // in_decorated_window_resizing will be false or cb will be NULL then. + // LIBDECOR_WINDOW_STATE_RESIZING will be off or cb will be NULL then. return; }