From 85814a2bca157db51566c5307bd0fae04a141e6f Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Fri, 27 Feb 2026 10:38:36 -0800 Subject: [PATCH] [digesting_libdecor] remove frame's refcount --- digesting_libdecor.c | 732 ++++++++++++++++++------------------------- digesting_libdecor.h | 11 - 2 files changed, 302 insertions(+), 441 deletions(-) diff --git a/digesting_libdecor.c b/digesting_libdecor.c index 2538bda..15fc5f6 100755 --- a/digesting_libdecor.c +++ b/digesting_libdecor.c @@ -105,15 +105,29 @@ wlevent__wl_registry_global(void *data, struct wl_registry *wl_registry, xdg_wm_base_add_listener(ctx.xdg_wm_base, &xdg_wm_base_listener, 0); } else if (!strcmp(interface, zxdg_decoration_manager_v1_interface.name)){ - ctx.decoration_manager = wl_registry_bind(wl_registry, name, &zxdg_decoration_manager_v1_interface, MIN(version, 2)); + uint32_t desired_version = 2; + + /* Find the required version for the available features. */ +#ifdef XDG_TOPLEVEL_STATE_CONSTRAINED_LEFT_SINCE_VERSION + desired_version = MAX(desired_version, XDG_TOPLEVEL_STATE_CONSTRAINED_LEFT_SINCE_VERSION); +#endif +#ifdef XDG_TOPLEVEL_STATE_SUSPENDED_SINCE_VERSION + desired_version = MAX(desired_version, XDG_TOPLEVEL_STATE_SUSPENDED_SINCE_VERSION); +#endif +#ifdef XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION + desired_version = MAX(desired_version, XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION); +#endif +#ifdef XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION + desired_version = MAX(desired_version, XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION); +#endif + + ctx.decoration_manager = wl_registry_bind(wl_registry, name, &zxdg_decoration_manager_v1_interface, MIN(version, desired_version)); } else if (strcmp(interface, "wl_subcompositor") == 0){ - ctx.wl_subcompositor = - wl_registry_bind(ctx.wl_registry, name, &wl_subcompositor_interface, 1); + ctx.wl_subcompositor = wl_registry_bind(ctx.wl_registry, name, &wl_subcompositor_interface, 1); } else if (strcmp(interface, "wl_shm") == 0){ - ctx.wl_shm = - wl_registry_bind(ctx.wl_registry, name, &wl_shm_interface, 1); + ctx.wl_shm = wl_registry_bind(ctx.wl_registry, name, &wl_shm_interface, 1); wl_shm_add_listener(ctx.wl_shm, &shm_listener, 0); } else if (strcmp(interface, "wl_seat") == 0){ @@ -139,8 +153,7 @@ wlevent__wl_registry_global(void *data, struct wl_registry *wl_registry, wl_list_insert(&ctx.output_list, &output->link); output->id = name; output->wl_output = wl_registry_bind(ctx.wl_registry, name, &wl_output_interface, MIN(version, 3)); - wl_proxy_set_tag((struct wl_proxy *)output->wl_output, - &libdecor_gtk_proxy_tag); + wl_proxy_set_tag((struct wl_proxy *)output->wl_output, &libdecor_gtk_proxy_tag); wl_output_add_listener(output->wl_output, &output_listener, output); } } @@ -414,9 +427,6 @@ int main(){ ctx.frame->shadow_blur = shadow_blur; } - ctx.frame->ref_count = 1; - - ctx.frame->wl_surface = ctx.wl_surface; ctx.frame->wm_capabilities = (LIBDECOR_WM_CAPABILITIES_WINDOW_MENU | LIBDECOR_WM_CAPABILITIES_MAXIMIZE | LIBDECOR_WM_CAPABILITIES_FULLSCREEN | @@ -425,14 +435,13 @@ int main(){ wl_list_insert(&ctx.visible_frame_list, &ctx.frame->gtk_link); ctx.frame->visible = true; - set_capabilities(ctx.frame, - LIBDECOR_ACTION_MOVE | - LIBDECOR_ACTION_RESIZE | - LIBDECOR_ACTION_MINIMIZE | - LIBDECOR_ACTION_FULLSCREEN | - LIBDECOR_ACTION_CLOSE); + set_capabilities(ctx.frame, (LIBDECOR_ACTION_MOVE | + LIBDECOR_ACTION_RESIZE | + LIBDECOR_ACTION_MINIMIZE | + LIBDECOR_ACTION_FULLSCREEN | + LIBDECOR_ACTION_CLOSE)); - ctx.frame->xdg_surface = xdg_wm_base_get_xdg_surface(ctx.xdg_wm_base, ctx.frame->wl_surface); + ctx.frame->xdg_surface = xdg_wm_base_get_xdg_surface(ctx.xdg_wm_base, ctx.wl_surface); xdg_surface_add_listener(ctx.frame->xdg_surface, &xdg_surface_listener, ctx.frame); ctx.frame->xdg_toplevel = xdg_surface_get_toplevel(ctx.frame->xdg_surface); @@ -452,7 +461,7 @@ int main(){ ctx.frame->content_limits.min_width = 80; ctx.frame->content_limits.min_height = 60; - wl_surface_commit(ctx.frame->wl_surface); + wl_surface_commit(ctx.wl_surface); /* (nodocs-wl_egl) */ ctx.wl_egl_window = wl_egl_window_create(ctx.wl_surface, ctx.w, ctx.h); @@ -660,12 +669,6 @@ libdecor_configuration_new(void) return configuration; } -static void -libdecor_configuration_free(struct libdecor_configuration *configuration) -{ - free(configuration); -} - static bool frame_get_window_size_for(struct libdecor_frame *frame, struct libdecor_state *state, @@ -789,7 +792,7 @@ xdg_surface_configure(void *user_data, struct xdg_surface *xdg_surface, uint32_t } } - libdecor_configuration_free(configuration); + free(configuration); } const struct xdg_surface_listener xdg_surface_listener = { @@ -965,39 +968,31 @@ xdg_toplevel_decoration_listener = { toplevel_decoration_configure, }; -void -libdecor_frame_ref(struct libdecor_frame *frame){ - frame->ref_count++; -} - void libdecor_frame_unref(struct libdecor_frame *frame){ - frame->ref_count--; - if (frame->ref_count == 0) { - if (ctx.decoration_manager && frame->toplevel_decoration) { - zxdg_toplevel_decoration_v1_destroy(frame->toplevel_decoration); - frame->toplevel_decoration = NULL; - } - - wl_list_remove(&frame->frame_link); - - if (frame->xdg_toplevel) - xdg_toplevel_destroy(frame->xdg_toplevel); - if (frame->xdg_surface) - xdg_surface_destroy(frame->xdg_surface); - - libdecor_plugin_gtk_frame_free(frame); - - free(frame->title); - free(frame->app_id); - - free(frame); + if (ctx.decoration_manager && frame->toplevel_decoration){ + zxdg_toplevel_decoration_v1_destroy(frame->toplevel_decoration); + frame->toplevel_decoration = NULL; } + + wl_list_remove(&frame->frame_link); + + if (frame->xdg_toplevel){ + xdg_toplevel_destroy(frame->xdg_toplevel); + } + if (frame->xdg_surface != 0){ + xdg_surface_destroy(frame->xdg_surface); + } + + libdecor_plugin_gtk_frame_free(frame); + + free(frame->title); + free(frame->app_id); + free(frame); } void -libdecor_frame_set_visibility(struct libdecor_frame *frame, - bool visible){ +libdecor_frame_set_visibility(struct libdecor_frame *frame, bool visible){ frame->visible = visible; /* enable/disable decorations that are managed by the compositor. @@ -1172,24 +1167,6 @@ libdecor_frame_move(struct libdecor_frame *frame, struct wl_seat *wl_seat, uint3 xdg_toplevel_move(frame->xdg_toplevel, wl_seat, serial); } -void -libdecor_frame_set_minimized(struct libdecor_frame *frame) -{ - xdg_toplevel_set_minimized(frame->xdg_toplevel); -} - -void -libdecor_frame_set_maximized(struct libdecor_frame *frame) -{ - xdg_toplevel_set_maximized(frame->xdg_toplevel); -} - -void -libdecor_frame_unset_maximized(struct libdecor_frame *frame) -{ - xdg_toplevel_unset_maximized(frame->xdg_toplevel); -} - void libdecor_frame_set_fullscreen(struct libdecor_frame *frame, struct wl_output *output) @@ -1209,12 +1186,6 @@ libdecor_frame_is_floating(struct libdecor_frame *frame) return state_is_floating(frame->frame_window_state); } -void -libdecor_frame_close(struct libdecor_frame *frame) -{ - xdg_toplevel_close(frame, frame->xdg_toplevel); -} - bool valid_limits(struct libdecor_frame *frame) { @@ -1727,8 +1698,7 @@ os_resize_anonymous_file(int fd, off_t size) * XDG_RUNTIME_DIR. */ int -libdecor_os_create_anonymous_file(off_t size) -{ +libdecor_os_create_anonymous_file(off_t size){ static const char template[] = "/libdecor-shared-XXXXXX"; const char *path; char *name; @@ -1779,13 +1749,11 @@ libdecor_os_create_anonymous_file(off_t size) //#include "plugins/gtk/libdecor-gtk.c" static void -find_widget_by_name(GtkWidget *widget, void *data) -{ - if (GTK_IS_WIDGET(widget)) { - char *style_ctx = gtk_style_context_to_string( - gtk_widget_get_style_context(widget), +find_widget_by_name(GtkWidget *widget, void *data){ + if (GTK_IS_WIDGET(widget)){ + char *style_ctx = gtk_style_context_to_string(gtk_widget_get_style_context(widget), GTK_STYLE_CONTEXT_PRINT_SHOW_STYLE); - if (strstr(style_ctx, ((struct header_element_data *)data)->name)) { + if (strstr(style_ctx, ((struct header_element_data *)data)->name)){ ((struct header_element_data *)data)->widget = widget; free(style_ctx); return; @@ -1800,27 +1768,15 @@ find_widget_by_name(GtkWidget *widget, void *data) } static struct header_element_data -find_widget_by_type(GtkWidget *widget, enum header_element type) -{ - char* name = NULL; - switch (type) { - case HEADER_FULL: - name = "headerbar.titlebar:"; - break; - case HEADER_TITLE: - name = "label.title:"; - break; - case HEADER_MIN: - name = ".minimize"; - break; - case HEADER_MAX: - name = ".maximize"; - break; - case HEADER_CLOSE: - name = ".close"; - break; - default: - break; +find_widget_by_type(GtkWidget *widget, enum header_element type){ + char* name = 0; + switch (type){ + case HEADER_FULL: name = "headerbar.titlebar:"; break; + case HEADER_TITLE: name = "label.title:"; break; + case HEADER_MIN: name = ".minimize"; break; + case HEADER_MAX: name = ".maximize"; break; + case HEADER_CLOSE: name = ".close"; break; + default:break; } struct header_element_data data = {.name = name, .type = type, .widget = NULL}; @@ -1829,15 +1785,13 @@ find_widget_by_type(GtkWidget *widget, enum header_element type) } static bool -in_region(const cairo_rectangle_int_t *rect, const int *x, const int *y) -{ +in_region(const cairo_rectangle_int_t *rect, const int *x, const int *y){ return (*x>=rect->x) & (*y>=rect->y) & (*x<(rect->x+rect->width)) & (*y<(rect->y+rect->height)); } static struct header_element_data -get_header_focus(const GtkHeaderBar *header_bar, const int x, const int y) -{ +get_header_focus(const GtkHeaderBar *header_bar, const int x, const int y){ /* we have to check child widgets (buttons, title) before the 'HDR_HDR' root widget */ static const enum header_element elems[] = {HEADER_TITLE, HEADER_MIN, HEADER_MAX, HEADER_CLOSE}; @@ -1858,23 +1812,19 @@ get_header_focus(const GtkHeaderBar *header_bar, const int x, const int y) } static bool -own_proxy(struct wl_proxy *proxy) -{ +own_proxy(struct wl_proxy *proxy){ if (!proxy) return false; - return (wl_proxy_get_tag(proxy) == &libdecor_gtk_proxy_tag); } static bool -own_surface(struct wl_surface *surface) -{ +own_surface(struct wl_surface *surface){ return own_proxy((struct wl_proxy *) surface); } static bool -own_output(struct wl_output *output) -{ +own_output(struct wl_output *output){ return own_proxy((struct wl_proxy *) output); } @@ -1892,11 +1842,6 @@ send_cursor(struct seat *seat); static bool update_local_cursor(struct seat *seat); -static int -libdecor_plugin_gtk_get_fd(void){ - return wl_display_get_fd(ctx.wl_display); -} - static int libdecor_plugin_gtk_dispatch(int timeout){ struct wl_display *wl_display = ctx.wl_display; @@ -1942,14 +1887,12 @@ libdecor_plugin_gtk_set_handle_application_cursor(bool handle_cursor){ } static void -toggle_maximized(struct libdecor_frame *const frame){ - if ((frame->frame_capabilities & LIBDECOR_ACTION_RESIZE)){ - if (!(frame->frame_window_state & LIBDECOR_WINDOW_STATE_MAXIMIZED)){ - libdecor_frame_set_maximized(frame); - } - else{ - libdecor_frame_unset_maximized(frame); - } +toggle_maximized(void){ + if (ctx.frame->frame_window_state & LIBDECOR_WINDOW_STATE_MAXIMIZED){ + xdg_toplevel_unset_maximized(ctx.frame->xdg_toplevel); + } + else{ + xdg_toplevel_set_maximized(ctx.frame->xdg_toplevel); } } @@ -2051,21 +1994,21 @@ free_border_component(struct border_component *border_component){ static void libdecor_plugin_gtk_frame_free(struct libdecor_frame *frame){ - g_clear_pointer (&frame->header, gtk_widget_destroy); - g_clear_pointer (&frame->window, gtk_widget_destroy); + g_clear_pointer(&frame->header, gtk_widget_destroy); + g_clear_pointer(&frame->window, gtk_widget_destroy); free_border_component(&frame->headerbar); free_border_component(&frame->shadow); frame->shadow_showing = false; - g_clear_pointer (&frame->shadow_blur, cairo_surface_destroy); - - g_clear_pointer (&frame->title, free); + g_clear_pointer(&frame->shadow_blur, cairo_surface_destroy); + g_clear_pointer(&frame->title, free); frame->decoration_type = DECORATION_TYPE_NONE; - if (frame->gtk_link.next != NULL) + if (frame->gtk_link.next != 0){ wl_list_remove(&frame->gtk_link); + } } static bool @@ -2211,8 +2154,7 @@ static struct wl_surface_listener surface_listener = { static void create_surface_subsurface_pair(struct libdecor_frame *frame, struct wl_surface **out_wl_surface, - struct wl_subsurface **out_wl_subsurface) -{ + struct wl_subsurface **out_wl_subsurface){ struct wl_compositor *wl_compositor = ctx.wl_compositor; struct wl_surface *wl_surface; struct wl_surface *parent; @@ -2221,7 +2163,7 @@ create_surface_subsurface_pair(struct libdecor_frame *frame, wl_surface = wl_compositor_create_surface(wl_compositor); wl_proxy_set_tag((struct wl_proxy *) wl_surface, &libdecor_gtk_proxy_tag); - parent = frame->wl_surface; + parent = ctx.wl_surface; wl_subsurface = wl_subcompositor_get_subsurface(ctx.wl_subcompositor, wl_surface, parent); *out_wl_surface = wl_surface; @@ -2564,8 +2506,7 @@ draw_component_content(struct libdecor_frame *frame, struct buffer *buffer, int component_width, int component_height, - enum component component) -{ + enum component component){ cairo_surface_t *surface; cairo_t *cr; @@ -2616,9 +2557,8 @@ draw_component_content(struct libdecor_frame *frame, static void set_component_input_region(struct libdecor_frame *frame, - struct border_component *border_component) -{ - if (border_component->type == SHADOW && frame->shadow_showing) { + struct border_component *border_component){ + if (border_component->type == SHADOW && frame->shadow_showing){ struct wl_region *input_region; int component_x; int component_y; @@ -2648,8 +2588,7 @@ set_component_input_region(struct libdecor_frame *frame, static void draw_border_component(struct libdecor_frame *frame, struct border_component *border_component, - enum component component) -{ + enum component component){ struct buffer *old_buffer; struct buffer *buffer = NULL; int component_x; @@ -2668,22 +2607,24 @@ draw_border_component(struct libdecor_frame *frame, set_component_input_region(frame, border_component); old_buffer = border_component->buffer; - if (old_buffer) { + if (old_buffer){ if (!old_buffer->in_use && old_buffer->buffer_width == component_width * scale && - old_buffer->buffer_height == component_height * scale) { + old_buffer->buffer_height == component_height * scale){ buffer = old_buffer; - } else { + } + else{ buffer_free(old_buffer); border_component->buffer = NULL; } } - if (!buffer) + if (!buffer){ buffer = create_shm_buffer(component_width, component_height, border_component->opaque, border_component->scale); + } draw_component_content(frame, buffer, component_width, component_height, @@ -2703,15 +2644,13 @@ draw_border_component(struct libdecor_frame *frame, } static void -draw_border(struct libdecor_frame *frame) -{ +draw_border(struct libdecor_frame *frame){ draw_border_component(frame, &frame->shadow, SHADOW); frame->shadow_showing = true; } static void -draw_title_bar(struct libdecor_frame *frame) -{ +draw_title_bar(struct libdecor_frame *frame){ GtkAllocation allocation = {0, 0, frame->gtk_content_width, 0}; enum libdecor_window_state state; GtkStyleContext *style; @@ -2721,15 +2660,17 @@ draw_title_bar(struct libdecor_frame *frame) state = frame->frame_window_state; style = gtk_widget_get_style_context(frame->window); - if (!(state & LIBDECOR_WINDOW_STATE_ACTIVE)) { + if (!(state & LIBDECOR_WINDOW_STATE_ACTIVE)){ gtk_widget_set_state_flags(frame->window, GTK_STATE_FLAG_BACKDROP, true); - } else { + } + else{ gtk_widget_unset_state_flags(frame->window, GTK_STATE_FLAG_BACKDROP); } - if (libdecor_frame_is_floating(frame)) { + if (libdecor_frame_is_floating(frame)){ gtk_style_context_remove_class(style, "maximized"); - } else { + } + else{ gtk_style_context_add_class(style, "maximized"); } @@ -2748,23 +2689,20 @@ draw_title_bar(struct libdecor_frame *frame) } W = frame->frame_content_width; H = frame->frame_content_height; - if (W < frame->content_limits.min_width) { + if (W < frame->content_limits.min_width){ W = frame->content_limits.min_width; libdecor_frame_commit(frame, W, H, NULL); - return; } - - /* set default height */ - gtk_widget_get_preferred_height(frame->header, NULL, &allocation.height); - - gtk_widget_size_allocate(frame->header, &allocation); - - draw_border_component(frame, &frame->headerbar, HEADER); + else{ + /* set default height */ + gtk_widget_get_preferred_height(frame->header, NULL, &allocation.height); + gtk_widget_size_allocate(frame->header, &allocation); + draw_border_component(frame, &frame->headerbar, HEADER); + } } static void -draw_decoration(struct libdecor_frame *frame) -{ +draw_decoration(struct libdecor_frame *frame){ switch (frame->decoration_type) { case DECORATION_TYPE_NONE: { if (frame->gtk_link.next != NULL){ @@ -2807,25 +2745,27 @@ draw_decoration(struct libdecor_frame *frame) static enum decoration_type window_state_to_decoration_type(enum libdecor_window_state window_state) { - if (window_state & LIBDECOR_WINDOW_STATE_FULLSCREEN) + if (window_state & LIBDECOR_WINDOW_STATE_FULLSCREEN){ return DECORATION_TYPE_NONE; - else if (window_state & LIBDECOR_WINDOW_STATE_MAXIMIZED || - window_state & LIBDECOR_WINDOW_STATE_TILED_LEFT || - window_state & LIBDECOR_WINDOW_STATE_TILED_RIGHT || - window_state & LIBDECOR_WINDOW_STATE_TILED_TOP || - window_state & LIBDECOR_WINDOW_STATE_TILED_BOTTOM) - /* title bar, no shadows */ + } + else if (window_state & (LIBDECOR_WINDOW_STATE_MAXIMIZED | + LIBDECOR_WINDOW_STATE_TILED_LEFT | + LIBDECOR_WINDOW_STATE_TILED_RIGHT | + LIBDECOR_WINDOW_STATE_TILED_TOP | + LIBDECOR_WINDOW_STATE_TILED_BOTTOM)){ + /* title bar, no shadows */ return DECORATION_TYPE_TITLE_ONLY; - else - /* title bar, shadows */ + } + else{ + /* title bar, shadows */ return DECORATION_TYPE_ALL; + } } static void libdecor_plugin_gtk_frame_commit(struct libdecor_frame *frame, struct libdecor_state *state, - struct libdecor_configuration *configuration) -{ + struct libdecor_configuration *configuration){ enum libdecor_window_state old_window_state; enum libdecor_window_state new_window_state; int old_content_width, old_content_height; @@ -2914,13 +2854,13 @@ sync_active_component(struct libdecor_frame *frame, struct seat *seat){ wl_surface_commit(ctx.wl_surface); } - if (update_local_cursor(seat)) + if (update_local_cursor(seat)){ send_cursor(seat); + } } static void -synthesize_pointer_enter(struct seat *seat) -{ +synthesize_pointer_enter(struct seat *seat){ struct wl_surface *surface; struct libdecor_frame *frame; @@ -2929,42 +2869,35 @@ synthesize_pointer_enter(struct seat *seat) return; frame = wl_surface_get_user_data(surface); - if (!frame) - return; - - update_component_focus(frame, seat->pointer_focus, seat); - frame->grab = NULL; - - /* update decorations */ - if (frame->active) { - draw_decoration(frame); - wl_surface_commit(ctx.wl_surface); + if (frame != 0){ + update_component_focus(frame, seat->pointer_focus, seat); + frame->grab = NULL; + + /* update decorations */ + if (frame->active) { + draw_decoration(frame); + wl_surface_commit(ctx.wl_surface); + } + + update_local_cursor(seat); + send_cursor(seat); } - - update_local_cursor(seat); - send_cursor(seat); } static void synthesize_pointer_leave(struct seat *seat){ - struct wl_surface *surface; - struct libdecor_frame *frame; - - surface = seat->pointer_focus; - if (!surface || !own_surface(surface)) - return; - - frame = wl_surface_get_user_data(surface); - if (!frame) - return; - - if (!frame->active) - return; - - frame->active = NULL; - draw_decoration(frame); - wl_surface_commit(ctx.wl_surface); - update_local_cursor(seat); + struct wl_surface *surface = seat->pointer_focus; + if (surface != 0 && own_surface(surface)){ + struct libdecor_frame *frame = wl_surface_get_user_data(surface); + if (frame != 0){ + if (frame->active != 0){ + frame->active = 0; + draw_decoration(frame); + wl_surface_commit(ctx.wl_surface); + update_local_cursor(seat); + } + } + } } static void @@ -2986,8 +2919,7 @@ libdecor_plugin_gtk_frame_popup_grab(struct libdecor_frame *frame, const char *s } static void -libdecor_plugin_gtk_frame_popup_ungrab(struct libdecor_frame *frame, - const char *seat_name){ +libdecor_plugin_gtk_frame_popup_ungrab(struct libdecor_frame *frame, const char *seat_name){ struct seat *seat; wl_list_for_each(seat, &ctx.seat_list, link) { @@ -3003,23 +2935,18 @@ libdecor_plugin_gtk_frame_popup_ungrab(struct libdecor_frame *frame, } } - fprintf(stderr, - "libdecor-WARNING: Application tried to ungrab unknown seat\n"); + fprintf(stderr, "libdecor-WARNING: Application tried to ungrab unknown seat\n"); } static bool -libdecor_plugin_gtk_frame_get_border_size(struct libdecor_frame *frame, - struct libdecor_configuration *configuration, - int *left, - int *right, - int *top, - int *bottom) -{ +libdecor_plugin_gtk_frame_get_border_size(struct libdecor_frame *frame, struct libdecor_configuration *configuration, + int *left, int *right, int *top, int *bottom){ enum libdecor_window_state window_state; if (configuration) { - if (!libdecor_configuration_get_window_state(configuration, &window_state)) + if (!libdecor_configuration_get_window_state(configuration, &window_state)){ return false; + } } else{ window_state = frame->frame_window_state; @@ -3060,12 +2987,8 @@ libdecor_plugin_gtk_frame_get_border_size(struct libdecor_frame *frame, } static void -cursor_surface_enter(void *data, - struct wl_surface *wl_surface, - struct wl_output *wl_output) -{ +cursor_surface_enter(void *data, struct wl_surface *wl_surface, struct wl_output *wl_output){ struct seat *seat = data; - if (own_output(wl_output)) { struct cursor_output *cursor_output; cursor_output = calloc(1, sizeof *cursor_output); @@ -3077,10 +3000,7 @@ cursor_surface_enter(void *data, } static void -cursor_surface_leave(void *data, - struct wl_surface *wl_surface, - struct wl_output *wl_output) -{ +cursor_surface_leave(void *data, struct wl_surface *wl_surface, struct wl_output *wl_output){ struct seat *seat = data; if (own_output(wl_output)) { @@ -3116,8 +3036,7 @@ ensure_cursor_surface(struct seat *seat) } static bool -ensure_cursor_theme(struct seat *seat) -{ +ensure_cursor_theme(struct seat *seat){ int scale = 1; struct wl_cursor_theme *theme; struct cursor_output *cursor_output; @@ -3155,41 +3074,42 @@ ensure_cursor_theme(struct seat *seat) enum libdecor_resize_edge component_edge(const struct border_component *cmpnt, - const int pointer_x, - const int pointer_y, - const int margin) -{ + const int pointer_x, const int pointer_y, + const int margin){ const bool top = pointer_y < margin * 2; const bool bottom = pointer_y > (cmpnt->buffer->height - margin * 2); const bool left = pointer_x < margin * 2; const bool right = pointer_x > (cmpnt->buffer->width - margin * 2); - if (top) { + if (top){ if (left) return LIBDECOR_RESIZE_EDGE_TOP_LEFT; else if (right) return LIBDECOR_RESIZE_EDGE_TOP_RIGHT; else return LIBDECOR_RESIZE_EDGE_TOP; - } else if (bottom) { + } + else if (bottom){ if (left) return LIBDECOR_RESIZE_EDGE_BOTTOM_LEFT; else if (right) return LIBDECOR_RESIZE_EDGE_BOTTOM_RIGHT; else return LIBDECOR_RESIZE_EDGE_BOTTOM; - } else if (left) { + } + else if (left){ return LIBDECOR_RESIZE_EDGE_LEFT; - } else if (right) { + } + else if (right){ return LIBDECOR_RESIZE_EDGE_RIGHT; - } else { + } + else{ return LIBDECOR_RESIZE_EDGE_NONE; } } static bool -update_local_cursor(struct seat *seat) -{ +update_local_cursor(struct seat *seat){ if (!seat->pointer_focus) { seat->current_cursor = seat->cursor_left_ptr; return false; @@ -3254,13 +3174,8 @@ send_cursor(struct seat *seat) } 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) -{ +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){ if (!surface) return; @@ -3268,7 +3183,6 @@ pointer_enter(void *data, struct libdecor_frame *frame = 0; if (!own_surface(surface)){ - struct seat *seat = wl_pointer_get_user_data(wl_pointer); if (!ctx.handle_cursor){ return; } @@ -3300,43 +3214,31 @@ pointer_enter(void *data, } static void -pointer_leave(void *data, - struct wl_pointer *wl_pointer, - uint32_t serial, - struct wl_surface *surface) -{ +pointer_leave(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface){ struct seat *seat = data; - struct libdecor_frame *frame; seat->pointer_focus = NULL; - if (!surface) - return; - - if (!own_surface(surface)) - return; - - frame = wl_surface_get_user_data(surface); - - if (frame) { - frame->titlebar_gesture.state = TITLEBAR_GESTURE_STATE_INIT; - frame->titlebar_gesture.first_pressed_button = 0; + if (surface != 0 && own_surface(surface)){ + struct libdecor_frame *frame = wl_surface_get_user_data(surface); - frame->active = NULL; - frame->hdr_focus.widget = NULL; - frame->hdr_focus.type = HEADER_NONE; - draw_decoration(frame); - wl_surface_commit(ctx.wl_surface); - update_local_cursor(seat); + if (frame != 0){ + frame->titlebar_gesture.state = TITLEBAR_GESTURE_STATE_INIT; + frame->titlebar_gesture.first_pressed_button = 0; + + frame->active = NULL; + frame->hdr_focus.widget = NULL; + frame->hdr_focus.type = HEADER_NONE; + draw_decoration(frame); + wl_surface_commit(ctx.wl_surface); + update_local_cursor(seat); + } } } static void -pointer_motion(void *data, - struct wl_pointer *wl_pointer, - uint32_t time, - wl_fixed_t surface_x, - wl_fixed_t surface_y){ +pointer_motion(void *data, struct wl_pointer *wl_pointer, uint32_t time, + wl_fixed_t surface_x, wl_fixed_t surface_y){ struct seat *seat = data; struct libdecor_frame *frame; struct header_element_data new_focus; @@ -3346,8 +3248,9 @@ pointer_motion(void *data, seat->pointer_x = wl_fixed_to_int(surface_x); seat->pointer_y = wl_fixed_to_int(surface_y); - if (update_local_cursor(seat)) + if (update_local_cursor(seat)){ send_cursor(seat); + } frame = wl_surface_get_user_data(seat->pointer_focus); /* avoid warnings after decoration has been turned off */ @@ -3388,12 +3291,9 @@ pointer_motion(void *data, } static void -handle_button_on_shadow(struct libdecor_frame *frame, - struct seat *seat, - uint32_t serial, - uint32_t time, - uint32_t button, - uint32_t state){ +handle_button_on_shadow(struct libdecor_frame *frame, struct seat *seat, + uint32_t serial, uint32_t time, + uint32_t button, uint32_t state){ enum libdecor_resize_edge edge = LIBDECOR_RESIZE_EDGE_NONE; edge = component_edge(frame->active, seat->pointer_x, seat->pointer_y, SHADOW_MARGIN); if (edge != LIBDECOR_RESIZE_EDGE_NONE && @@ -3403,14 +3303,13 @@ handle_button_on_shadow(struct libdecor_frame *frame, } static void -handle_titlebar_gesture(struct libdecor_frame *frame, - struct seat *seat, - uint32_t serial, - enum titlebar_gesture gesture) -{ - switch (gesture) { +handle_titlebar_gesture(struct libdecor_frame *frame, struct seat *seat, + uint32_t serial, enum titlebar_gesture gesture){ + switch (gesture){ case TITLEBAR_GESTURE_DOUBLE_CLICK: { - toggle_maximized(frame); + if ((frame->frame_capabilities & LIBDECOR_ACTION_RESIZE)){ + toggle_maximized(); + } }break; case TITLEBAR_GESTURE_MIDDLE_CLICK: break; @@ -3428,43 +3327,42 @@ handle_button_on_header(struct libdecor_frame *frame, struct seat *seat, uint32_ uint32_t time, uint32_t button, uint32_t state){ switch (frame->titlebar_gesture.state){ case TITLEBAR_GESTURE_STATE_INIT: { - if (state != WL_POINTER_BUTTON_STATE_PRESSED) - return; - - if (button == BTN_RIGHT){ - handle_titlebar_gesture(frame, seat, serial, TITLEBAR_GESTURE_RIGHT_CLICK); - frame->titlebar_gesture.state = TITLEBAR_GESTURE_STATE_CONSUMED; - } - else{ - if (button == BTN_LEFT && - frame->titlebar_gesture.first_pressed_button == BTN_LEFT && - time - frame->titlebar_gesture.first_pressed_time < - (uint32_t) ctx.double_click_time_ms){ - handle_titlebar_gesture(frame, seat, serial, TITLEBAR_GESTURE_DOUBLE_CLICK); + if (state == WL_POINTER_BUTTON_STATE_PRESSED){ + if (button == BTN_RIGHT){ + handle_titlebar_gesture(frame, seat, serial, TITLEBAR_GESTURE_RIGHT_CLICK); frame->titlebar_gesture.state = TITLEBAR_GESTURE_STATE_CONSUMED; } else{ - frame->titlebar_gesture.first_pressed_button = button; - frame->titlebar_gesture.first_pressed_time = time; - frame->titlebar_gesture.pressed_x = seat->pointer_x; - frame->titlebar_gesture.pressed_y = seat->pointer_y; - frame->titlebar_gesture.pressed_serial = serial; - frame->titlebar_gesture.state = TITLEBAR_GESTURE_STATE_BUTTON_PRESSED; + if (button == BTN_LEFT && + frame->titlebar_gesture.first_pressed_button == BTN_LEFT && + time - frame->titlebar_gesture.first_pressed_time < + (uint32_t) ctx.double_click_time_ms){ + handle_titlebar_gesture(frame, seat, serial, TITLEBAR_GESTURE_DOUBLE_CLICK); + frame->titlebar_gesture.state = TITLEBAR_GESTURE_STATE_CONSUMED; + } + else{ + frame->titlebar_gesture.first_pressed_button = button; + frame->titlebar_gesture.first_pressed_time = time; + frame->titlebar_gesture.pressed_x = seat->pointer_x; + frame->titlebar_gesture.pressed_y = seat->pointer_y; + frame->titlebar_gesture.pressed_serial = serial; + frame->titlebar_gesture.state = TITLEBAR_GESTURE_STATE_BUTTON_PRESSED; + } } - } - - frame->titlebar_gesture.button_pressed_count = 1; - - switch (frame->hdr_focus.type){ - case HEADER_MIN: - case HEADER_MAX: - case HEADER_CLOSE: { - frame->hdr_focus.state |= GTK_STATE_FLAG_ACTIVE; - draw_title_bar(frame); - wl_surface_commit(ctx.wl_surface); - }break; - default: break; + frame->titlebar_gesture.button_pressed_count = 1; + + switch (frame->hdr_focus.type){ + case HEADER_MIN: + case HEADER_MAX: + case HEADER_CLOSE: { + frame->hdr_focus.state |= GTK_STATE_FLAG_ACTIVE; + draw_title_bar(frame); + wl_surface_commit(ctx.wl_surface); + }break; + + default: break; + } } }break; @@ -3480,22 +3378,23 @@ handle_button_on_header(struct libdecor_frame *frame, struct seat *seat, uint32_ frame->titlebar_gesture.state = TITLEBAR_GESTURE_STATE_INIT; if (frame->titlebar_gesture.first_pressed_button == button && button == BTN_LEFT) { - libdecor_frame_ref(frame); switch (frame->hdr_focus.type) { case HEADER_MIN: { if (frame->frame_capabilities & LIBDECOR_ACTION_MINIMIZE){ - libdecor_frame_set_minimized(frame); + xdg_toplevel_set_minimized(frame->xdg_toplevel); } }break; case HEADER_MAX: { - toggle_maximized(frame); + if ((frame->frame_capabilities & LIBDECOR_ACTION_RESIZE)){ + toggle_maximized(); + } }break; case HEADER_CLOSE: { if (frame->frame_capabilities & LIBDECOR_ACTION_CLOSE){ - libdecor_frame_close(frame); - seat->pointer_focus = NULL; + xdg_toplevel_close(frame, frame->xdg_toplevel); + seat->pointer_focus = 0; } }break; @@ -3507,7 +3406,6 @@ handle_button_on_header(struct libdecor_frame *frame, struct seat *seat, uint32_ draw_title_bar(frame); wl_surface_commit(ctx.wl_surface); } - libdecor_frame_unref(frame); } } else{ @@ -3538,46 +3436,32 @@ handle_button_on_header(struct libdecor_frame *frame, struct seat *seat, uint32_ } static void -pointer_button(void *data, - struct wl_pointer *wl_pointer, - uint32_t serial, - uint32_t time, - uint32_t button, - uint32_t state) -{ +pointer_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial, + uint32_t time, uint32_t button, uint32_t state){ struct seat *seat = data; - struct libdecor_frame *frame; - - if (!seat->pointer_focus || !own_surface(seat->pointer_focus)) - return; - - frame = wl_surface_get_user_data(seat->pointer_focus); - if (!frame) - return; - - switch (frame->active->type) { - case SHADOW: - { - handle_button_on_shadow(frame, seat, serial, time, button, state); - }break; - - case HEADER: - { - handle_button_on_header(frame, seat, serial, time, button, state); - }break; - - default: break; + if (seat->pointer_focus && own_surface(seat->pointer_focus)){ + struct libdecor_frame *frame = wl_surface_get_user_data(seat->pointer_focus); + if (frame != 0){ + switch (frame->active->type) { + case SHADOW: + { + handle_button_on_shadow(frame, seat, serial, time, button, state); + }break; + + case HEADER: + { + handle_button_on_header(frame, seat, serial, time, button, state); + }break; + + default: break; + } + } } } static void -pointer_axis(void *data, - struct wl_pointer *wl_pointer, - uint32_t time, - uint32_t axis, - wl_fixed_t value) -{ -} +pointer_axis(void *data, struct wl_pointer *wl_pointer, + uint32_t time, uint32_t axis, wl_fixed_t value){} const struct wl_pointer_listener pointer_listener = { pointer_enter, @@ -3609,15 +3493,9 @@ update_touch_focus(struct seat *seat, struct libdecor_frame *frame, } static void -touch_down(void *data, - struct wl_touch *wl_touch, - uint32_t serial, - uint32_t time, - struct wl_surface *surface, - int32_t id, - wl_fixed_t x, - wl_fixed_t y) -{ +touch_down(void *data, struct wl_touch *wl_touch, uint32_t serial, + uint32_t time, struct wl_surface *surface, int32_t id, + wl_fixed_t x, wl_fixed_t y){ struct seat *seat = data; struct libdecor_frame *frame; @@ -3660,11 +3538,15 @@ touch_down(void *data, }break; default: { if (time - seat->touch_down_time_stamp < (uint32_t)ctx.double_click_time_ms) { - toggle_maximized(frame); + if ((frame->frame_capabilities & LIBDECOR_ACTION_RESIZE)){ + toggle_maximized(); + } } - else if (frame->frame_capabilities & LIBDECOR_ACTION_MOVE){ - seat->touch_down_time_stamp = time; - libdecor_frame_move(frame, seat->wl_seat, serial); + else{ + if (frame->frame_capabilities & LIBDECOR_ACTION_MOVE){ + seat->touch_down_time_stamp = time; + libdecor_frame_move(frame, seat->wl_seat, serial); + } } }break; } @@ -3682,59 +3564,49 @@ static void touch_up(void *data, struct wl_touch *wl_touch, uint32_t serial, uint32_t time, int32_t id){ struct seat *seat = data; - struct libdecor_frame *frame; - - if (!seat->touch_focus || !own_surface(seat->touch_focus)) - return; - - frame = wl_surface_get_user_data(seat->touch_focus); - if (!frame) - return; - - if (!frame->touch_active) - return; - - switch (frame->touch_active->type) { - case HEADER: - libdecor_frame_ref(frame); - switch (frame->hdr_focus.type) { - case HEADER_MIN: { - if (frame->frame_capabilities & LIBDECOR_ACTION_MINIMIZE){ - libdecor_frame_set_minimized(frame); + if (seat->touch_focus && own_surface(seat->touch_focus)){ + struct libdecor_frame *frame = wl_surface_get_user_data(seat->touch_focus); + if (frame != 0 && frame->touch_active != 0){ + if (frame->touch_active->type == HEADER){ + switch (frame->hdr_focus.type) { + case HEADER_MIN: { + if (frame->frame_capabilities & LIBDECOR_ACTION_MINIMIZE){ + xdg_toplevel_set_minimized(frame->xdg_toplevel); + } + }break; + + case HEADER_MAX: { + if ((frame->frame_capabilities & LIBDECOR_ACTION_RESIZE)){ + toggle_maximized(); + } + }break; + + case HEADER_CLOSE: { + if (frame->frame_capabilities & LIBDECOR_ACTION_CLOSE){ + xdg_toplevel_close(frame, frame->xdg_toplevel); + seat->touch_focus = 0; + } + }break; + + default: break; } - }break; - - case HEADER_MAX: { - toggle_maximized(frame); - }break; - - case HEADER_CLOSE: { - if (frame->frame_capabilities & LIBDECOR_ACTION_CLOSE){ - libdecor_frame_close(frame); - seat->touch_focus = NULL; + + /* unset active/clicked state once released */ + frame->hdr_focus.state &= ~GTK_STATE_FLAG_ACTIVE; + if (GTK_IS_WIDGET(frame->header)) { + draw_title_bar(frame); + wl_surface_commit(ctx.wl_surface); } - }break; + } - default: break; - } - /* unset active/clicked state once released */ - frame->hdr_focus.state &= ~GTK_STATE_FLAG_ACTIVE; - if (GTK_IS_WIDGET(frame->header)) { - draw_title_bar(frame); + seat->touch_focus = NULL; + frame->touch_active = NULL; + frame->hdr_focus.widget = NULL; + frame->hdr_focus.type = HEADER_NONE; + draw_decoration(frame); wl_surface_commit(ctx.wl_surface); } - libdecor_frame_unref(frame); - break; - default: - break; } - - seat->touch_focus = NULL; - frame->touch_active = NULL; - frame->hdr_focus.widget = NULL; - frame->hdr_focus.type = HEADER_NONE; - draw_decoration(frame); - wl_surface_commit(ctx.wl_surface); } static void diff --git a/digesting_libdecor.h b/digesting_libdecor.h index a684fe3..a4dbcf5 100644 --- a/digesting_libdecor.h +++ b/digesting_libdecor.h @@ -167,10 +167,6 @@ struct libdecor_frame { struct wl_list frame_link; //struct libdecor_frame_private; - int ref_count; - - struct wl_surface *wl_surface; - void *user_data; struct xdg_surface *xdg_surface; @@ -356,7 +352,6 @@ enum titlebar_gesture { // libdecor.h -void libdecor_frame_ref(struct libdecor_frame *frame); void libdecor_frame_unref(struct libdecor_frame *frame); void libdecor_frame_set_visibility(struct libdecor_frame *frame, bool visible); @@ -389,14 +384,10 @@ void libdecor_frame_move(struct libdecor_frame *frame, void libdecor_frame_commit(struct libdecor_frame *frame, int w, int h, struct libdecor_configuration *configuration); -void libdecor_frame_set_minimized(struct libdecor_frame *frame); -void libdecor_frame_set_maximized(struct libdecor_frame *frame); -void libdecor_frame_unset_maximized(struct libdecor_frame *frame); void libdecor_frame_set_fullscreen(struct libdecor_frame *frame, struct wl_output *output); void libdecor_frame_unset_fullscreen(struct libdecor_frame *frame); bool libdecor_frame_is_floating(struct libdecor_frame *frame); -void libdecor_frame_close(struct libdecor_frame *frame); void libdecor_frame_map(struct libdecor_frame *frame); bool libdecor_configuration_get_content_size(struct libdecor_configuration *configuration, @@ -440,8 +431,6 @@ static void output_removed(struct output *output); static const char *libdecor_gtk_proxy_tag = "libdecor-gtk"; -static int libdecor_plugin_gtk_get_fd(void); -static int libdecor_plugin_gtk_get_fd(void); static int libdecor_plugin_gtk_dispatch(int timeout); static void libdecor_plugin_gtk_set_handle_application_cursor(bool handle_cursor); static void libdecor_plugin_gtk_frame_free(struct libdecor_frame *frame);