From fb2af4f143adbbf6a19cb629b6dd2d3f093733f8 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sat, 28 Feb 2026 15:06:48 -0800 Subject: [PATCH] [digesting_libdecor] collapse some couple code paths into 'update_client_side_rendering_state' --- digesting_libdecor.c | 329 ++++++++++++++++++------------------------- 1 file changed, 138 insertions(+), 191 deletions(-) diff --git a/digesting_libdecor.c b/digesting_libdecor.c index 4f3f152..a171396 100755 --- a/digesting_libdecor.c +++ b/digesting_libdecor.c @@ -1129,34 +1129,6 @@ int main(){ //#include "libdecor.c" -static void -frame_get_window_size_for(struct libdecor_state *state, int *window_width, int *window_height){ - *window_width = state->content_width; - *window_height = state->content_height; - if (ctx.visible && ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){ - Sides2D border_size = border_size_from_window_state(ctx.frame_window_state); - *window_width += border_size.x[0] + border_size.x[1]; - *window_height += border_size.y[0] + border_size.y[1]; - } -} - -static void -frame_set_window_geometry(int32_t w, int32_t h){ - Extent2D extent = {0}; - extent.w = w; - extent.w = h; - - if (ctx.visible && ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){ - Sides2D border_size = border_size_from_window_state(ctx.frame_window_state); - extent.x = -border_size.x[0]; - extent.y = -border_size.y[0]; - extent.w = w + border_size.x[0] + border_size.x[1]; - extent.h = h + border_size.y[0] + border_size.y[1]; - } - - xdg_surface_set_window_geometry(ctx.xdg_surface, extent.x, extent.y, extent.w, extent.h); -} - bool libdecor_configuration_get_content_size(struct libdecor_configuration *configuration, int *width, int *height){ /* get configured toplevel dimensions */ @@ -1202,17 +1174,119 @@ libdecor_configuration_get_content_size(struct libdecor_configuration *configura return true; } +static enum decoration_type +decoration_type_from_window_state(enum libdecor_window_state window_state){ + enum decoration_type result = DECORATION_TYPE_ALL; + if (window_state & LIBDECOR_WINDOW_STATE_FULLSCREEN){ + result = DECORATION_TYPE_NONE; + } + 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)){ + result = DECORATION_TYPE_TITLE_ONLY; + } + return(result); +} + +static void +free_border_component(struct border_component *border_component){ + if (border_component->wl_surface) { + wl_subsurface_destroy(border_component->wl_subsurface); + border_component->wl_subsurface = NULL; + wl_surface_destroy(border_component->wl_surface); + border_component->wl_surface = NULL; + } + + if (border_component->wl_buffer != 0){ + wl_buffer_destroy(border_component->wl_buffer); + } + if (border_component->data != 0){ + munmap(border_component->data, border_component->data_size); + } + border_component->wl_buffer = 0; + border_component->data = 0; + border_component->data_size = 0; + border_component->width = 0; + border_component->height = 0; +} + +void +update_client_side_rendering_state(void){ + if (ctx.visible && ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){ + enum libdecor_window_state old_window_state; + enum libdecor_window_state new_window_state; + int old_content_width, old_content_height; + int new_content_width, new_content_height; + enum decoration_type old_decoration_type; + enum decoration_type new_decoration_type; + + old_window_state = ctx.gtk_window_state; + new_window_state = ctx.frame_window_state; + + old_content_width = ctx.gtk_content_width; + old_content_height = ctx.gtk_content_height; + new_content_width = ctx.frame_content_width; + new_content_height = ctx.frame_content_height; + + old_decoration_type = ctx.decoration_type; + new_decoration_type = decoration_type_from_window_state(new_window_state); + + if (old_decoration_type != new_decoration_type || + old_content_width != new_content_width || + old_content_height != new_content_height || + old_window_state != new_window_state){ + + ctx.gtk_content_width = new_content_width; + ctx.gtk_content_height = new_content_height; + ctx.gtk_window_state = new_window_state; + ctx.decoration_type = new_decoration_type; + + draw_decoration(); + + /* set fixed window size */ + if (!(ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){ + ctx.size_bounds.x[0] = ctx.gtk_content_width; + ctx.size_bounds.y[0] = ctx.gtk_content_height; + ctx.size_bounds.x[1] = ctx.gtk_content_width; + ctx.size_bounds.y[1] = ctx.gtk_content_height; + } + } + } + else{ + g_clear_pointer(&ctx.header, gtk_widget_destroy); + g_clear_pointer(&ctx.window, gtk_widget_destroy); + + free_border_component(&ctx.component_slot[COMPONENT_SLOT_HEADER]); + free_border_component(&ctx.component_slot[COMPONENT_SLOT_SHADOW]); + ctx.shadow_showing = false; + + g_clear_pointer(&ctx.title, free); + + ctx.decoration_type = DECORATION_TYPE_NONE; + } + + { + Extent2D extent = {0}; + extent.w = ctx.frame_content_width; + extent.h = ctx.frame_content_height; + + if (ctx.visible && ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){ + Sides2D border_size = border_size_from_window_state(ctx.frame_window_state); + extent.x = -border_size.x[0]; + extent.y = -border_size.y[0]; + extent.w += border_size.x[0] + border_size.x[1]; + extent.h += border_size.y[0] + border_size.y[1]; + } + + xdg_surface_set_window_geometry(ctx.xdg_surface, extent.x, extent.y, extent.w, extent.h); + } +} + void libdecor_frame_set_visibility(bool visible){ ctx.visible = visible; - - /* enable/disable decorations that are managed by the compositor. - * Note that, as of xdg_decoration v1, this is just a hint and there is - * no reliable way of disabling all decorations. In practice this should - * work but per spec this is not guaranteed. - * - * See also: https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/17 - */ if (ctx.decoration_manager != 0 && ctx.toplevel_decoration != 0 && ctx.has_decoration_mode && @@ -1225,15 +1299,7 @@ libdecor_frame_set_visibility(bool visible){ if (ctx.frame_content_width > 0 && ctx.frame_content_height > 0){ - if (ctx.visible != 0 && - ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){ - libdecor_plugin_gtk_frame_commit(); - } - else{ - libdecor_plugin_gtk_frame_free(); - } - - frame_set_window_geometry(ctx.frame_content_width, ctx.frame_content_height); + update_client_side_rendering_state(); wl_surface_commit(ctx.wl_surface); } @@ -1268,24 +1334,22 @@ libdecor_frame_unset_fullscreen(void){ void libdecor_frame_commit(int w, int h, struct libdecor_configuration *configuration){ + if (configuration != 0 && configuration->has_window_state){ + ctx.frame_window_state = configuration->window_state; + } + + Sides2D border_size = border_size_from_window_state(ctx.frame_window_state); + int border_added_w = border_size.x[0] + border_size.x[1]; + int border_added_h = border_size.y[0] + border_size.y[1]; + struct libdecor_state state = {0}; state.content_width = w; state.content_height = h; - - if (configuration != 0 && configuration->has_window_state){ - ctx.frame_window_state = configuration->window_state; - state.window_state = configuration->window_state; - } - else{ - state.window_state = ctx.frame_window_state; - } + state.window_state = ctx.frame_window_state; ctx.frame_content_width = state.content_width; ctx.frame_content_height = state.content_height; { - /* If the frame is configured as non-resizable before the first - * configure event is received, we have to manually set the min/max - * limits with the configured content size afterwards. */ if (!(ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){ ctx.size_bounds.x[0] = ctx.frame_content_width; ctx.size_bounds.y[0] = ctx.frame_content_height; @@ -1293,49 +1357,27 @@ libdecor_frame_commit(int w, int h, struct libdecor_configuration *configuration ctx.size_bounds.y[1] = ctx.frame_content_height; } - if (ctx.size_bounds.x[0] > 0 && - ctx.size_bounds.y[0] > 0){ - struct libdecor_state state_min; - int win_min_width, win_min_height; - - state_min.content_width = ctx.size_bounds.x[0]; - state_min.content_height = ctx.size_bounds.y[0]; - state_min.window_state = state.window_state; - - frame_get_window_size_for(&state_min, &win_min_width, &win_min_height); - xdg_toplevel_set_min_size(ctx.xdg_toplevel, win_min_width, win_min_height); - } - else{ - xdg_toplevel_set_min_size(ctx.xdg_toplevel, 0, 0); - } - - if (ctx.size_bounds.x[1] > 0 && - ctx.size_bounds.y[1] > 0){ - struct libdecor_state state_max; - int win_max_width, win_max_height; - - state_max.content_width = ctx.size_bounds.x[1]; - state_max.content_height = ctx.size_bounds.y[1]; - state_max.window_state = state.window_state; - - frame_get_window_size_for(&state_max, &win_max_width, &win_max_height); - xdg_toplevel_set_max_size(ctx.xdg_toplevel, win_max_width, win_max_height); - } - else{ - xdg_toplevel_set_max_size(ctx.xdg_toplevel, 0, 0); + for (int i = 0; i < 2; i += 1){ + int w = 0; + int h = 0; + if (ctx.size_bounds.x[i] > 0 && ctx.size_bounds.y[i] > 0){ + w = ctx.size_bounds.x[i]; + h = ctx.size_bounds.y[i]; + if (ctx.visible && ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){ + w += border_added_w; + h += border_added_h; + } + } + if (i == 0){ + xdg_toplevel_set_min_size(ctx.xdg_toplevel, w, h); + } + else{ + xdg_toplevel_set_max_size(ctx.xdg_toplevel, w, h); + } } } - /* switch between decoration modes */ - if (ctx.visible && - ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){ - libdecor_plugin_gtk_frame_commit(); - } - else{ - libdecor_plugin_gtk_frame_free(); - } - - frame_set_window_geometry(ctx.frame_content_width, ctx.frame_content_height); + update_client_side_rendering_state(); if (configuration != 0){ xdg_surface_ack_configure(ctx.xdg_surface, configuration->serial); @@ -1829,43 +1871,6 @@ toggle_maximized(void){ } } -static void -free_border_component(struct border_component *border_component){ - if (border_component->wl_surface) { - wl_subsurface_destroy(border_component->wl_subsurface); - border_component->wl_subsurface = NULL; - wl_surface_destroy(border_component->wl_surface); - border_component->wl_surface = NULL; - } - - if (border_component->wl_buffer != 0){ - wl_buffer_destroy(border_component->wl_buffer); - } - if (border_component->data != 0){ - munmap(border_component->data, border_component->data_size); - } - border_component->wl_buffer = 0; - border_component->data = 0; - border_component->data_size = 0; - border_component->width = 0; - border_component->height = 0; -} - -static void -libdecor_plugin_gtk_frame_free(void){ - g_clear_pointer(&ctx.header, gtk_widget_destroy); - g_clear_pointer(&ctx.window, gtk_widget_destroy); - - free_border_component(&ctx.component_slot[COMPONENT_SLOT_HEADER]); - free_border_component(&ctx.component_slot[COMPONENT_SLOT_SHADOW]); - ctx.shadow_showing = false; - - g_clear_pointer(&ctx.shadow_blur, cairo_surface_destroy); - g_clear_pointer(&ctx.title, free); - - ctx.decoration_type = DECORATION_TYPE_NONE; -} - static void hide_border_component(struct border_component *border_component){ if (border_component->wl_surface){ @@ -2345,64 +2350,6 @@ draw_decoration(void){ } } -static enum decoration_type -decoration_type_from_window_state(enum libdecor_window_state window_state){ - enum decoration_type result = DECORATION_TYPE_ALL; - if (window_state & LIBDECOR_WINDOW_STATE_FULLSCREEN){ - result = DECORATION_TYPE_NONE; - } - 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)){ - result = DECORATION_TYPE_TITLE_ONLY; - } - return(result); -} - -static void -libdecor_plugin_gtk_frame_commit(void){ - enum libdecor_window_state old_window_state; - enum libdecor_window_state new_window_state; - int old_content_width, old_content_height; - int new_content_width, new_content_height; - enum decoration_type old_decoration_type; - enum decoration_type new_decoration_type; - - old_window_state = ctx.gtk_window_state; - new_window_state = ctx.frame_window_state; - - old_content_width = ctx.gtk_content_width; - old_content_height = ctx.gtk_content_height; - new_content_width = ctx.frame_content_width; - new_content_height = ctx.frame_content_height; - - old_decoration_type = ctx.decoration_type; - new_decoration_type = decoration_type_from_window_state(new_window_state); - - if (old_decoration_type != new_decoration_type || - old_content_width != new_content_width || - old_content_height != new_content_height || - old_window_state != new_window_state){ - - ctx.gtk_content_width = new_content_width; - ctx.gtk_content_height = new_content_height; - ctx.gtk_window_state = new_window_state; - ctx.decoration_type = new_decoration_type; - - draw_decoration(); - - /* set fixed window size */ - if (!(ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){ - ctx.size_bounds.x[0] = ctx.gtk_content_width; - ctx.size_bounds.y[0] = ctx.gtk_content_height; - ctx.size_bounds.x[1] = ctx.gtk_content_width; - ctx.size_bounds.y[1] = ctx.gtk_content_height; - } - } -} - static Sides2D border_size_from_window_state(enum libdecor_window_state window_state){ Sides2D border_size = {0};