FLTK implementation of the "GTK Shell" Wayland protocol - cont'd

The loop over all libdecor-gtk decorations is now made using libdecor's
data structures, rather than using FLTK's mapped window list.
This commit is contained in:
ManoloFLTK 2023-12-14 07:55:31 +01:00
parent 6ac3e8e230
commit 673fa2e09c
2 changed files with 57 additions and 24 deletions

View File

@ -175,16 +175,28 @@ struct libdecor_frame_cairo {
/* Definitions derived from libdecor-gtk.c */
typedef struct _GtkWidget GtkWidget;
enum header_element {
HEADER_NONE,
HEADER_FULL, /* entire header bar */
HEADER_TITLE, /* label */
HEADER_MIN,
HEADER_MAX,
HEADER_CLOSE,
struct libdecor_plugin_gtk {
struct libdecor_plugin plugin;
struct wl_callback *globals_callback;
struct wl_callback *globals_callback_shm;
struct libdecor *context;
struct wl_registry *wl_registry;
struct wl_subcompositor *wl_subcompositor;
struct wl_compositor *wl_compositor;
struct wl_shm *wl_shm;
struct wl_callback *shm_callback;
bool has_argb;
struct wl_list visible_frame_list;
struct wl_list seat_list;
struct wl_list output_list;
char *cursor_theme_name;
int cursor_size;
int double_click_time_ms;
};
typedef struct _GtkWidget GtkWidget;
enum header_element { HEADER_NONE }; /* details are not needed */
typedef enum { GTK_STATE_FLAG_NORMAL = 0 } GtkStateFlags;
struct border_component_gtk {
@ -338,11 +350,38 @@ unsigned char *fl_libdecor_titlebar_buffer(struct libdecor_frame *frame,
}
/* returns the wl_surface of the window's headerbar for GTK */
struct wl_surface *fl_headerbar_surface(struct libdecor_frame *frame) {
if (!strcmp(plugin_name(frame), "GTK3 plugin")) {
struct libdecor_frame_gtk *lfg = (struct libdecor_frame_gtk *)frame;
return lfg->headerbar.wl_surface;
struct libdecor { // copied from libdecor.c
int ref_count;
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) {
static bool checked_plugin_name = false;
static bool is_gtk = true;
if (!context || !is_gtk) return false;
struct libdecor_plugin_gtk *lpg = (struct libdecor_plugin_gtk *)context->plugin;
struct libdecor_frame_gtk *frame;
if (!checked_plugin_name && !wl_list_empty(&lpg->visible_frame_list)) {
checked_plugin_name = true;
frame = wl_container_of(lpg->visible_frame_list.next, frame, link);
is_gtk = !strcmp(plugin_name(&frame->frame), "GTK3 plugin");
if (!is_gtk) return false;
}
return NULL;
// loop over all decorations created by libdecor-gtk
wl_list_for_each(frame, &lpg->visible_frame_list, link) {
if (frame->headerbar.wl_surface == surface) return true;
}
return false;
}

View File

@ -47,7 +47,7 @@
#include <string.h> // for strerror()
extern "C" {
bool libdecor_get_cursor_settings(char **theme, int *size);
struct wl_surface *fl_headerbar_surface(struct libdecor_frame *frame);
bool fl_is_surface_gtk_titlebar(struct wl_surface *, struct libdecor *);
}
@ -203,15 +203,9 @@ static void pointer_enter(void *data, struct wl_pointer *wl_pointer, uint32_t se
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_X *x = Fl_X::first;
while (x) {
struct wld_window *xid = (struct wld_window*)x->xid;
if (xid->kind == Fl_Wayland_Window_Driver::DECORATED &&
surface == fl_headerbar_surface(xid->frame)) {
gtk_shell_surface = surface;
return;
}
x = x->next;
Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver();
if (fl_is_surface_gtk_titlebar(surface, scr_driver->libdecor_context)) {
gtk_shell_surface = surface;
}
}
if (!win) return;