From 3cd3537ef8d077de9da2a041ee4268979feeb39d Mon Sep 17 00:00:00 2001 From: ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> Date: Fri, 4 Apr 2025 12:06:00 +0200 Subject: Update bundled libdecor to last upstream version (Apr 4, 2025) --- documentation/src/bundled-libs.dox | 4 +- libdecor/build/fl_libdecor.h | 1 + libdecor/src/libdecor-plugin.h | 3 ++ libdecor/src/libdecor.c | 29 ++++++++++++- libdecor/src/libdecor.h | 18 +++++++- libdecor/src/plugins/cairo/libdecor-cairo.c | 64 ++++++++++++++++++++++------- libdecor/src/plugins/dummy/libdecor-dummy.c | 8 ++++ libdecor/src/plugins/gtk/libdecor-gtk.c | 40 +++++++++++++----- 8 files changed, 139 insertions(+), 28 deletions(-) diff --git a/documentation/src/bundled-libs.dox b/documentation/src/bundled-libs.dox index c300f4606..1316f6a81 100644 --- a/documentation/src/bundled-libs.dox +++ b/documentation/src/bundled-libs.dox @@ -23,14 +23,14 @@ The nanosvg library is not affected. \section bundled-status Current status \code -Current versions of bundled libraries (as of March 19, 2025): +Current versions of bundled libraries (as of April 4, 2025): Library Version/git commit Release date FLTK Version -------------------------------------------------------------------------- jpeg jpeg-9f 2024-01-14 1.4.0 nanosvg 7aeda550a8 [1] 2023-12-02 1.4.0 png libpng-1.6.44 2024-09-12 1.4.1 zlib zlib-1.3.1 2024-01-22 1.4.0 - libdecor 8cbf2e89 [2] 2025-03-09 1.5.0 + libdecor 5974b6d4 [2] 2025-04-03 1.5.0 -------------------------------------------------------------------------- Previous versions of bundled libraries (FLTK 1.3.x): diff --git a/libdecor/build/fl_libdecor.h b/libdecor/build/fl_libdecor.h index 87cbd3199..97041c885 100644 --- a/libdecor/build/fl_libdecor.h +++ b/libdecor/build/fl_libdecor.h @@ -63,6 +63,7 @@ #define libdecor_frame_get_xdg_surface fl_libdecor_frame_get_xdg_surface #define libdecor_frame_get_xdg_toplevel fl_libdecor_frame_get_xdg_toplevel #define libdecor_frame_get_wm_capabilities fl_libdecor_frame_get_wm_capabilities +#define libdecor_set_handle_application_cursor fl_libdecor_set_handle_application_cursor #define libdecor_state_new fl_libdecor_state_new #define libdecor_state_free fl_libdecor_state_free #define libdecor_configuration_get_content_size fl_libdecor_configuration_get_content_size diff --git a/libdecor/src/libdecor-plugin.h b/libdecor/src/libdecor-plugin.h index ba80ce642..d57430e9c 100644 --- a/libdecor/src/libdecor-plugin.h +++ b/libdecor/src/libdecor-plugin.h @@ -92,6 +92,9 @@ struct libdecor_plugin_interface { int (* dispatch)(struct libdecor_plugin *plugin, int timeout); + void (* set_handle_application_cursor)(struct libdecor_plugin *plugin, + bool handle_cursor); + struct libdecor_frame * (* frame_new)(struct libdecor_plugin *plugin); void (* frame_free)(struct libdecor_plugin *plugin, struct libdecor_frame *frame); diff --git a/libdecor/src/libdecor.c b/libdecor/src/libdecor.c index 92d4f46e5..8cef57221 100644 --- a/libdecor/src/libdecor.c +++ b/libdecor/src/libdecor.c @@ -451,11 +451,28 @@ xdg_toplevel_close(void *user_data, #ifdef HAVE_XDG_SHELL_V6 static void -xdg_toplevel_configure_bounds(void *data, +xdg_toplevel_configure_bounds(void *user_data, struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height) { + struct libdecor_frame *frame = user_data; + struct libdecor_frame_private *frame_priv = frame->priv; + struct libdecor *context = frame_priv->context; + struct libdecor_plugin *plugin = context->plugin; + int left = 0, top = 0, right = 0, bottom = 0; + + if (frame_has_visible_client_side_decoration(frame) && + plugin->priv->iface->frame_get_border_size) { + plugin->priv->iface->frame_get_border_size(plugin, frame, NULL, + &left, &right, &top, &bottom); + } + + width -= left + right; + height -= top + bottom; + if (frame_priv->iface->bounds) { + frame_priv->iface->bounds(frame, width, height, frame_priv->user_data); + } } static void @@ -1261,6 +1278,16 @@ libdecor_frame_get_xdg_toplevel(struct libdecor_frame *frame) return frame->priv->xdg_toplevel; } +LIBDECOR_EXPORT void +libdecor_set_handle_application_cursor(struct libdecor *context, + bool handle_cursor) +{ + struct libdecor_plugin *plugin = context->plugin; + + plugin->priv->iface->set_handle_application_cursor(plugin, + handle_cursor); +} + LIBDECOR_EXPORT int libdecor_frame_get_content_width(struct libdecor_frame *frame) { diff --git a/libdecor/src/libdecor.h b/libdecor/src/libdecor.h index e52ced0cd..2158829fd 100644 --- a/libdecor/src/libdecor.h +++ b/libdecor/src/libdecor.h @@ -168,6 +168,15 @@ struct libdecor_frame_interface { const char *seat_name, void *user_data); + /** + * The recommended client region bounds for the window. + * This will be followed by a configure event. + */ + void (* bounds)(struct libdecor_frame *frame, + int width, + int height, + void *user_data); + /* Reserved */ void (* reserved0)(void); void (* reserved1)(void); @@ -178,7 +187,6 @@ struct libdecor_frame_interface { void (* reserved6)(void); void (* reserved7)(void); void (* reserved8)(void); - void (* reserved9)(void); }; /** @@ -543,6 +551,14 @@ libdecor_frame_get_xdg_toplevel(struct libdecor_frame *frame); enum libdecor_wm_capabilities libdecor_frame_get_wm_capabilities(struct libdecor_frame *frame); +/** + * Tell libdecor to set the default pointer cursor when the pointer is over an + * application surface. The default false. + */ +void +libdecor_set_handle_application_cursor(struct libdecor *context, + bool handle_cursor); + /** * Create a new content surface state. */ diff --git a/libdecor/src/plugins/cairo/libdecor-cairo.c b/libdecor/src/plugins/cairo/libdecor-cairo.c index 5978d431d..d8854bc8e 100644 --- a/libdecor/src/plugins/cairo/libdecor-cairo.c +++ b/libdecor/src/plugins/cairo/libdecor-cairo.c @@ -149,6 +149,7 @@ struct seat { struct wl_cursor *cursor_left_ptr; struct wl_surface *pointer_focus; + struct libdecor_frame_cairo *pointer_focus_frame; int pointer_x, pointer_y; @@ -279,6 +280,8 @@ struct libdecor_plugin_cairo { int cursor_size; PangoFontDescription *font; + + bool handle_cursor; }; static const char *libdecor_cairo_proxy_tag = "libdecor-cairo"; @@ -538,6 +541,16 @@ libdecor_plugin_cairo_dispatch(struct libdecor_plugin *plugin, } } +static void +libdecor_plugin_cairo_set_handle_application_cursor(struct libdecor_plugin *plugin, + bool handle_cursor) +{ + struct libdecor_plugin_cairo *plugin_cairo = + (struct libdecor_plugin_cairo *) plugin; + + plugin_cairo->handle_cursor = handle_cursor; +} + static struct libdecor_frame * libdecor_plugin_cairo_frame_new(struct libdecor_plugin *plugin) { @@ -685,9 +698,12 @@ libdecor_plugin_cairo_frame_free(struct libdecor_plugin *plugin, struct seat *seat; wl_list_for_each(seat, &plugin_cairo->seat_list, link) { - if (seat->pointer_focus != NULL && - wl_surface_get_user_data(seat->pointer_focus) == frame_cairo) - seat->pointer_focus = NULL; + if (seat->pointer_focus) { + if (wl_surface_get_user_data(seat->pointer_focus) == frame_cairo) + seat->pointer_focus = NULL; + if (seat->pointer_focus_frame == frame_cairo) + seat->pointer_focus_frame = NULL; + } } free_border_component(&frame_cairo->title_bar.title); @@ -812,6 +828,10 @@ update_component_focus(struct libdecor_frame_cairo *frame_cairo, static struct border_component *focus_component; border_component = get_component_for_surface(frame_cairo, surface); + if (!border_component) { + focus_component = NULL; + goto out; + } focus_component = border_component; wl_list_for_each(child_component, &border_component->child_components, link) { @@ -830,6 +850,7 @@ update_component_focus(struct libdecor_frame_cairo *frame_cairo, } } +out: if (frame_cairo->grab) frame_cairo->active = frame_cairo->grab; else @@ -1882,6 +1903,8 @@ static struct libdecor_plugin_interface cairo_plugin_iface = { .get_fd = libdecor_plugin_cairo_get_fd, .dispatch = libdecor_plugin_cairo_dispatch, + .set_handle_application_cursor = libdecor_plugin_cairo_set_handle_application_cursor, + .frame_new = libdecor_plugin_cairo_frame_new, .frame_free = libdecor_plugin_cairo_frame_free, .frame_commit = libdecor_plugin_cairo_frame_commit, @@ -2109,8 +2132,14 @@ update_local_cursor(struct seat *seat) return false; } - if (!own_surface(seat->pointer_focus)) - return false; + if (!own_surface(seat->pointer_focus)) { + if (seat->plugin_cairo->handle_cursor) { + seat->current_cursor = seat->cursor_left_ptr; + return true; + } else { + return false; + } + } struct libdecor_frame_cairo *frame_cairo = wl_surface_get_user_data(seat->pointer_focus); @@ -2195,7 +2224,7 @@ synthesize_pointer_enter(struct seat *seat) struct libdecor_frame_cairo *frame_cairo; surface = seat->pointer_focus; - if (!surface) + if (!surface || !own_surface(surface)) return; frame_cairo = wl_surface_get_user_data(surface); @@ -2222,7 +2251,7 @@ synthesize_pointer_leave(struct seat *seat) struct libdecor_frame_cairo *frame_cairo; surface = seat->pointer_focus; - if (!surface) + if (!surface || !own_surface(surface)) return; frame_cairo = wl_surface_get_user_data(surface); @@ -2247,12 +2276,20 @@ pointer_enter(void *data, wl_fixed_t surface_y) { struct seat *seat = data; + struct libdecor_frame_cairo *frame_cairo = NULL; if (!surface) return; - if (!own_surface(surface)) - return; + if (!own_surface(surface)) { + struct seat *seat = wl_pointer_get_user_data(wl_pointer); + struct libdecor_plugin_cairo *plugin_cairo = seat->plugin_cairo; + + if (!plugin_cairo->handle_cursor) + return; + } else { + frame_cairo = wl_surface_get_user_data(surface); + } ensure_cursor_surface(seat); @@ -2260,6 +2297,7 @@ pointer_enter(void *data, seat->pointer_y = wl_fixed_to_int(surface_y); seat->serial = serial; seat->pointer_focus = surface; + seat->pointer_focus_frame = frame_cairo; if (seat->grabbed) return; @@ -2283,6 +2321,7 @@ pointer_leave(void *data, synthesize_pointer_leave(seat); seat->pointer_focus = NULL; + seat->pointer_focus_frame = NULL; } static void @@ -2293,7 +2332,6 @@ pointer_motion(void *data, wl_fixed_t surface_y) { struct seat *seat = data; - struct libdecor_frame_cairo *frame_cairo; seat->pointer_x = wl_fixed_to_int(surface_x); seat->pointer_y = wl_fixed_to_int(surface_y); @@ -2301,12 +2339,10 @@ pointer_motion(void *data, if (seat->grabbed) return; - if (!seat->pointer_focus) + if (!seat->pointer_focus_frame) return; - frame_cairo = wl_surface_get_user_data(seat->pointer_focus); - - sync_active_component(frame_cairo, seat); + sync_active_component(seat->pointer_focus_frame, seat); } static void diff --git a/libdecor/src/plugins/dummy/libdecor-dummy.c b/libdecor/src/plugins/dummy/libdecor-dummy.c index 7dc2428ca..621dd027f 100644 --- a/libdecor/src/plugins/dummy/libdecor-dummy.c +++ b/libdecor/src/plugins/dummy/libdecor-dummy.c @@ -60,6 +60,12 @@ libdecor_plugin_dummy_frame_new(struct libdecor_plugin *plugin) return frame; } +static void +libdecor_plugin_dummy_set_handle_application_cursor(struct libdecor_plugin *plugin, + bool handle_cursor) +{ +} + static void libdecor_plugin_dummy_frame_free(struct libdecor_plugin *plugin, struct libdecor_frame *frame) @@ -97,6 +103,8 @@ libdecor_plugin_dummy_frame_popup_ungrab(struct libdecor_plugin *plugin, static struct libdecor_plugin_interface dummy_plugin_iface = { .destroy = libdecor_plugin_dummy_destroy, + .set_handle_application_cursor = libdecor_plugin_dummy_set_handle_application_cursor, + .frame_new = libdecor_plugin_dummy_frame_new, .frame_free = libdecor_plugin_dummy_frame_free, .frame_commit = libdecor_plugin_dummy_frame_commit, diff --git a/libdecor/src/plugins/gtk/libdecor-gtk.c b/libdecor/src/plugins/gtk/libdecor-gtk.c index 5f010958a..3f2a54473 100644 --- a/libdecor/src/plugins/gtk/libdecor-gtk.c +++ b/libdecor/src/plugins/gtk/libdecor-gtk.c @@ -342,6 +342,8 @@ struct libdecor_plugin_gtk { int double_click_time_ms; int drag_threshold; + + bool handle_cursor; }; static const char *libdecor_gtk_proxy_tag = "libdecor-gtk"; @@ -555,6 +557,16 @@ libdecor_plugin_gtk_dispatch(struct libdecor_plugin *plugin, } } +static void +libdecor_plugin_gtk_set_handle_application_cursor(struct libdecor_plugin *plugin, + bool handle_cursor) +{ + struct libdecor_plugin_gtk *plugin_gtk = + (struct libdecor_plugin_gtk *) plugin; + + plugin_gtk->handle_cursor = handle_cursor; +} + static struct libdecor_frame * libdecor_plugin_gtk_frame_new(struct libdecor_plugin *plugin) { @@ -1644,7 +1656,7 @@ synthesize_pointer_enter(struct seat *seat) struct libdecor_frame_gtk *frame_gtk; surface = seat->pointer_focus; - if (!surface) + if (!surface || !own_surface(surface)) return; frame_gtk = wl_surface_get_user_data(surface); @@ -1671,7 +1683,7 @@ synthesize_pointer_leave(struct seat *seat) struct libdecor_frame_gtk *frame_gtk; surface = seat->pointer_focus; - if (!surface) + if (!surface || !own_surface(surface)) return; frame_gtk = wl_surface_get_user_data(surface); @@ -1788,6 +1800,8 @@ static struct libdecor_plugin_interface gtk_plugin_iface = { .get_fd = libdecor_plugin_gtk_get_fd, .dispatch = libdecor_plugin_gtk_dispatch, + .set_handle_application_cursor = libdecor_plugin_gtk_set_handle_application_cursor, + .frame_new = libdecor_plugin_gtk_frame_new, .frame_free = libdecor_plugin_gtk_frame_free, .frame_commit = libdecor_plugin_gtk_frame_commit, @@ -2089,12 +2103,17 @@ pointer_enter(void *data, return; struct seat *seat = data; - struct libdecor_frame_gtk *frame_gtk; + struct libdecor_frame_gtk *frame_gtk = NULL; - if (!own_surface(surface)) - return; + if (!own_surface(surface)) { + struct seat *seat = wl_pointer_get_user_data(wl_pointer); + struct libdecor_plugin_gtk *plugin_gtk = seat->plugin_gtk; - frame_gtk = wl_surface_get_user_data(surface); + if (!plugin_gtk->handle_cursor) + return; + } else { + frame_gtk = wl_surface_get_user_data(surface); + } ensure_cursor_surface(seat); @@ -2124,18 +2143,19 @@ pointer_leave(void *data, uint32_t serial, struct wl_surface *surface) { - if (!surface) - return; - struct seat *seat = data; struct libdecor_frame_gtk *frame_gtk; + seat->pointer_focus = NULL; + + if (!surface) + return; + if (!own_surface(surface)) return; frame_gtk = wl_surface_get_user_data(surface); - seat->pointer_focus = NULL; if (frame_gtk) { frame_gtk->titlebar_gesture.state = TITLEBAR_GESTURE_STATE_INIT; -- cgit v1.2.3