diff --git a/digesting_libdecor.c b/digesting_libdecor.c index 0689d08..079575e 100755 --- a/digesting_libdecor.c +++ b/digesting_libdecor.c @@ -424,15 +424,15 @@ int main(){ cairo_destroy(cr); blur_surface(shadow_blur, 64); - ctx.frame->shadow_blur = shadow_blur; + ctx.shadow_blur = shadow_blur; } - ctx.frame->wm_capabilities = (LIBDECOR_WM_CAPABILITIES_WINDOW_MENU | - LIBDECOR_WM_CAPABILITIES_MAXIMIZE | - LIBDECOR_WM_CAPABILITIES_FULLSCREEN | - LIBDECOR_WM_CAPABILITIES_MINIMIZE); + ctx.wm_capabilities = (LIBDECOR_WM_CAPABILITIES_WINDOW_MENU | + LIBDECOR_WM_CAPABILITIES_MAXIMIZE | + LIBDECOR_WM_CAPABILITIES_FULLSCREEN | + LIBDECOR_WM_CAPABILITIES_MINIMIZE); - ctx.frame->visible = true; + ctx.visible = true; set_capabilities(ctx.frame, (LIBDECOR_ACTION_MOVE | LIBDECOR_ACTION_RESIZE | @@ -446,7 +446,7 @@ int main(){ ctx.xdg_toplevel = xdg_surface_get_toplevel(ctx.xdg_surface); xdg_toplevel_add_listener(ctx.xdg_toplevel, &xdg_toplevel_listener, ctx.frame); - ctx.frame->decoration_mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE; + ctx.decoration_mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE; ctx.toplevel_decoration = 0; if (ctx.decoration_manager != 0){ ctx.toplevel_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(ctx.decoration_manager, ctx.xdg_toplevel); @@ -458,8 +458,8 @@ int main(){ libdecor_frame_set_app_id(ctx.frame, "demo"); libdecor_frame_set_title(ctx.frame, "Example Window"); - ctx.frame->content_limits.min_width = 80; - ctx.frame->content_limits.min_height = 60; + ctx.content_limits.min_width = 80; + ctx.content_limits.min_height = 60; wl_surface_commit(ctx.wl_surface); /* (nodocs-wl_egl) */ @@ -634,7 +634,7 @@ state_is_floating(enum libdecor_window_state window_state){ static void constrain_content_size(const struct libdecor_frame *frame, int *width, int *height){ - const struct libdecor_limits lim = frame->content_limits; + const struct libdecor_limits lim = ctx.content_limits; if (lim.min_width > 0) *width = MAX(lim.min_width, *width); @@ -649,13 +649,8 @@ constrain_content_size(const struct libdecor_frame *frame, int *width, int *heig static bool frame_has_visible_client_side_decoration(struct libdecor_frame *frame){ - /* visibility by client configuration */ - const bool vis_client = frame->visible; - /* visibility by compositor configuration */ - const bool vis_server = (frame->decoration_mode == - ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE); - - return vis_client && vis_server; + return(ctx.visible != 0 && + ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE); } static struct libdecor_configuration * @@ -733,7 +728,7 @@ libdecor_configuration_get_content_size(struct libdecor_configuration *configura int left, right, top, bottom; /* Update window state for correct border size calculation */ - frame->frame_window_state = configuration->window_state; + ctx.frame_window_state = configuration->window_state; if (!libdecor_plugin_gtk_frame_get_border_size(frame, configuration, &left, &right, &top, &bottom)){ return false; } @@ -766,8 +761,8 @@ xdg_surface_configure(void *user_data, struct xdg_surface *xdg_surface, uint32_t struct libdecor_frame *frame = user_data; struct libdecor_configuration *configuration; - configuration = frame->pending_configuration; - frame->pending_configuration = NULL; + configuration = ctx.pending_configuration; + ctx.pending_configuration = NULL; if (!configuration) configuration = libdecor_configuration_new(); @@ -870,12 +865,12 @@ xdg_toplevel_configure(void *user_data, window_state = parse_states(states); - frame->pending_configuration = libdecor_configuration_new(); - frame->pending_configuration->has_size = true; - frame->pending_configuration->window_width = width; - frame->pending_configuration->window_height = height; - frame->pending_configuration->has_window_state = true; - frame->pending_configuration->window_state = window_state; + ctx.pending_configuration = libdecor_configuration_new(); + ctx.pending_configuration->has_size = true; + ctx.pending_configuration->window_width = width; + ctx.pending_configuration->window_height = height; + ctx.pending_configuration->has_window_state = true; + ctx.pending_configuration->window_state = window_state; } static void @@ -911,24 +906,24 @@ xdg_toplevel_wm_capabilities(void *user_data, struct libdecor_frame *frame = user_data; enum xdg_toplevel_wm_capabilities *wm_cap; - frame->wm_capabilities = 0; + ctx.wm_capabilities = 0; wl_array_for_each(wm_cap, capabilities) { switch (*wm_cap) { case XDG_TOPLEVEL_WM_CAPABILITIES_WINDOW_MENU: { - frame->wm_capabilities |= LIBDECOR_WM_CAPABILITIES_WINDOW_MENU; + ctx.wm_capabilities |= LIBDECOR_WM_CAPABILITIES_WINDOW_MENU; }break; case XDG_TOPLEVEL_WM_CAPABILITIES_MAXIMIZE: { - frame->wm_capabilities |= LIBDECOR_WM_CAPABILITIES_MAXIMIZE; + ctx.wm_capabilities |= LIBDECOR_WM_CAPABILITIES_MAXIMIZE; }break; case XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN: { - frame->wm_capabilities |= LIBDECOR_WM_CAPABILITIES_FULLSCREEN; + ctx.wm_capabilities |= LIBDECOR_WM_CAPABILITIES_FULLSCREEN; }break; case XDG_TOPLEVEL_WM_CAPABILITIES_MINIMIZE: { - frame->wm_capabilities |= LIBDECOR_WM_CAPABILITIES_MINIMIZE; + ctx.wm_capabilities |= LIBDECOR_WM_CAPABILITIES_MINIMIZE; }break; default: break; @@ -956,9 +951,9 @@ toplevel_decoration_configure(void *data, struct libdecor_frame *frame = (struct libdecor_frame*)data; /* Ignore any _configure calls after the first, they will be * from our set_mode call. */ - if (!frame->has_decoration_mode) { - frame->has_decoration_mode = true; - frame->decoration_mode = mode; + if (!ctx.has_decoration_mode) { + ctx.has_decoration_mode = true; + ctx.decoration_mode = mode; } } @@ -983,14 +978,14 @@ libdecor_frame_unref(struct libdecor_frame *frame){ libdecor_plugin_gtk_frame_free(frame); - free(frame->title); - free(frame->app_id); + free(ctx.title); + free(ctx.app_id); free(frame); } void libdecor_frame_set_visibility(struct libdecor_frame *frame, bool visible){ - frame->visible = 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 @@ -1001,16 +996,16 @@ libdecor_frame_set_visibility(struct libdecor_frame *frame, bool visible){ */ if (ctx.decoration_manager != 0 && ctx.toplevel_decoration != 0 && - frame->has_decoration_mode != 0 && - frame->decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE) { + ctx.has_decoration_mode != 0 && + ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE){ zxdg_toplevel_decoration_v1_set_mode(ctx.toplevel_decoration, - frame->visible - ? ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE - : ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE); + ctx.visible ? + ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE : + ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE); } - if (frame->frame_content_width > 0 && - frame->frame_content_height > 0){ + if (ctx.frame_content_width > 0 && + ctx.frame_content_height > 0){ /* enable/disable decorations that are managed by a plugin */ if (frame_has_visible_client_side_decoration(frame)){ /* show client-side decorations */ @@ -1021,7 +1016,7 @@ libdecor_frame_set_visibility(struct libdecor_frame *frame, bool visible){ libdecor_plugin_gtk_frame_free(frame); } - frame_set_window_geometry(frame, frame->frame_content_width, frame->frame_content_height); + frame_set_window_geometry(frame, ctx.frame_content_width, ctx.frame_content_height); wl_surface_commit(ctx.wl_surface); } @@ -1029,12 +1024,12 @@ libdecor_frame_set_visibility(struct libdecor_frame *frame, bool visible){ void libdecor_frame_set_title(struct libdecor_frame *frame, const char *title){ - if (!STREQL(frame->title, title)){ - free(frame->title); - frame->title = strdup(title); + if (!STREQL(ctx.title, title)){ + free(ctx.title); + ctx.title = strdup(title); if (ctx.xdg_toplevel != 0){ xdg_toplevel_set_title(ctx.xdg_toplevel, title); - if (GTK_IS_WIDGET(frame->header)){ + if (GTK_IS_WIDGET(ctx.header)){ draw_decoration(frame); wl_surface_commit(ctx.wl_surface); } @@ -1044,8 +1039,8 @@ libdecor_frame_set_title(struct libdecor_frame *frame, const char *title){ void libdecor_frame_set_app_id(struct libdecor_frame *frame, const char *app_id){ - free(frame->app_id); - frame->app_id = strdup(app_id); + free(ctx.app_id); + ctx.app_id = strdup(app_id); if (ctx.xdg_toplevel != 0){ xdg_toplevel_set_app_id(ctx.xdg_toplevel, app_id); @@ -1056,31 +1051,29 @@ static void set_capabilities(struct libdecor_frame *frame, const enum libdecor_capabilities new_capabilities){ struct libdecor_state *state; - if (frame->frame_capabilities != new_capabilities){ - frame->frame_capabilities = new_capabilities; - if (frame->frame_content_width != 0 && - frame->frame_content_height != 0){ + if (ctx.frame_capabilities != new_capabilities){ + ctx.frame_capabilities = new_capabilities; + if (ctx.frame_content_width != 0 && + ctx.frame_content_height != 0){ - frame->gtk_capabilities = frame->frame_capabilities; - if (GTK_IS_WIDGET(frame->header)){ + ctx.gtk_capabilities = ctx.frame_capabilities; + if (GTK_IS_WIDGET(ctx.header)){ draw_decoration(frame); wl_surface_commit(ctx.wl_surface); } - if (!(frame->frame_capabilities & LIBDECOR_ACTION_RESIZE)){ - frame->interactive_limits = frame->content_limits; - /* set fixed window size */ - ctx.frame->content_limits.min_width = frame->frame_content_width; - ctx.frame->content_limits.min_height = frame->frame_content_height; - ctx.frame->content_limits.max_width = frame->frame_content_width; - ctx.frame->content_limits.max_height = frame->frame_content_height; + if (!(ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){ + ctx.interactive_limits = ctx.content_limits; + ctx.content_limits.min_width = ctx.frame_content_width; + ctx.content_limits.min_height = ctx.frame_content_height; + ctx.content_limits.max_width = ctx.frame_content_width; + ctx.content_limits.max_height = ctx.frame_content_height; } else{ - /* restore old limits */ - frame->content_limits = frame->interactive_limits; + ctx.content_limits = ctx.interactive_limits; } - libdecor_frame_commit(frame, frame->frame_content_width, frame->frame_content_height, 0); + libdecor_frame_commit(frame, ctx.frame_content_width, ctx.frame_content_height, 0); wl_surface_commit(ctx.wl_surface); } @@ -1168,24 +1161,23 @@ libdecor_frame_unset_fullscreen(struct libdecor_frame *frame){ } bool -libdecor_frame_is_floating(struct libdecor_frame *frame) -{ - return state_is_floating(frame->frame_window_state); +libdecor_frame_is_floating(struct libdecor_frame *frame){ + return state_is_floating(ctx.frame_window_state); } bool valid_limits(struct libdecor_frame *frame) { - if (frame->content_limits.min_width > 0 && - frame->content_limits.max_width > 0 && - frame->content_limits.min_width > - frame->content_limits.max_width) + if (ctx.content_limits.min_width > 0 && + ctx.content_limits.max_width > 0 && + ctx.content_limits.min_width > + ctx.content_limits.max_width) return false; - if (frame->content_limits.min_height > 0 && - frame->content_limits.max_height > 0 && - frame->content_limits.min_height > - frame->content_limits.max_height) + if (ctx.content_limits.min_height > 0 && + ctx.content_limits.max_height > 0 && + ctx.content_limits.min_height > + ctx.content_limits.max_height) return false; return true; @@ -1200,38 +1192,36 @@ libdecor_frame_apply_limits(struct libdecor_frame *frame, enum libdecor_window_s /* 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 (!(frame->frame_capabilities & LIBDECOR_ACTION_RESIZE)){ - frame->content_limits.min_width = frame->frame_content_width; - frame->content_limits.max_width = frame->frame_content_width; - - frame->content_limits.min_height = frame->frame_content_height; - frame->content_limits.max_height = frame->frame_content_height; + if (!(ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){ + ctx.content_limits.min_width = ctx.frame_content_width; + ctx.content_limits.min_height = ctx.frame_content_height; + ctx.content_limits.max_width = ctx.frame_content_width; + ctx.content_limits.max_height = ctx.frame_content_height; } - if (frame->content_limits.min_width > 0 && - frame->content_limits.min_height > 0){ + if (ctx.content_limits.min_width > 0 && + ctx.content_limits.min_height > 0){ struct libdecor_state state_min; int win_min_width, win_min_height; - state_min.content_width = frame->content_limits.min_width; - state_min.content_height = frame->content_limits.min_height; + state_min.content_width = ctx.content_limits.min_width; + state_min.content_height = ctx.content_limits.min_height; state_min.window_state = window_state; - frame_get_window_size_for(frame, &state_min, - &win_min_width, &win_min_height); + frame_get_window_size_for(frame, &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 (frame->content_limits.max_width > 0 && - frame->content_limits.max_height > 0){ + if (ctx.content_limits.max_width > 0 && + ctx.content_limits.max_height > 0){ struct libdecor_state state_max; int win_max_width, win_max_height; - state_max.content_width = frame->content_limits.max_width; - state_max.content_height = frame->content_limits.max_height; + state_max.content_width = ctx.content_limits.max_width; + state_max.content_height = ctx.content_limits.max_height; state_max.window_state = window_state; frame_get_window_size_for(frame, &state_max, &win_max_width, &win_max_height); @@ -1244,8 +1234,8 @@ libdecor_frame_apply_limits(struct libdecor_frame *frame, enum libdecor_window_s static void libdecor_frame_apply_state(struct libdecor_frame *frame, struct libdecor_state *state){ - frame->frame_content_width = state->content_width; - frame->frame_content_height = state->content_height; + ctx.frame_content_width = state->content_width; + ctx.frame_content_height = state->content_height; libdecor_frame_apply_limits(frame, state->window_state); } @@ -1257,11 +1247,11 @@ libdecor_frame_commit(struct libdecor_frame *frame, int w, int h, state.content_height = h; if (configuration != 0 && configuration->has_window_state){ - frame->frame_window_state = configuration->window_state; + ctx.frame_window_state = configuration->window_state; state.window_state = configuration->window_state; } else{ - state.window_state = frame->frame_window_state; + state.window_state = ctx.frame_window_state; } libdecor_frame_apply_state(frame, &state); @@ -1274,7 +1264,7 @@ libdecor_frame_commit(struct libdecor_frame *frame, int w, int h, libdecor_plugin_gtk_frame_free(frame); } - frame_set_window_geometry(frame, frame->frame_content_width, frame->frame_content_height); + frame_set_window_geometry(frame, ctx.frame_content_width, ctx.frame_content_height); if (configuration != 0){ xdg_surface_ack_configure(ctx.xdg_surface, configuration->serial); @@ -1866,7 +1856,7 @@ libdecor_plugin_gtk_set_handle_application_cursor(bool handle_cursor){ static void toggle_maximized(void){ - if (ctx.frame->frame_window_state & LIBDECOR_WINDOW_STATE_MAXIMIZED){ + if (ctx.frame_window_state & LIBDECOR_WINDOW_STATE_MAXIMIZED){ xdg_toplevel_unset_maximized(ctx.xdg_toplevel); } else{ @@ -1972,50 +1962,48 @@ 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(&ctx.header, gtk_widget_destroy); + g_clear_pointer(&ctx.window, gtk_widget_destroy); - free_border_component(&frame->headerbar); - free_border_component(&frame->shadow); - frame->shadow_showing = false; + free_border_component(&ctx.headerbar); + free_border_component(&ctx.shadow); + ctx.shadow_showing = false; - g_clear_pointer(&frame->shadow_blur, cairo_surface_destroy); - g_clear_pointer(&frame->title, free); + g_clear_pointer(&ctx.shadow_blur, cairo_surface_destroy); + g_clear_pointer(&ctx.title, free); - frame->decoration_type = DECORATION_TYPE_NONE; + ctx.decoration_type = DECORATION_TYPE_NONE; } static bool -is_border_surfaces_showing(struct libdecor_frame *frame) -{ - return frame->shadow_showing; +is_border_surfaces_showing(struct libdecor_frame *frame){ + return ctx.shadow_showing; } static void -hide_border_component(struct border_component *border_component) -{ - if (!border_component->wl_surface) - return; - - wl_surface_attach(border_component->wl_surface, NULL, 0, 0); - wl_surface_commit(border_component->wl_surface); +hide_border_component(struct border_component *border_component){ + if (border_component->wl_surface){ + wl_surface_attach(border_component->wl_surface, NULL, 0, 0); + wl_surface_commit(border_component->wl_surface); + } } static void -hide_border_surfaces(struct libdecor_frame *frame) -{ - hide_border_component(&frame->shadow); - frame->shadow_showing = false; +hide_border_surfaces(struct libdecor_frame *frame){ + hide_border_component(&ctx.shadow); + ctx.shadow_showing = false; } static struct border_component * -get_component_for_surface(struct libdecor_frame *frame, const struct wl_surface *surface) -{ - if (frame->shadow.wl_surface == surface) - return &frame->shadow; - if (frame->headerbar.wl_surface == surface) - return &frame->headerbar; - return NULL; +get_component_for_surface(struct libdecor_frame *frame, const struct wl_surface *surface){ + struct border_component *result = 0; + if (ctx.shadow.wl_surface == surface){ + result = &ctx.shadow; + } + else if (ctx.headerbar.wl_surface == surface){ + result = &ctx.headerbar; + } + return result; } static bool @@ -2032,7 +2020,7 @@ redraw_scale(struct libdecor_frame *frame, struct border_component *cmpnt) } if (scale != cmpnt->scale) { cmpnt->scale = scale; - if ((frame->decoration_type != DECORATION_TYPE_NONE) && + if ((ctx.decoration_type != DECORATION_TYPE_NONE) && ((cmpnt->type != SHADOW) || is_border_surfaces_showing(frame))) { draw_border_component(frame, cmpnt, cmpnt->type); return true; @@ -2152,22 +2140,22 @@ ensure_component(struct libdecor_frame *frame, struct border_component *cmpnt){ static void ensure_border_surfaces(struct libdecor_frame *frame){ - frame->shadow.type = SHADOW; - frame->shadow.opaque = false; - ensure_component(frame, &frame->shadow); + ctx.shadow.type = SHADOW; + ctx.shadow.opaque = false; + ensure_component(frame, &ctx.shadow); } static void ensure_title_bar_surfaces(struct libdecor_frame *frame){ GtkStyleContext *context_hdr; - frame->headerbar.type = HEADER; - frame->headerbar.opaque = false; - ensure_component(frame, &frame->headerbar); + ctx.headerbar.type = HEADER; + ctx.headerbar.opaque = false; + ensure_component(frame, &ctx.headerbar); - if (frame->shadow.wl_surface) { - wl_subsurface_place_above(frame->headerbar.wl_subsurface, - frame->shadow.wl_surface); + if (ctx.shadow.wl_surface){ + wl_subsurface_place_above(ctx.headerbar.wl_subsurface, + ctx.shadow.wl_surface); } /* create an offscreen window with a header bar */ @@ -2176,38 +2164,37 @@ ensure_title_bar_surfaces(struct libdecor_frame *frame){ * after construction. So we just destroy and re-create them. */ /* avoid warning when restoring previously turned off decoration */ - if (GTK_IS_WIDGET(frame->header)) { - gtk_widget_destroy(frame->header); - frame->header = NULL; + if (GTK_IS_WIDGET(ctx.header)){ + gtk_widget_destroy(ctx.header); + ctx.header = NULL; } /* avoid warning when restoring previously turned off decoration */ - if (GTK_IS_WIDGET(frame->window)) { - gtk_widget_destroy(frame->window); - frame->window = NULL; + if (GTK_IS_WIDGET(ctx.window)){ + gtk_widget_destroy(ctx.window); + ctx.window = NULL; } - frame->window = gtk_offscreen_window_new(); - frame->header = gtk_header_bar_new(); + ctx.window = gtk_offscreen_window_new(); + ctx.header = gtk_header_bar_new(); - g_object_get(gtk_widget_get_settings(frame->window), - "gtk-double-click-time", - &ctx.double_click_time_ms, - "gtk-dnd-drag-threshold", - &ctx.drag_threshold, + g_object_get(gtk_widget_get_settings(ctx.window), + "gtk-double-click-time", &ctx.double_click_time_ms, + "gtk-dnd-drag-threshold", &ctx.drag_threshold, NULL); /* set as "default" decoration */ - g_object_set(frame->header, "title", frame->title, + g_object_set(ctx.header, + "title", ctx.title, "has-subtitle", FALSE, "show-close-button", TRUE, NULL); - context_hdr = gtk_widget_get_style_context(frame->header); + context_hdr = gtk_widget_get_style_context(ctx.header); gtk_style_context_add_class(context_hdr, GTK_STYLE_CLASS_TITLEBAR); gtk_style_context_add_class(context_hdr, "default-decoration"); - gtk_window_set_titlebar(GTK_WINDOW(frame->window), frame->header); - gtk_header_bar_set_show_close_button(GTK_HEADER_BAR(frame->header), TRUE); + gtk_window_set_titlebar(GTK_WINDOW(ctx.window), ctx.header); + gtk_header_bar_set_show_close_button(GTK_HEADER_BAR(ctx.header), TRUE); - gtk_window_set_resizable(GTK_WINDOW(frame->window), (frame->frame_capabilities & LIBDECOR_ACTION_RESIZE) != 0); + gtk_window_set_resizable(GTK_WINDOW(ctx.window), (ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE) != 0); } static void @@ -2220,41 +2207,45 @@ calculate_component_size(struct libdecor_frame *frame, { int content_width, content_height; - content_width = frame->frame_content_width; - content_height = frame->frame_content_height; + content_width = ctx.frame_content_width; + content_height = ctx.frame_content_height; /* avoid warning when restoring previously turned off decoration */ - const int title_height = GTK_IS_WIDGET(frame->header)?gtk_widget_get_allocated_height(frame->header):0; + const int title_height = GTK_IS_WIDGET(ctx.header)?gtk_widget_get_allocated_height(ctx.header):0; - switch (component) { - case NONE: - *component_width = 0; - *component_height = 0; - return; - case SHADOW: - *component_x = -(int)SHADOW_MARGIN; - *component_y = -(int)(SHADOW_MARGIN+title_height); - *component_width = content_width + 2 * SHADOW_MARGIN; - *component_height = content_height - + 2 * SHADOW_MARGIN - + title_height; - return; - case HEADER: - *component_x = 0; - /* reuse product of function call above */ - *component_y = - title_height; - *component_width = gtk_widget_get_allocated_width(frame->header); - /* reuse product of function call above */ - *component_height = title_height; - return; + switch (component){ + case NONE: { + *component_width = 0; + *component_height = 0; + return; + } + + case SHADOW: { + *component_x = -(int)SHADOW_MARGIN; + *component_y = -(int)(SHADOW_MARGIN+title_height); + *component_width = content_width + 2 * SHADOW_MARGIN; + *component_height = content_height + + 2 * SHADOW_MARGIN + + title_height; + return; + } + + case HEADER: { + *component_x = 0; + /* reuse product of function call above */ + *component_y = - title_height; + *component_width = gtk_widget_get_allocated_width(ctx.header); + /* reuse product of function call above */ + *component_height = title_height; + return; + } } abort(); } static void -array_append(enum header_element **array, size_t *n, enum header_element item) -{ +array_append(enum header_element **array, size_t *n, enum header_element item){ (*n)++; *array = realloc(*array, (*n) * sizeof (enum header_element)); (*array)[(*n)-1] = item; @@ -2266,8 +2257,8 @@ draw_header_background(struct libdecor_frame *frame, cairo_t *cr){ GtkAllocation allocation; GtkStyleContext* style; - gtk_widget_get_allocation(GTK_WIDGET(frame->header), &allocation); - style = gtk_widget_get_style_context(frame->header); + gtk_widget_get_allocation(GTK_WIDGET(ctx.header), &allocation); + style = gtk_widget_get_style_context(ctx.header); gtk_render_background(style, cr, allocation.x, allocation.y, allocation.width, allocation.height); } @@ -2279,7 +2270,7 @@ draw_header_title(struct libdecor_frame *frame_gtk, cairo_surface_t *surface){ cairo_surface_t *label_surface = NULL; cairo_t *cr; - label = find_widget_by_type(frame_gtk->header, HEADER_TITLE).widget; + label = find_widget_by_type(ctx.header, HEADER_TITLE).widget; gtk_widget_get_allocation(label, &allocation); /* create subsection in which to draw label */ @@ -2322,117 +2313,119 @@ draw_header_button(struct libdecor_frame *frame, cairo_surface_t* icon_surface; gint width = 0, height = 0; - gint left = 0, top = 0, right = 0, bottom = 0; GtkBorder border; - GtkBorder padding; - elem = find_widget_by_type(frame->header, button_type); + elem = find_widget_by_type(ctx.header, button_type); button = elem.widget; - if (!button) - return; - button_style = gtk_widget_get_style_context(button); - style_state = elem.state; - - /* change style based on window state and focus */ - if (!(window_state & LIBDECOR_WINDOW_STATE_ACTIVE)) { - style_state |= GTK_STATE_FLAG_BACKDROP; - } - if (frame->hdr_focus.widget == button) { - style_state |= GTK_STATE_FLAG_PRELIGHT; - if (frame->hdr_focus.state & GTK_STATE_FLAG_ACTIVE) { - style_state |= GTK_STATE_FLAG_ACTIVE; + if (button){ + button_style = gtk_widget_get_style_context(button); + style_state = elem.state; + + /* change style based on window state and focus */ + if (!(window_state & LIBDECOR_WINDOW_STATE_ACTIVE)) { + style_state |= GTK_STATE_FLAG_BACKDROP; } + if (ctx.hdr_focus.widget == button) { + style_state |= GTK_STATE_FLAG_PRELIGHT; + if (ctx.hdr_focus.state & GTK_STATE_FLAG_ACTIVE) { + style_state |= GTK_STATE_FLAG_ACTIVE; + } + } + + /* background */ + gtk_widget_get_clip(button, &allocation); + + gtk_style_context_save(button_style); + gtk_style_context_set_state(button_style, style_state); + gtk_render_background(button_style, cr, + allocation.x, allocation.y, + allocation.width, allocation.height); + gtk_render_frame(button_style, cr, + allocation.x, allocation.y, + allocation.width, allocation.height); + gtk_style_context_restore(button_style); + + /* symbol */ + switch (button_type) { + case HEADER_MIN: { + icon_name = "window-minimize-symbolic"; + }break; + + case HEADER_MAX:{ + icon_name = (window_state & LIBDECOR_WINDOW_STATE_MAXIMIZED) ? + "window-restore-symbolic" : + "window-maximize-symbolic"; + }break; + + case HEADER_CLOSE: { + icon_name = "window-close-symbolic"; + }break; + + default: { + icon_name = NULL; + }break; + } + + /* get scale */ + cairo_surface_get_device_scale(surface, &sx, &sy); + scale = (sx+sy) / 2.0; + + /* get original icon dimensions */ + icon_widget = gtk_bin_get_child(GTK_BIN(button)); + gtk_widget_get_allocation(icon_widget, &allocation_icon); + + /* icon info */ + if (!gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &icon_width, &icon_height)) { + icon_width = 16; + icon_height = 16; + } + icon_info = gtk_icon_theme_lookup_icon_for_scale(gtk_icon_theme_get_default(), icon_name, + icon_width, scale, (GtkIconLookupFlags)0); + + /* icon pixel buffer*/ + gtk_style_context_save(button_style); + gtk_style_context_set_state(button_style, style_state); + icon_pixbuf = gtk_icon_info_load_symbolic_for_context( + icon_info, button_style, NULL, NULL); + icon_surface = gdk_cairo_surface_create_from_pixbuf(icon_pixbuf, scale, NULL); + gtk_style_context_restore(button_style); + + /* dimensions and position */ + gtk_style_context_get(button_style, gtk_style_context_get_state(button_style), + "min-width", &width, "min-height", &height, NULL); + + if (width < icon_width){ + width = icon_width; + } + if (height < icon_height){ + height = icon_height; + } + + gtk_style_context_get_border(button_style, gtk_style_context_get_state(button_style), &border); + left += border.left; + right += border.right; + top += border.top; + bottom += border.bottom; + + gtk_style_context_get_padding(button_style, gtk_style_context_get_state(button_style), &padding); + left += padding.left; + right += padding.right; + top += padding.top; + bottom += padding.bottom; + + width += left + right; + height += top + bottom; + + gtk_render_icon_surface(gtk_widget_get_style_context(icon_widget), + cr, icon_surface, + allocation.x + ((width - icon_width) / 2), + allocation.y + ((height - icon_height) / 2)); + cairo_paint(cr); + cairo_surface_destroy(icon_surface); + g_object_unref(icon_pixbuf); } - - /* background */ - gtk_widget_get_clip(button, &allocation); - - gtk_style_context_save(button_style); - gtk_style_context_set_state(button_style, style_state); - gtk_render_background(button_style, cr, - allocation.x, allocation.y, - allocation.width, allocation.height); - gtk_render_frame(button_style, cr, - allocation.x, allocation.y, - allocation.width, allocation.height); - gtk_style_context_restore(button_style); - - /* symbol */ - switch (button_type) { - case HEADER_MIN: - icon_name = "window-minimize-symbolic"; - break; - case HEADER_MAX: - icon_name = (window_state & LIBDECOR_WINDOW_STATE_MAXIMIZED) ? - "window-restore-symbolic" : - "window-maximize-symbolic"; - break; - case HEADER_CLOSE: - icon_name = "window-close-symbolic"; - break; - default: - icon_name = NULL; - break; - } - - /* get scale */ - cairo_surface_get_device_scale(surface, &sx, &sy); - scale = (sx+sy) / 2.0; - - /* get original icon dimensions */ - icon_widget = gtk_bin_get_child(GTK_BIN(button)); - gtk_widget_get_allocation(icon_widget, &allocation_icon); - - /* icon info */ - if (!gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &icon_width, &icon_height)) { - icon_width = 16; - icon_height = 16; - } - icon_info = gtk_icon_theme_lookup_icon_for_scale( - gtk_icon_theme_get_default(), icon_name, - icon_width, scale, (GtkIconLookupFlags)0); - - /* icon pixel buffer*/ - gtk_style_context_save(button_style); - gtk_style_context_set_state(button_style, style_state); - icon_pixbuf = gtk_icon_info_load_symbolic_for_context( - icon_info, button_style, NULL, NULL); - icon_surface = gdk_cairo_surface_create_from_pixbuf(icon_pixbuf, scale, NULL); - gtk_style_context_restore(button_style); - - /* dimensions and position */ - gtk_style_context_get(button_style, gtk_style_context_get_state(button_style), - "min-width", &width, "min-height", &height, NULL); - - if (width < icon_width) - width = icon_width; - if (height < icon_height) - height = icon_height; - - gtk_style_context_get_border(button_style, gtk_style_context_get_state(button_style), &border); - left += border.left; - right += border.right; - top += border.top; - bottom += border.bottom; - - gtk_style_context_get_padding(button_style, gtk_style_context_get_state(button_style), &padding); - left += padding.left; - right += padding.right; - top += padding.top; - bottom += padding.bottom; - - width += left + right; - height += top + bottom; - - gtk_render_icon_surface(gtk_widget_get_style_context(icon_widget), - cr, icon_surface, - allocation.x + ((width - icon_width) / 2), - allocation.y + ((height - icon_height) / 2)); - cairo_paint(cr); - cairo_surface_destroy(icon_surface); - g_object_unref(icon_pixbuf); } static void @@ -2442,16 +2435,16 @@ draw_header_buttons(struct libdecor_frame *frame, cairo_t *cr, cairo_surface_t * enum header_element *buttons = NULL; size_t nbuttons = 0; - window_state = frame->frame_window_state; + window_state = ctx.frame_window_state; /* set buttons by capability */ - if ((frame->frame_capabilities & LIBDECOR_ACTION_MINIMIZE)){ + if ((ctx.frame_capabilities & LIBDECOR_ACTION_MINIMIZE)){ array_append(&buttons, &nbuttons, HEADER_MIN); } - if ((frame->frame_capabilities & LIBDECOR_ACTION_RESIZE)){ + if ((ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){ array_append(&buttons, &nbuttons, HEADER_MAX); } - if ((frame->frame_capabilities & LIBDECOR_ACTION_CLOSE)){ + if ((ctx.frame_capabilities & LIBDECOR_ACTION_CLOSE)){ array_append(&buttons, &nbuttons, HEADER_CLOSE); } @@ -2495,7 +2488,7 @@ draw_component_content(struct libdecor_frame *frame, case NONE: break; case SHADOW: { - render_shadow(cr, frame->shadow_blur, + render_shadow(cr, ctx.shadow_blur, -(int)SHADOW_MARGIN/2, -(int)SHADOW_MARGIN/2, buffer->width + SHADOW_MARGIN, buffer->height + SHADOW_MARGIN, 64, 64); @@ -2514,8 +2507,8 @@ draw_component_content(struct libdecor_frame *frame, &component_width, &component_height); cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); cairo_rectangle(cr, -component_x, -component_y, - frame->frame_content_width, - frame->frame_content_height); + ctx.frame_content_width, + ctx.frame_content_height); cairo_fill(cr); } @@ -2526,7 +2519,7 @@ 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){ + if (border_component->type == SHADOW && ctx.shadow_showing){ struct wl_region *input_region; int component_x; int component_y; @@ -2545,10 +2538,9 @@ set_component_input_region(struct libdecor_frame *frame, wl_region_add(input_region, 0, 0, component_width, component_height); wl_region_subtract(input_region, -component_x, -component_y, - frame->frame_content_width, - frame->frame_content_height); - wl_surface_set_input_region(border_component->wl_surface, - input_region); + ctx.frame_content_width, + ctx.frame_content_height); + wl_surface_set_input_region(border_component->wl_surface, input_region); wl_region_destroy(input_region); } } @@ -2613,26 +2605,26 @@ draw_border_component(struct libdecor_frame *frame, static void draw_border(struct libdecor_frame *frame){ - draw_border_component(frame, &frame->shadow, SHADOW); - frame->shadow_showing = true; + draw_border_component(frame, &ctx.shadow, SHADOW); + ctx.shadow_showing = true; } static void draw_title_bar(struct libdecor_frame *frame){ - GtkAllocation allocation = {0, 0, frame->gtk_content_width, 0}; + GtkAllocation allocation = {0, 0, ctx.gtk_content_width, 0}; enum libdecor_window_state state; GtkStyleContext *style; int pref_width; int W, H; - state = frame->frame_window_state; - style = gtk_widget_get_style_context(frame->window); + state = ctx.frame_window_state; + style = gtk_widget_get_style_context(ctx.window); if (!(state & LIBDECOR_WINDOW_STATE_ACTIVE)){ - gtk_widget_set_state_flags(frame->window, GTK_STATE_FLAG_BACKDROP, true); + gtk_widget_set_state_flags(ctx.window, GTK_STATE_FLAG_BACKDROP, true); } else{ - gtk_widget_unset_state_flags(frame->window, GTK_STATE_FLAG_BACKDROP); + gtk_widget_unset_state_flags(ctx.window, GTK_STATE_FLAG_BACKDROP); } if (libdecor_frame_is_floating(frame)){ @@ -2642,41 +2634,41 @@ draw_title_bar(struct libdecor_frame *frame){ gtk_style_context_add_class(style, "maximized"); } - gtk_widget_show_all(frame->window); + gtk_widget_show_all(ctx.window); /* set default width, using an empty title to estimate its smallest admissible value */ - gtk_header_bar_set_title(GTK_HEADER_BAR(frame->header), ""); - gtk_widget_get_preferred_width(frame->header, NULL, &pref_width); - gtk_header_bar_set_title(GTK_HEADER_BAR(frame->header), frame->title); - if (frame->content_limits.min_width < pref_width){ - frame->content_limits.min_width = pref_width; + gtk_header_bar_set_title(GTK_HEADER_BAR(ctx.header), ""); + gtk_widget_get_preferred_width(ctx.header, NULL, &pref_width); + gtk_header_bar_set_title(GTK_HEADER_BAR(ctx.header), ctx.title); + if (ctx.content_limits.min_width < pref_width){ + ctx.content_limits.min_width = pref_width; } - if (frame->content_limits.max_width != 0 && - frame->content_limits.max_width < frame->content_limits.min_width){ - frame->content_limits.max_width = frame->content_limits.min_width; + if (ctx.content_limits.max_width != 0 && + ctx.content_limits.max_width < ctx.content_limits.min_width){ + ctx.content_limits.max_width = ctx.content_limits.min_width; } - W = frame->frame_content_width; - H = frame->frame_content_height; - if (W < frame->content_limits.min_width){ - W = frame->content_limits.min_width; + W = ctx.frame_content_width; + H = ctx.frame_content_height; + if (W < ctx.content_limits.min_width){ + W = ctx.content_limits.min_width; libdecor_frame_commit(frame, W, H, NULL); } 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); + gtk_widget_get_preferred_height(ctx.header, 0, &allocation.height); + gtk_widget_size_allocate(ctx.header, &allocation); + draw_border_component(frame, &ctx.headerbar, HEADER); } } static void draw_decoration(struct libdecor_frame *frame){ - switch (frame->decoration_type) { + switch (ctx.decoration_type) { case DECORATION_TYPE_NONE: { if (is_border_surfaces_showing(frame)){ hide_border_surfaces(frame); } - hide_border_component(&frame->headerbar); + hide_border_component(&ctx.headerbar); }break; case DECORATION_TYPE_ALL: { @@ -2730,15 +2722,15 @@ libdecor_plugin_gtk_frame_commit(struct libdecor_frame *frame, enum decoration_type old_decoration_type; enum decoration_type new_decoration_type; - old_window_state = frame->gtk_window_state; - new_window_state = frame->frame_window_state; + old_window_state = ctx.gtk_window_state; + new_window_state = ctx.frame_window_state; - old_content_width = frame->gtk_content_width; - old_content_height = frame->gtk_content_height; - new_content_width = frame->frame_content_width; - new_content_height = frame->frame_content_height; + 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 = frame->decoration_type; + old_decoration_type = ctx.decoration_type; new_decoration_type = window_state_to_decoration_type(new_window_state); if (old_decoration_type == new_decoration_type && @@ -2747,19 +2739,19 @@ libdecor_plugin_gtk_frame_commit(struct libdecor_frame *frame, old_window_state == new_window_state) return; - frame->gtk_content_width = new_content_width; - frame->gtk_content_height = new_content_height; - frame->gtk_window_state = new_window_state; - frame->decoration_type = new_decoration_type; + 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(frame); /* set fixed window size */ - if (!(frame->frame_capabilities & LIBDECOR_ACTION_RESIZE)){ - ctx.frame->content_limits.min_width = frame->gtk_content_width; - ctx.frame->content_limits.min_height = frame->gtk_content_height; - ctx.frame->content_limits.max_width = frame->gtk_content_width; - ctx.frame->content_limits.max_height = frame->gtk_content_height; + if (!(ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){ + ctx.content_limits.min_width = ctx.gtk_content_width; + ctx.content_limits.min_height = ctx.gtk_content_height; + ctx.content_limits.max_width = ctx.gtk_content_width; + ctx.content_limits.max_height = ctx.gtk_content_height; } } @@ -2788,13 +2780,13 @@ update_component_focus(struct libdecor_frame *frame, struct wl_surface *surface, } } - if (frame->grab){ - frame->active = frame->grab; + if (ctx.grab){ + ctx.active = ctx.grab; } else{ - frame->active = focus_component; + ctx.active = focus_component; } - frame->focus = focus_component; + ctx.focus = focus_component; } static void @@ -2804,9 +2796,9 @@ sync_active_component(struct libdecor_frame *frame, struct seat *seat){ if (!seat->pointer_focus) return; - old_active = frame->active; + old_active = ctx.active; update_component_focus(frame, seat->pointer_focus, seat); - if (old_active != frame->active) { + if (old_active != ctx.active) { draw_decoration(frame); wl_surface_commit(ctx.wl_surface); } @@ -2822,22 +2814,18 @@ synthesize_pointer_enter(struct seat *seat){ struct libdecor_frame *frame; surface = seat->pointer_focus; - if (!surface || !own_surface(surface)) - return; - - frame = wl_surface_get_user_data(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); + if (surface && own_surface(surface)){ + frame = wl_surface_get_user_data(surface); + if (frame != 0){ + update_component_focus(frame, seat->pointer_focus, seat); + ctx.grab = 0; + if (ctx.active) { + draw_decoration(frame); + wl_surface_commit(ctx.wl_surface); + } + update_local_cursor(seat); + send_cursor(seat); } - - update_local_cursor(seat); - send_cursor(seat); } } @@ -2847,8 +2835,8 @@ synthesize_pointer_leave(struct seat *seat){ 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; + if (ctx.active != 0){ + ctx.active = 0; draw_decoration(frame); wl_surface_commit(ctx.wl_surface); update_local_cursor(seat); @@ -2906,7 +2894,7 @@ libdecor_plugin_gtk_frame_get_border_size(struct libdecor_frame *frame, struct l } } else{ - window_state = frame->frame_window_state; + window_state = ctx.frame_window_state; } if (left){ @@ -2931,11 +2919,11 @@ libdecor_plugin_gtk_frame_get_border_size(struct libdecor_frame *frame, struct l } G_GNUC_FALLTHROUGH; case DECORATION_TYPE_TITLE_ONLY: { - if (!frame->header){ + if (!ctx.header){ ensure_title_bar_surfaces(frame); } - gtk_widget_show_all(frame->window); - gtk_widget_get_preferred_height(frame->header, NULL, top); + gtk_widget_show_all(ctx.window); + gtk_widget_get_preferred_height(ctx.header, NULL, top); }break; } } @@ -3067,35 +3055,36 @@ component_edge(const struct border_component *cmpnt, static bool update_local_cursor(struct seat *seat){ - if (!seat->pointer_focus) { + if (!seat->pointer_focus){ seat->current_cursor = seat->cursor_left_ptr; return false; } - if (!own_surface(seat->pointer_focus)) + if (!own_surface(seat->pointer_focus)){ return false; + } struct libdecor_frame *frame = wl_surface_get_user_data(seat->pointer_focus); struct wl_cursor *wl_cursor = NULL; - if (!frame || !frame->active) { + if (!frame || !ctx.active){ seat->current_cursor = seat->cursor_left_ptr; return false; } bool theme_updated = ensure_cursor_theme(seat); - if (frame->active->type == SHADOW && + if (ctx.active->type == SHADOW && is_border_surfaces_showing(frame) && - (frame->frame_capabilities & LIBDECOR_ACTION_RESIZE)){ + (ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){ enum libdecor_resize_edge edge; - edge = component_edge(frame->active, - seat->pointer_x, - seat->pointer_y, SHADOW_MARGIN); + edge = component_edge(ctx.active, seat->pointer_x, seat->pointer_y, SHADOW_MARGIN); - if (edge != LIBDECOR_RESIZE_EDGE_NONE) + if (edge != LIBDECOR_RESIZE_EDGE_NONE){ wl_cursor = seat->cursors[edge - 1]; - } else { + } + } + else{ wl_cursor = seat->cursor_left_ptr; } @@ -3158,10 +3147,10 @@ pointer_enter(void *data, struct wl_pointer *wl_pointer, uint32_t serial, if (!frame) return; - frame->active = get_component_for_surface(frame, surface); + ctx.active = get_component_for_surface(frame, surface); /* update decorations */ - if (frame->active) { + if (ctx.active){ draw_decoration(frame); wl_surface_commit(ctx.wl_surface); } @@ -3180,12 +3169,12 @@ pointer_leave(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct struct libdecor_frame *frame = wl_surface_get_user_data(surface); if (frame != 0){ - frame->titlebar_gesture.state = TITLEBAR_GESTURE_STATE_INIT; - frame->titlebar_gesture.first_pressed_button = 0; + ctx.titlebar_gesture.state = TITLEBAR_GESTURE_STATE_INIT; + ctx.titlebar_gesture.first_pressed_button = 0; - frame->active = NULL; - frame->hdr_focus.widget = NULL; - frame->hdr_focus.type = HEADER_NONE; + ctx.active = 0; + ctx.hdr_focus.widget = 0; + ctx.hdr_focus.type = HEADER_NONE; draw_decoration(frame); wl_surface_commit(ctx.wl_surface); update_local_cursor(seat); @@ -3211,33 +3200,28 @@ pointer_motion(void *data, struct wl_pointer *wl_pointer, uint32_t time, frame = wl_surface_get_user_data(seat->pointer_focus); /* avoid warnings after decoration has been turned off */ - if (!GTK_IS_WIDGET(frame->header) || frame->active->type != HEADER) { - frame->hdr_focus.type = HEADER_NONE; + if (!GTK_IS_WIDGET(ctx.header) || ctx.active->type != HEADER) { + ctx.hdr_focus.type = HEADER_NONE; } - new_focus = get_header_focus(GTK_HEADER_BAR(frame->header), - seat->pointer_x, seat->pointer_y); + new_focus = get_header_focus(GTK_HEADER_BAR(ctx.header), + seat->pointer_x, seat->pointer_y); /* only update if widget change so that we keep the state */ - if (frame->hdr_focus.widget != new_focus.widget) { - frame->hdr_focus = new_focus; + if (ctx.hdr_focus.widget != new_focus.widget) { + ctx.hdr_focus = new_focus; } - frame->hdr_focus.state |= GTK_STATE_FLAG_PRELIGHT; + ctx.hdr_focus.state |= GTK_STATE_FLAG_PRELIGHT; /* redraw with updated button visuals */ draw_title_bar(frame); wl_surface_commit(ctx.wl_surface); - switch (frame->titlebar_gesture.state) { + switch (ctx.titlebar_gesture.state) { case TITLEBAR_GESTURE_STATE_BUTTON_PRESSED: - if (frame->titlebar_gesture.first_pressed_button == BTN_LEFT) { - if (ABS ((double) seat->pointer_x - - (double) frame->titlebar_gesture.pressed_x) > - ctx.drag_threshold || - ABS ((double) seat->pointer_y - - (double) frame->titlebar_gesture.pressed_y) > - ctx.drag_threshold) { - libdecor_frame_move(frame, seat->wl_seat, - frame->titlebar_gesture.pressed_serial); + if (ctx.titlebar_gesture.first_pressed_button == BTN_LEFT) { + if (ABS((double)seat->pointer_x - (double)ctx.titlebar_gesture.pressed_x) > ctx.drag_threshold || + ABS((double)seat->pointer_y - (double)ctx.titlebar_gesture.pressed_y) > ctx.drag_threshold){ + libdecor_frame_move(frame, seat->wl_seat, ctx.titlebar_gesture.pressed_serial); } } case TITLEBAR_GESTURE_STATE_INIT: @@ -3252,9 +3236,9 @@ 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); + edge = component_edge(ctx.active, seat->pointer_x, seat->pointer_y, SHADOW_MARGIN); if (edge != LIBDECOR_RESIZE_EDGE_NONE && - (frame->frame_capabilities & LIBDECOR_ACTION_RESIZE)){ + (ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){ libdecor_frame_resize(frame, seat->wl_seat, serial, edge); } } @@ -3264,7 +3248,7 @@ handle_titlebar_gesture(struct libdecor_frame *frame, struct seat *seat, uint32_t serial, enum titlebar_gesture gesture){ switch (gesture){ case TITLEBAR_GESTURE_DOUBLE_CLICK: { - if ((frame->frame_capabilities & LIBDECOR_ACTION_RESIZE)){ + if ((ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){ toggle_maximized(); } }break; @@ -3272,7 +3256,7 @@ handle_titlebar_gesture(struct libdecor_frame *frame, struct seat *seat, case TITLEBAR_GESTURE_MIDDLE_CLICK: break; case TITLEBAR_GESTURE_RIGHT_CLICK: { - const int title_height = gtk_widget_get_allocated_height(frame->header); + const int title_height = gtk_widget_get_allocated_height(ctx.header); libdecor_frame_show_window_menu(frame, seat->wl_seat, serial, seat->pointer_x, seat->pointer_y -title_height); }break; @@ -3282,38 +3266,37 @@ handle_titlebar_gesture(struct libdecor_frame *frame, struct seat *seat, static void handle_button_on_header(struct libdecor_frame *frame, struct seat *seat, uint32_t serial, uint32_t time, uint32_t button, uint32_t state){ - switch (frame->titlebar_gesture.state){ + switch (ctx.titlebar_gesture.state){ case TITLEBAR_GESTURE_STATE_INIT: { 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; + ctx.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){ + ctx.titlebar_gesture.first_pressed_button == BTN_LEFT && + time - ctx.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; + ctx.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; + ctx.titlebar_gesture.first_pressed_button = button; + ctx.titlebar_gesture.first_pressed_time = time; + ctx.titlebar_gesture.pressed_x = seat->pointer_x; + ctx.titlebar_gesture.pressed_y = seat->pointer_y; + ctx.titlebar_gesture.pressed_serial = serial; + ctx.titlebar_gesture.state = TITLEBAR_GESTURE_STATE_BUTTON_PRESSED; } } - frame->titlebar_gesture.button_pressed_count = 1; + ctx.titlebar_gesture.button_pressed_count = 1; - switch (frame->hdr_focus.type){ + switch (ctx.hdr_focus.type){ case HEADER_MIN: case HEADER_MAX: case HEADER_CLOSE: { - frame->hdr_focus.state |= GTK_STATE_FLAG_ACTIVE; + ctx.hdr_focus.state |= GTK_STATE_FLAG_ACTIVE; draw_title_bar(frame); wl_surface_commit(ctx.wl_surface); }break; @@ -3325,31 +3308,31 @@ handle_button_on_header(struct libdecor_frame *frame, struct seat *seat, uint32_ case TITLEBAR_GESTURE_STATE_BUTTON_PRESSED: { if (state == WL_POINTER_BUTTON_STATE_PRESSED) { - frame->titlebar_gesture.state = TITLEBAR_GESTURE_STATE_DISCARDED; - frame->titlebar_gesture.button_pressed_count++; + ctx.titlebar_gesture.state = TITLEBAR_GESTURE_STATE_DISCARDED; + ctx.titlebar_gesture.button_pressed_count += 1; } else{ - frame->titlebar_gesture.button_pressed_count--; + ctx.titlebar_gesture.button_pressed_count -= 1; - if (frame->titlebar_gesture.button_pressed_count == 0) { - frame->titlebar_gesture.state = TITLEBAR_GESTURE_STATE_INIT; - if (frame->titlebar_gesture.first_pressed_button == button && + if (ctx.titlebar_gesture.button_pressed_count == 0) { + ctx.titlebar_gesture.state = TITLEBAR_GESTURE_STATE_INIT; + if (ctx.titlebar_gesture.first_pressed_button == button && button == BTN_LEFT) { - switch (frame->hdr_focus.type) { + switch (ctx.hdr_focus.type) { case HEADER_MIN: { - if (frame->frame_capabilities & LIBDECOR_ACTION_MINIMIZE){ + if (ctx.frame_capabilities & LIBDECOR_ACTION_MINIMIZE){ xdg_toplevel_set_minimized(ctx.xdg_toplevel); } }break; case HEADER_MAX: { - if ((frame->frame_capabilities & LIBDECOR_ACTION_RESIZE)){ + if ((ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){ toggle_maximized(); } }break; case HEADER_CLOSE: { - if (frame->frame_capabilities & LIBDECOR_ACTION_CLOSE){ + if (ctx.frame_capabilities & LIBDECOR_ACTION_CLOSE){ xdg_toplevel_close(frame, ctx.xdg_toplevel); seat->pointer_focus = 0; } @@ -3358,16 +3341,16 @@ handle_button_on_header(struct libdecor_frame *frame, struct seat *seat, uint32_ default: break; } - frame->hdr_focus.state &= ~GTK_STATE_FLAG_ACTIVE; - if (GTK_IS_WIDGET(frame->header)){ + ctx.hdr_focus.state &= ~GTK_STATE_FLAG_ACTIVE; + if (GTK_IS_WIDGET(ctx.header)){ draw_title_bar(frame); wl_surface_commit(ctx.wl_surface); } } } else{ - frame->hdr_focus.state &= ~GTK_STATE_FLAG_ACTIVE; - if (GTK_IS_WIDGET(frame->header)) { + ctx.hdr_focus.state &= ~GTK_STATE_FLAG_ACTIVE; + if (GTK_IS_WIDGET(ctx.header)) { draw_title_bar(frame); wl_surface_commit(ctx.wl_surface); } @@ -3379,13 +3362,13 @@ handle_button_on_header(struct libdecor_frame *frame, struct seat *seat, uint32_ case TITLEBAR_GESTURE_STATE_CONSUMED: case TITLEBAR_GESTURE_STATE_DISCARDED: { if (state == WL_POINTER_BUTTON_STATE_PRESSED){ - frame->titlebar_gesture.button_pressed_count++; + ctx.titlebar_gesture.button_pressed_count++; } else{ - frame->titlebar_gesture.button_pressed_count--; - if (frame->titlebar_gesture.button_pressed_count == 0) { - frame->titlebar_gesture.state = TITLEBAR_GESTURE_STATE_INIT; - frame->titlebar_gesture.first_pressed_button = 0; + ctx.titlebar_gesture.button_pressed_count--; + if (ctx.titlebar_gesture.button_pressed_count == 0) { + ctx.titlebar_gesture.state = TITLEBAR_GESTURE_STATE_INIT; + ctx.titlebar_gesture.first_pressed_button = 0; } } }break; @@ -3399,7 +3382,7 @@ pointer_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial, 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) { + switch (ctx.active->type) { case SHADOW: { handle_button_on_shadow(frame, seat, serial, time, button, state); @@ -3431,21 +3414,17 @@ const struct wl_pointer_listener pointer_listener = { static void update_touch_focus(struct seat *seat, struct libdecor_frame *frame, wl_fixed_t x, wl_fixed_t y){ - /* avoid warnings after decoration has been turned off */ - if (GTK_IS_WIDGET(frame->header) && frame->touch_active->type == HEADER){ - struct header_element_data new_focus = get_header_focus(GTK_HEADER_BAR(frame->header), - wl_fixed_to_int(x), wl_fixed_to_int(y)); - /* only update if widget change so that we keep the state */ - if (frame->hdr_focus.widget != new_focus.widget){ - frame->hdr_focus = new_focus; + if (GTK_IS_WIDGET(ctx.header) && ctx.touch_active->type == HEADER){ + struct header_element_data new_focus = get_header_focus(GTK_HEADER_BAR(ctx.header), wl_fixed_to_int(x), wl_fixed_to_int(y)); + if (ctx.hdr_focus.widget != new_focus.widget){ + ctx.hdr_focus = new_focus; } - frame->hdr_focus.state |= GTK_STATE_FLAG_PRELIGHT; - /* redraw with updated button visuals */ + ctx.hdr_focus.state |= GTK_STATE_FLAG_PRELIGHT; draw_title_bar(frame); wl_surface_commit(ctx.wl_surface); } else{ - frame->hdr_focus.type = HEADER_NONE; + ctx.hdr_focus.type = HEADER_NONE; } } @@ -3464,9 +3443,9 @@ touch_down(void *data, struct wl_touch *wl_touch, uint32_t serial, return; seat->touch_focus = surface; - frame->touch_active = get_component_for_surface(frame, surface); + ctx.touch_active = get_component_for_surface(frame, surface); - if (!frame->touch_active) + if (!ctx.touch_active) return; update_touch_focus(seat, frame, x, y); @@ -3476,31 +3455,28 @@ touch_down(void *data, struct wl_touch *wl_touch, uint32_t serial, wl_surface_commit(ctx.wl_surface); enum libdecor_resize_edge edge = LIBDECOR_RESIZE_EDGE_NONE; - switch (frame->touch_active->type) { + switch (ctx.touch_active->type) { case SHADOW: { - edge = component_edge(frame->touch_active, - wl_fixed_to_int(x), - wl_fixed_to_int(y), - SHADOW_MARGIN); + edge = component_edge(ctx.touch_active, wl_fixed_to_int(x), wl_fixed_to_int(y), SHADOW_MARGIN); }break; case HEADER: { - switch (frame->hdr_focus.type){ + switch (ctx.hdr_focus.type){ case HEADER_MIN: case HEADER_MAX: case HEADER_CLOSE: { - frame->hdr_focus.state |= GTK_STATE_FLAG_ACTIVE; + ctx.hdr_focus.state |= GTK_STATE_FLAG_ACTIVE; draw_title_bar(frame); wl_surface_commit(ctx.wl_surface); }break; default: { if (time - seat->touch_down_time_stamp < (uint32_t)ctx.double_click_time_ms) { - if ((frame->frame_capabilities & LIBDECOR_ACTION_RESIZE)){ + if ((ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){ toggle_maximized(); } } else{ - if (frame->frame_capabilities & LIBDECOR_ACTION_MOVE){ + if (ctx.frame_capabilities & LIBDECOR_ACTION_MOVE){ seat->touch_down_time_stamp = time; libdecor_frame_move(frame, seat->wl_seat, serial); } @@ -3512,7 +3488,7 @@ touch_down(void *data, struct wl_touch *wl_touch, uint32_t serial, default: break; } if (edge != LIBDECOR_RESIZE_EDGE_NONE && - (frame->frame_capabilities & LIBDECOR_ACTION_RESIZE)) { + (ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)) { libdecor_frame_resize(frame, seat->wl_seat, serial, edge); } } @@ -3522,23 +3498,23 @@ touch_up(void *data, struct wl_touch *wl_touch, uint32_t serial, uint32_t time, struct seat *seat = data; 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) { + if (frame != 0 && ctx.touch_active != 0){ + if (ctx.touch_active->type == HEADER){ + switch (ctx.hdr_focus.type) { case HEADER_MIN: { - if (frame->frame_capabilities & LIBDECOR_ACTION_MINIMIZE){ + if (ctx.frame_capabilities & LIBDECOR_ACTION_MINIMIZE){ xdg_toplevel_set_minimized(ctx.xdg_toplevel); } }break; case HEADER_MAX: { - if ((frame->frame_capabilities & LIBDECOR_ACTION_RESIZE)){ + if ((ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){ toggle_maximized(); } }break; case HEADER_CLOSE: { - if (frame->frame_capabilities & LIBDECOR_ACTION_CLOSE){ + if (ctx.frame_capabilities & LIBDECOR_ACTION_CLOSE){ xdg_toplevel_close(frame, ctx.xdg_toplevel); seat->touch_focus = 0; } @@ -3548,17 +3524,17 @@ touch_up(void *data, struct wl_touch *wl_touch, uint32_t serial, uint32_t time, } /* unset active/clicked state once released */ - frame->hdr_focus.state &= ~GTK_STATE_FLAG_ACTIVE; - if (GTK_IS_WIDGET(frame->header)) { + ctx.hdr_focus.state &= ~GTK_STATE_FLAG_ACTIVE; + if (GTK_IS_WIDGET(ctx.header)) { draw_title_bar(frame); wl_surface_commit(ctx.wl_surface); } } - seat->touch_focus = NULL; - frame->touch_active = NULL; - frame->hdr_focus.widget = NULL; - frame->hdr_focus.type = HEADER_NONE; + seat->touch_focus = 0; + ctx.touch_active = 0; + ctx.hdr_focus.widget = 0; + ctx.hdr_focus.type = HEADER_NONE; draw_decoration(frame); wl_surface_commit(ctx.wl_surface); } @@ -3571,14 +3547,12 @@ touch_motion(void *data, struct wl_touch *wl_touch, uint32_t time, 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; - - update_touch_focus(seat, frame, x, y); + if (seat->touch_focus && own_surface(seat->touch_focus)){ + frame = wl_surface_get_user_data(seat->touch_focus); + if (frame != 0){ + update_touch_focus(seat, frame, x, y); + } + } } static void @@ -3614,8 +3588,8 @@ output_done(void *data, struct wl_output *wl_output){ struct seat *seat; if (ctx.frame != 0 && - ctx.frame->decoration_type != DECORATION_TYPE_NONE){ - bool updated = redraw_scale(ctx.frame, &ctx.frame->shadow); + ctx.decoration_type != DECORATION_TYPE_NONE){ + bool updated = redraw_scale(ctx.frame, &ctx.shadow); if (updated){ wl_surface_commit(ctx.wl_surface); } @@ -3656,9 +3630,8 @@ output_removed(struct output *output){ struct libdecor_frame *frame; struct seat *seat; - if (ctx.frame != 0 && - ctx.frame->decoration_type != DECORATION_TYPE_NONE){ - remove_surface_outputs(&ctx.frame->shadow, output); + if (ctx.frame != 0 && ctx.decoration_type != DECORATION_TYPE_NONE){ + remove_surface_outputs(&ctx.shadow, output); } wl_list_for_each(seat, &ctx.seat_list, link) { struct cursor_output *cursor_output; diff --git a/digesting_libdecor.h b/digesting_libdecor.h index e0711d3..b48dfa8 100644 --- a/digesting_libdecor.h +++ b/digesting_libdecor.h @@ -163,65 +163,7 @@ struct border_component { }; struct libdecor_frame { - //struct libdecor_frame_private; - char *app_id; - char *title; - struct libdecor_limits content_limits; - struct xdg_toplevel *parent; - - struct libdecor_configuration *pending_configuration; - - int frame_content_width; - int frame_content_height; - - enum libdecor_window_state frame_window_state; - - bool has_decoration_mode; - enum zxdg_toplevel_decoration_v1_mode decoration_mode; - - enum libdecor_capabilities frame_capabilities; - enum libdecor_wm_capabilities wm_capabilities; - - /* original limits for interactive resize */ - struct libdecor_limits interactive_limits; - bool visible; - - //struct libdecor_frame_gtk; - int gtk_content_width; - int gtk_content_height; - - enum libdecor_window_state gtk_window_state; - - enum decoration_type decoration_type; - - enum libdecor_capabilities gtk_capabilities; - - struct border_component *active; - struct border_component *touch_active; - - struct border_component *focus; - struct border_component *grab; - - bool shadow_showing; - struct border_component shadow; - - GtkWidget *window; /* offscreen window for rendering */ - GtkWidget *header; /* header bar with widgets */ - struct border_component headerbar; - struct header_element_data hdr_focus; - - /* store pre-processed shadow tile */ - cairo_surface_t *shadow_blur; - - struct { - enum titlebar_gesture_state state; - int button_pressed_count; - uint32_t first_pressed_button; - uint32_t first_pressed_time; - double pressed_x; - double pressed_y; - uint32_t pressed_serial; - } titlebar_gesture; + int dummy; }; // #include "libdecor.c" @@ -473,6 +415,66 @@ typedef struct Ctx{ int has_cached_config; struct libdecor_configuration cached_config; + + //struct libdecor_frame_private; + char *app_id; + char *title; + struct libdecor_limits content_limits; + struct xdg_toplevel *parent; + + struct libdecor_configuration *pending_configuration; + + int frame_content_width; + int frame_content_height; + + enum libdecor_window_state frame_window_state; + + bool has_decoration_mode; + enum zxdg_toplevel_decoration_v1_mode decoration_mode; + + enum libdecor_capabilities frame_capabilities; + enum libdecor_wm_capabilities wm_capabilities; + + /* original limits for interactive resize */ + struct libdecor_limits interactive_limits; + bool visible; + + //struct libdecor_frame_gtk; + int gtk_content_width; + int gtk_content_height; + + enum libdecor_window_state gtk_window_state; + + enum decoration_type decoration_type; + + enum libdecor_capabilities gtk_capabilities; + + struct border_component *active; + struct border_component *touch_active; + + struct border_component *focus; + struct border_component *grab; + + bool shadow_showing; + struct border_component shadow; + + GtkWidget *window; /* offscreen window for rendering */ + GtkWidget *header; /* header bar with widgets */ + struct border_component headerbar; + struct header_element_data hdr_focus; + + /* store pre-processed shadow tile */ + cairo_surface_t *shadow_blur; + + struct { + enum titlebar_gesture_state state; + int button_pressed_count; + uint32_t first_pressed_button; + uint32_t first_pressed_time; + double pressed_x; + double pressed_y; + uint32_t pressed_serial; + } titlebar_gesture; } Ctx; #endif //DIGESTING_LIBDECOR_H