From 2af1da4ff46915256ff30a4f54f6ad0a41804aee Mon Sep 17 00:00:00 2001 From: ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> Date: Mon, 6 May 2024 09:29:32 +0200 Subject: [PATCH] Wayland: simpler implementation of "GTK Shell" protocol --- libdecor/build/fl_libdecor-plugins.c | 55 +++---------------- .../Wayland/Fl_Wayland_Screen_Driver.cxx | 23 ++++++-- 2 files changed, 24 insertions(+), 54 deletions(-) diff --git a/libdecor/build/fl_libdecor-plugins.c b/libdecor/build/fl_libdecor-plugins.c index f04f8cf2c..4197ea8f0 100644 --- a/libdecor/build/fl_libdecor-plugins.c +++ b/libdecor/build/fl_libdecor-plugins.c @@ -301,52 +301,11 @@ unsigned char *fl_libdecor_titlebar_buffer(struct libdecor_frame *frame, } -struct libdecor { // copied from libdecor.c, for libdecor versions > 0.2.2 - int ref_count; - const struct libdecor_interface *iface; - void *user_data; // added after libdecor version 0.2.2 - 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_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; -}; - - -/* Returns whether surface is a GTK-titlebar created by libdecor-gtk */ -bool fl_is_surface_gtk_titlebar(struct wl_surface *surface, struct libdecor *context, - struct wl_display *wl_display) { - if (!context || get_plugin_kind(NULL) != GTK3) return false; - // loop over all decorations created by libdecor-gtk - struct libdecor_frame *frame; - struct wl_list *frames; - if (context->wl_display == wl_display) frames = &context->frames; - else if (((struct libdecor_022*)context)->wl_display == wl_display) - frames = &(((struct libdecor_022*)context)->frames); - else return false; - wl_list_for_each(frame, frames, link) { - struct libdecor_frame_gtk *frame_gtk = (struct libdecor_frame_gtk*)frame; - if (frame_gtk->headerbar.wl_surface == surface) return true; - } - return false; +/* Returns whether surface is the libdecor-created GTK-titlebar of frame */ +bool fl_is_surface_from_GTK_titlebar (struct wl_surface *surface, struct libdecor_frame *frame, + bool *using_GTK) { + *using_GTK = (get_plugin_kind(NULL) == GTK3); + if (!*using_GTK) return false; + struct libdecor_frame_gtk *frame_gtk = (struct libdecor_frame_gtk*)frame; + return (frame_gtk->headerbar.wl_surface == surface); } diff --git a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx index b2b9d1435..a0fc66f6f 100644 --- a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx @@ -47,7 +47,8 @@ #include // for strerror() extern "C" { bool libdecor_get_cursor_settings(char **theme, int *size); - bool fl_is_surface_gtk_titlebar(struct wl_surface *, struct libdecor *, struct wl_display *); + bool fl_is_surface_from_GTK_titlebar (struct wl_surface *surface, struct libdecor_frame *frame, + bool *using_GTK); } // set this to 1 for keyboard debug output, 0 for no debug output @@ -204,11 +205,21 @@ static Fl_Window *event_coords_from_surface(struct wl_surface *surface, static void pointer_enter(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t surface_x, wl_fixed_t surface_y) { Fl_Window *win = event_coords_from_surface(surface, surface_x, surface_y); - if (!win && gtk_shell) { // check that surface is the headerbar of a GTK-decorated window - Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver(); - if (fl_is_surface_gtk_titlebar(surface, scr_driver->libdecor_context, - Fl_Wayland_Screen_Driver::wl_display)) { - gtk_shell_surface = surface; + if (!win && gtk_shell) { // check whether surface is the headerbar of a GTK-decorated window + Fl_X *xp = Fl_X::first; + bool using_GTK = true; + while (xp && using_GTK) { // all mapped windows + struct wld_window *xid = (struct wld_window*)xp->xid; + if (xid->kind == Fl_Wayland_Window_Driver::DECORATED && + fl_is_surface_from_GTK_titlebar(surface, xid->frame, &using_GTK)) { + gtk_shell_surface = surface; + break; + } + xp = xp->next; + } + if (!using_GTK) { + gtk_shell1_destroy(gtk_shell); + gtk_shell = NULL; } } if (!win) return;