diff --git a/digesting_libdecor.c b/digesting_libdecor.c index 25fd8db..5ca05a2 100755 --- a/digesting_libdecor.c +++ b/digesting_libdecor.c @@ -235,6 +235,19 @@ const struct wl_seat_listener seat_listener = { seat_name }; +static void +xdg_toplevel_decoration_configure(void *data, struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, uint32_t mode){ + if (!ctx.has_decoration_mode){ + ctx.has_decoration_mode = true; + ctx.decoration_mode = mode; + } +} + +const struct zxdg_toplevel_decoration_v1_listener +xdg_toplevel_decoration_listener = { + xdg_toplevel_decoration_configure, +}; + int main(){ /* get desktop settings */ ctx.color_scheme = libdecor_get_color_scheme(); @@ -268,7 +281,6 @@ int main(){ { ctx.w = 640; ctx.h = 480; - wl_list_init(&ctx.visible_frame_list); wl_list_init(&ctx.seat_list); wl_list_init(&ctx.output_list); } @@ -425,18 +437,16 @@ int main(){ ctx.shadow_blur = shadow_blur; } + ctx.visible = true; ctx.wm_capabilities = (LIBDECOR_WM_CAPABILITIES_WINDOW_MENU | LIBDECOR_WM_CAPABILITIES_MAXIMIZE | LIBDECOR_WM_CAPABILITIES_FULLSCREEN | LIBDECOR_WM_CAPABILITIES_MINIMIZE); - - ctx.visible = true; - - set_capabilities(LIBDECOR_ACTION_MOVE | - LIBDECOR_ACTION_RESIZE | - LIBDECOR_ACTION_MINIMIZE | - LIBDECOR_ACTION_FULLSCREEN | - LIBDECOR_ACTION_CLOSE); + ctx.frame_capabilities = (LIBDECOR_ACTION_MOVE | + LIBDECOR_ACTION_RESIZE | + LIBDECOR_ACTION_MINIMIZE | + LIBDECOR_ACTION_FULLSCREEN | + LIBDECOR_ACTION_CLOSE); ctx.xdg_surface = xdg_wm_base_get_xdg_surface(ctx.xdg_wm_base, ctx.wl_surface); xdg_surface_add_listener(ctx.xdg_surface, &xdg_surface_listener, 0); @@ -445,17 +455,19 @@ int main(){ xdg_toplevel_add_listener(ctx.xdg_toplevel, &xdg_toplevel_listener, 0); 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); zxdg_toplevel_decoration_v1_add_listener(ctx.toplevel_decoration, &xdg_toplevel_decoration_listener, 0); } - libdecor_frame_set_app_id("demo"); - libdecor_frame_set_title("Example Window"); - ctx.content_limits.min_width = 80; ctx.content_limits.min_height = 60; + + xdg_toplevel_set_app_id(ctx.xdg_toplevel, "demo"); + xdg_toplevel_set_title(ctx.xdg_toplevel, "Example Window"); + ctx.title = strdup("Example Window"); + + draw_decoration(); wl_surface_commit(ctx.wl_surface); /* (nodocs-wl_egl) */ @@ -643,12 +655,6 @@ constrain_content_size(int *width, int *height){ *height = MIN(*height, lim.max_height); } -static bool -frame_has_visible_client_side_decoration(void){ - return(ctx.visible != 0 && - ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE); -} - static struct libdecor_configuration * libdecor_configuration_new(void) { @@ -664,11 +670,9 @@ frame_get_window_size_for(struct libdecor_state *state, int *window_width, int * *window_width = state->content_width; *window_height = state->content_height; - if (frame_has_visible_client_side_decoration()) { + if (ctx.visible && ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){ int left, right, top, bottom; - if (!libdecor_plugin_gtk_frame_get_border_size(0, &left, &right, &top, &bottom)){ - return false; - } + libdecor_plugin_gtk_frame_get_border_size(ctx.frame_window_state, &left, &right, &top, &bottom); *window_width += left + right; *window_height += top + bottom; } @@ -679,10 +683,11 @@ frame_get_window_size_for(struct libdecor_state *state, int *window_width, int * static void frame_set_window_geometry(int32_t content_width, int32_t content_height){ int x, y, width, height; - int left, right, top, bottom; - if (frame_has_visible_client_side_decoration() && - libdecor_plugin_gtk_frame_get_border_size(0, &left, &right, &top, &bottom)){ + if (ctx.visible != 0 && + ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){ + int left, right, top, bottom; + libdecor_plugin_gtk_frame_get_border_size(ctx.frame_window_state, &left, &right, &top, &bottom); x = -left; y = -top; width = content_width + left + right; @@ -710,13 +715,15 @@ libdecor_configuration_get_content_size(struct libdecor_configuration *configura *width = configuration->window_width; *height = configuration->window_height; - /* remove plugin-specific border size */ - if (frame_has_visible_client_side_decoration()) { + if (ctx.visible != 0 && + ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){ int left, right, top, bottom; - /* Update window state for correct border size calculation */ ctx.frame_window_state = configuration->window_state; - if (!libdecor_plugin_gtk_frame_get_border_size(configuration, &left, &right, &top, &bottom)){ + if (configuration->has_window_state){ + libdecor_plugin_gtk_frame_get_border_size(configuration->window_state, &left, &right, &top, &bottom); + } + else{ return false; } @@ -732,26 +739,16 @@ libdecor_configuration_get_content_size(struct libdecor_configuration *configura return true; } -bool -libdecor_configuration_get_window_state(struct libdecor_configuration *configuration, - enum libdecor_window_state *window_state) -{ - if (!configuration->has_window_state) - return false; - - *window_state = configuration->window_state; - return true; -} - static void xdg_surface_configure(void *user_data, struct xdg_surface *xdg_surface, uint32_t serial){ struct libdecor_configuration *configuration; configuration = ctx.pending_configuration; - ctx.pending_configuration = NULL; + ctx.pending_configuration = 0; - if (!configuration) + if (configuration == 0){ configuration = libdecor_configuration_new(); + } configuration->serial = serial; @@ -788,51 +785,25 @@ parse_states(struct wl_array *states){ enum xdg_toplevel_state state = *p; switch (state) { - case XDG_TOPLEVEL_STATE_FULLSCREEN: - pending_state |= LIBDECOR_WINDOW_STATE_FULLSCREEN; - break; - case XDG_TOPLEVEL_STATE_MAXIMIZED: - pending_state |= LIBDECOR_WINDOW_STATE_MAXIMIZED; - break; - case XDG_TOPLEVEL_STATE_ACTIVATED: - pending_state |= LIBDECOR_WINDOW_STATE_ACTIVE; - break; - case XDG_TOPLEVEL_STATE_TILED_LEFT: - pending_state |= LIBDECOR_WINDOW_STATE_TILED_LEFT; - break; - case XDG_TOPLEVEL_STATE_TILED_RIGHT: - pending_state |= LIBDECOR_WINDOW_STATE_TILED_RIGHT; - break; - case XDG_TOPLEVEL_STATE_TILED_TOP: - pending_state |= LIBDECOR_WINDOW_STATE_TILED_TOP; - break; - case XDG_TOPLEVEL_STATE_TILED_BOTTOM: - pending_state |= LIBDECOR_WINDOW_STATE_TILED_BOTTOM; - break; - case XDG_TOPLEVEL_STATE_RESIZING: - pending_state |= LIBDECOR_WINDOW_STATE_RESIZING; - break; + case XDG_TOPLEVEL_STATE_FULLSCREEN: pending_state |= LIBDECOR_WINDOW_STATE_FULLSCREEN; break; + case XDG_TOPLEVEL_STATE_MAXIMIZED: pending_state |= LIBDECOR_WINDOW_STATE_MAXIMIZED; break; + case XDG_TOPLEVEL_STATE_ACTIVATED: pending_state |= LIBDECOR_WINDOW_STATE_ACTIVE; break; + case XDG_TOPLEVEL_STATE_TILED_LEFT: pending_state |= LIBDECOR_WINDOW_STATE_TILED_LEFT; break; + case XDG_TOPLEVEL_STATE_TILED_RIGHT: pending_state |= LIBDECOR_WINDOW_STATE_TILED_RIGHT; break; + case XDG_TOPLEVEL_STATE_TILED_TOP: pending_state |= LIBDECOR_WINDOW_STATE_TILED_TOP; break; + case XDG_TOPLEVEL_STATE_TILED_BOTTOM: pending_state |= LIBDECOR_WINDOW_STATE_TILED_BOTTOM; break; + case XDG_TOPLEVEL_STATE_RESIZING: pending_state |= LIBDECOR_WINDOW_STATE_RESIZING; break; #ifdef XDG_TOPLEVEL_STATE_SUSPENDED_SINCE_VERSION - case XDG_TOPLEVEL_STATE_SUSPENDED: - pending_state |= LIBDECOR_WINDOW_STATE_SUSPENDED; - break; + case XDG_TOPLEVEL_STATE_SUSPENDED: pending_state |= LIBDECOR_WINDOW_STATE_SUSPENDED; break; #endif #ifdef XDG_TOPLEVEL_STATE_CONSTRAINED_LEFT_SINCE_VERSION - case XDG_TOPLEVEL_STATE_CONSTRAINED_LEFT: - pending_state |= LIBDECOR_WINDOW_STATE_CONSTRAINED_LEFT; - break; - case XDG_TOPLEVEL_STATE_CONSTRAINED_RIGHT: - pending_state |= LIBDECOR_WINDOW_STATE_CONSTRAINED_RIGHT; - break; - case XDG_TOPLEVEL_STATE_CONSTRAINED_TOP: - pending_state |= LIBDECOR_WINDOW_STATE_CONSTRAINED_TOP; - break; - case XDG_TOPLEVEL_STATE_CONSTRAINED_BOTTOM: - pending_state |= LIBDECOR_WINDOW_STATE_CONSTRAINED_BOTTOM; - break; + case XDG_TOPLEVEL_STATE_CONSTRAINED_LEFT: pending_state |= LIBDECOR_WINDOW_STATE_CONSTRAINED_LEFT; break; + case XDG_TOPLEVEL_STATE_CONSTRAINED_RIGHT: pending_state |= LIBDECOR_WINDOW_STATE_CONSTRAINED_RIGHT; break; + case XDG_TOPLEVEL_STATE_CONSTRAINED_TOP: pending_state |= LIBDECOR_WINDOW_STATE_CONSTRAINED_TOP; break; + case XDG_TOPLEVEL_STATE_CONSTRAINED_BOTTOM: pending_state |= LIBDECOR_WINDOW_STATE_CONSTRAINED_BOTTOM; break; #endif - default: - break; + + default: break; } } @@ -840,12 +811,8 @@ parse_states(struct wl_array *states){ } static void -xdg_toplevel_configure(void *user_data, - struct xdg_toplevel *xdg_toplevel, - int32_t width, - int32_t height, - struct wl_array *states) -{ +xdg_toplevel_configure(void *user_data, struct xdg_toplevel *xdg_toplevel, + int32_t width, int32_t height, struct wl_array *states){ enum libdecor_window_state window_state; window_state = parse_states(states); @@ -868,7 +835,8 @@ static void xdg_toplevel_configure_bounds(void *user_data, struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height){ int left = 0, top = 0, right = 0, bottom = 0; - if (frame_has_visible_client_side_decoration()){ + if (ctx.visible != 0 && + ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){ libdecor_plugin_gtk_frame_get_border_size(0, &left, &right, &top, &bottom); } @@ -922,44 +890,6 @@ const struct xdg_toplevel_listener xdg_toplevel_listener = { #endif }; -static void -toplevel_decoration_configure(void *data, - struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, - uint32_t mode) -{ - /* Ignore any _configure calls after the first, they will be - * from our set_mode call. */ - if (!ctx.has_decoration_mode) { - ctx.has_decoration_mode = true; - ctx.decoration_mode = mode; - } -} - -const struct zxdg_toplevel_decoration_v1_listener -xdg_toplevel_decoration_listener = { - toplevel_decoration_configure, -}; - -void -libdecor_frame_unref(void){ - if (ctx.decoration_manager != 0 && ctx.toplevel_decoration != 0){ - zxdg_toplevel_decoration_v1_destroy(ctx.toplevel_decoration); - ctx.toplevel_decoration = 0; - } - - if (ctx.xdg_toplevel != 0){ - xdg_toplevel_destroy(ctx.xdg_toplevel); - } - if (ctx.xdg_surface != 0){ - xdg_surface_destroy(ctx.xdg_surface); - } - - libdecor_plugin_gtk_frame_free(); - - free(ctx.title); - free(ctx.app_id); -} - void libdecor_frame_set_visibility(bool visible){ ctx.visible = visible; @@ -973,7 +903,7 @@ libdecor_frame_set_visibility(bool visible){ */ if (ctx.decoration_manager != 0 && ctx.toplevel_decoration != 0 && - ctx.has_decoration_mode != 0 && + ctx.has_decoration_mode && ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE){ zxdg_toplevel_decoration_v1_set_mode(ctx.toplevel_decoration, ctx.visible ? @@ -983,13 +913,11 @@ libdecor_frame_set_visibility(bool visible){ 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()){ - /* show client-side decorations */ + if (ctx.visible != 0 && + ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){ libdecor_plugin_gtk_frame_commit(0, 0); } else{ - /* destroy client-side decorations */ libdecor_plugin_gtk_frame_free(); } @@ -999,87 +927,18 @@ libdecor_frame_set_visibility(bool visible){ } } -void -libdecor_frame_set_title(const char *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(ctx.header)){ - draw_decoration(); - wl_surface_commit(ctx.wl_surface); - } - } - } -} - -void -libdecor_frame_set_app_id(const char *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); - } -} - -static void -set_capabilities(const enum libdecor_capabilities new_capabilities){ - struct libdecor_state *state; - - if (ctx.frame_capabilities != new_capabilities){ - ctx.frame_capabilities = new_capabilities; - if (ctx.frame_content_width != 0 && - ctx.frame_content_height != 0){ - - ctx.gtk_capabilities = ctx.frame_capabilities; - if (GTK_IS_WIDGET(ctx.header)){ - draw_decoration(); - wl_surface_commit(ctx.wl_surface); - } - - 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{ - ctx.content_limits = ctx.interactive_limits; - } - - libdecor_frame_commit(ctx.frame_content_width, ctx.frame_content_height, 0); - - wl_surface_commit(ctx.wl_surface); - } - } -} - void libdecor_frame_popup_grab(const char *seat_name){ libdecor_plugin_gtk_frame_popup_grab(seat_name); } -void -libdecor_frame_popup_ungrab(const char *seat_name){ - libdecor_plugin_gtk_frame_popup_ungrab(seat_name); -} - -void -libdecor_frame_show_window_menu(struct wl_seat *wl_seat, uint32_t serial, int x, int y){ - if (ctx.xdg_toplevel != 0){ - xdg_toplevel_show_window_menu(ctx.xdg_toplevel, wl_seat, serial, x, y); - } -} - void libdecor_frame_translate_coordinate(int content_x, int content_y, int *frame_x, int *frame_y){ *frame_x = content_x; *frame_y = content_y; - if (frame_has_visible_client_side_decoration()){ + if (ctx.visible != 0 && + ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){ int left, top; libdecor_plugin_gtk_frame_get_border_size(0, &left, 0, &top, 0); *frame_x += left; @@ -1231,7 +1090,8 @@ libdecor_frame_commit(int w, int h, struct libdecor_configuration *configuration libdecor_frame_apply_state(&state); /* switch between decoration modes */ - if (frame_has_visible_client_side_decoration()){ + if (ctx.visible != 0 && + ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){ libdecor_plugin_gtk_frame_commit(&state, configuration); } else{ @@ -1726,55 +1586,41 @@ find_widget_by_type(GtkWidget *widget, enum header_element type){ return data; } -static bool -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){ - /* 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}; + static const enum header_element elems[] = { + HEADER_TITLE, HEADER_MIN, HEADER_MAX, HEADER_CLOSE + }; + struct header_element_data result = {0}; - for (size_t i = 0; i < ARRAY_LENGTH(elems); i++) { - struct header_element_data elem = - find_widget_by_type(GTK_WIDGET(header_bar), elems[i]); - if (elem.widget) { + for (size_t i = 0; i < ARRAY_LENGTH(elems); i += 1){ + struct header_element_data elem = find_widget_by_type(GTK_WIDGET(header_bar), elems[i]); + if (elem.widget){ GtkAllocation allocation; gtk_widget_get_allocation(GTK_WIDGET(elem.widget), &allocation); - if (in_region(&allocation, &x, &y)) - return elem; + if (allocation.x <= x && x < allocation.x + allocation.width && + allocation.y <= y && y < allocation.y + allocation.height){ + result = elem; + break; + } } } - struct header_element_data elem_none = { .widget=NULL}; - return elem_none; + return(result); } static bool -own_proxy(struct wl_proxy *proxy){ - if (!proxy) - return false; - return (wl_proxy_get_tag(proxy) == &libdecor_gtk_proxy_tag); +own_proxy(void *proxy){ + bool result = false; + if (proxy != 0){ + result = (wl_proxy_get_tag((struct wl_proxy*)proxy) == &libdecor_gtk_proxy_tag); + } + return(result); } -static bool -own_surface(struct wl_surface *surface){ - return own_proxy((struct wl_proxy *) surface); -} +static void buffer_free(struct buffer *buffer); -static bool -own_output(struct wl_output *output){ - return own_proxy((struct wl_proxy *) output); -} - -static void -buffer_free(struct buffer *buffer); - -static void -draw_border_component(struct border_component *border_component, enum component component); +static void draw_border_component(struct border_component *border_component); static void send_cursor(struct seat *seat); @@ -1839,66 +1685,18 @@ toggle_maximized(void){ static void buffer_release(void *user_data, struct wl_buffer *wl_buffer){ struct buffer *buffer = user_data; - - if (buffer->is_detached) + if (buffer->is_detached){ buffer_free(buffer); - else + } + else{ buffer->in_use = false; + } } const struct wl_buffer_listener buffer_listener = { buffer_release }; -static struct buffer * -create_shm_buffer(int width, int height, bool opaque, int scale){ - struct wl_shm_pool *pool; - int fd, size, buffer_width, buffer_height, stride; - void *data; - struct buffer *buffer; - enum wl_shm_format buf_fmt; - - buffer_width = width * scale; - buffer_height = height * scale; - stride = buffer_width * 4; - size = stride * buffer_height; - - fd = libdecor_os_create_anonymous_file(size); - if (fd < 0) { - fprintf(stderr, "creating a buffer file for %d B failed: %s\n", size, strerror(errno)); - return NULL; - } - - data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if (data == MAP_FAILED) { - fprintf(stderr, "mmap failed: %s\n", strerror(errno)); - close(fd); - return NULL; - } - - buf_fmt = opaque ? WL_SHM_FORMAT_XRGB8888 : WL_SHM_FORMAT_ARGB8888; - - pool = wl_shm_create_pool(ctx.wl_shm, fd, size); - buffer = calloc(1, sizeof *buffer); - buffer->wl_buffer = wl_shm_pool_create_buffer(pool, 0, - buffer_width, buffer_height, - stride, - buf_fmt); - wl_buffer_add_listener(buffer->wl_buffer, &buffer_listener, buffer); - wl_shm_pool_destroy(pool); - close(fd); - - buffer->data = data; - buffer->data_size = size; - buffer->width = width; - buffer->height = height; - buffer->scale = scale; - buffer->buffer_width = buffer_width; - buffer->buffer_height = buffer_height; - - return buffer; -} - static void buffer_free(struct buffer *buffer){ if (buffer->wl_buffer) { @@ -1947,27 +1745,16 @@ libdecor_plugin_gtk_frame_free(void){ ctx.decoration_type = DECORATION_TYPE_NONE; } -static bool -is_border_surfaces_showing(void){ - return ctx.shadow_showing; -} - static void 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_attach(border_component->wl_surface, 0, 0, 0); wl_surface_commit(border_component->wl_surface); } } -static void -hide_border_surfaces(void){ - hide_border_component(&ctx.shadow); - ctx.shadow_showing = false; -} - static struct border_component * -get_component_for_surface(const struct wl_surface *surface){ +border_component_from_wl_surface(const struct wl_surface *surface){ struct border_component *result = 0; if (ctx.shadow.wl_surface == surface){ result = &ctx.shadow; @@ -1975,99 +1762,81 @@ get_component_for_surface(const struct wl_surface *surface){ else if (ctx.headerbar.wl_surface == surface){ result = &ctx.headerbar; } - return result; + return(result); } -static bool +static void redraw_scale(struct border_component *cmpnt){ struct surface_output *surface_output; int scale = 1; - if (cmpnt->wl_surface == NULL) - return false; - - wl_list_for_each(surface_output, &cmpnt->output_list, link) { - scale = MAX(scale, surface_output->output->scale); - } - if (scale != cmpnt->scale) { - cmpnt->scale = scale; - if ((ctx.decoration_type != DECORATION_TYPE_NONE) && - ((cmpnt->type != SHADOW) || is_border_surfaces_showing())) { - draw_border_component(cmpnt, cmpnt->type); - return true; + bool need_commit = false; + if (cmpnt->wl_surface != NULL){ + wl_list_for_each(surface_output, &cmpnt->output_list, link){ + scale = MAX(scale, surface_output->output->scale); + } + if (scale != cmpnt->scale){ + cmpnt->scale = scale; + if ((ctx.decoration_type != DECORATION_TYPE_NONE) && + (cmpnt->type != SHADOW || ctx.shadow_showing)){ + draw_border_component(cmpnt); + need_commit = true; + } } } - return false; -} - -static bool -add_surface_output(struct wl_output *wl_output, struct wl_list *list){ - struct output *output; - struct surface_output *surface_output; - if (!own_output(wl_output)) - return false; - - output = wl_output_get_user_data(wl_output); - - if (output == NULL) - return false; - - surface_output = calloc(1, sizeof *surface_output); - surface_output->output = output; - wl_list_insert(list, &surface_output->link); - return true; + if (need_commit){ + wl_surface_commit(ctx.wl_surface); + } } static void surface_enter(void *data, struct wl_surface *wl_surface, struct wl_output *wl_output){ - struct border_component *cmpnt; - - if (!(own_surface(wl_surface) && own_output(wl_output))) - return; - - cmpnt = get_component_for_surface(wl_surface); - if (cmpnt == NULL) - return; - - if (!add_surface_output(wl_output, &cmpnt->output_list)) - return; - - if (redraw_scale(cmpnt)){ - wl_surface_commit(ctx.wl_surface); - } -} - -static bool -remove_surface_output(struct wl_list *list, const struct wl_output *wl_output) -{ - struct surface_output *surface_output; - wl_list_for_each(surface_output, list, link) { - if (surface_output->output->wl_output == wl_output) { - wl_list_remove(&surface_output->link); - free(surface_output); - return true; + if (own_proxy(wl_surface) && own_proxy(wl_output)){ + struct border_component *cmpnt = border_component_from_wl_surface(wl_surface); + if (cmpnt != 0){ + bool new_surface_output = false; + if (own_proxy(wl_output)){ + struct output *output = wl_output_get_user_data(wl_output); + if (output != 0){ + struct wl_list *list = &cmpnt->output_list; + struct surface_output *surface_output = calloc(1, sizeof *surface_output); + surface_output->output = output; + wl_list_insert(list, &surface_output->link); + new_surface_output = true; + } + } + + if (new_surface_output){ + redraw_scale(cmpnt); + } } } - return false; } static void surface_leave(void *data, struct wl_surface *wl_surface, struct wl_output *wl_output){ - struct border_component *cmpnt; - - if (!(own_surface(wl_surface) && own_output(wl_output))) - return; - - cmpnt = get_component_for_surface(wl_surface); - if (cmpnt == NULL) - return; - - if (!remove_surface_output(&cmpnt->output_list, wl_output)) - return; - - if (redraw_scale(cmpnt)){ - wl_surface_commit(ctx.wl_surface); + if (own_proxy(wl_surface) && own_proxy(wl_output)){ + struct border_component *cmpnt = border_component_from_wl_surface(wl_surface); + if (cmpnt != 0){ + bool removed_surface_output = false; + { + struct wl_list *list = &cmpnt->output_list; + struct surface_output *surface_output; + wl_list_for_each(surface_output, list, link){ + if (surface_output->output->wl_output == wl_output){ + wl_list_remove(&surface_output->link); + free(surface_output); + removed_surface_output = true; + break; + } + } + } + + if (removed_surface_output){ + redraw_scale(cmpnt); + } + } } } @@ -2076,64 +1845,39 @@ static struct wl_surface_listener surface_listener = { surface_leave, }; -static void -create_surface_subsurface_pair(struct wl_surface **out_wl_surface, struct wl_subsurface **out_wl_subsurface){ - struct wl_surface *wl_surface; - struct wl_subsurface *wl_subsurface; - - wl_surface = wl_compositor_create_surface(ctx.wl_compositor); - wl_proxy_set_tag((struct wl_proxy *)wl_surface, &libdecor_gtk_proxy_tag); - wl_subsurface = wl_subcompositor_get_subsurface(ctx.wl_subcompositor, wl_surface, ctx.wl_surface); - - *out_wl_surface = wl_surface; - *out_wl_subsurface = wl_subsurface; -} - static void ensure_component(struct border_component *cmpnt){ - if (!cmpnt->wl_surface){ + if (cmpnt->wl_surface == 0){ wl_list_init(&cmpnt->output_list); cmpnt->scale = 1; - create_surface_subsurface_pair(&cmpnt->wl_surface, &cmpnt->wl_subsurface); + cmpnt->wl_surface = wl_compositor_create_surface(ctx.wl_compositor); + wl_proxy_set_tag((struct wl_proxy *)cmpnt->wl_surface, &libdecor_gtk_proxy_tag); + cmpnt->wl_subsurface = wl_subcompositor_get_subsurface(ctx.wl_subcompositor, cmpnt->wl_surface, ctx.wl_surface); wl_surface_add_listener(cmpnt->wl_surface, &surface_listener, 0); } } -static void -ensure_border_surfaces(void){ - ctx.shadow.type = SHADOW; - ctx.shadow.opaque = false; - ensure_component(&ctx.shadow); -} - static void ensure_title_bar_surfaces(void){ GtkStyleContext *context_hdr; ctx.headerbar.type = HEADER; ctx.headerbar.opaque = false; - ensure_component( &ctx.headerbar); + ensure_component(&ctx.headerbar); if (ctx.shadow.wl_surface){ - wl_subsurface_place_above(ctx.headerbar.wl_subsurface, - ctx.shadow.wl_surface); + wl_subsurface_place_above(ctx.headerbar.wl_subsurface, ctx.shadow.wl_surface); } - /* create an offscreen window with a header bar */ - /* TODO: This should only be done once at frame consutrction, but then - * the window and headerbar would not change style (e.g. backdrop) - * after construction. So we just destroy and re-create them. - */ - /* avoid warning when restoring previously turned off decoration */ if (GTK_IS_WIDGET(ctx.header)){ gtk_widget_destroy(ctx.header); - ctx.header = NULL; + ctx.header = 0; } - /* avoid warning when restoring previously turned off decoration */ if (GTK_IS_WIDGET(ctx.window)){ gtk_widget_destroy(ctx.window); - ctx.window = NULL; + ctx.window = 0; } + ctx.window = gtk_offscreen_window_new(); ctx.header = gtk_header_bar_new(); @@ -2141,7 +1885,6 @@ ensure_title_bar_surfaces(void){ "gtk-double-click-time", &ctx.double_click_time_ms, "gtk-dnd-drag-threshold", &ctx.drag_threshold, NULL); - /* set as "default" decoration */ g_object_set(ctx.header, "title", ctx.title, "has-subtitle", FALSE, @@ -2158,47 +1901,36 @@ ensure_title_bar_surfaces(void){ gtk_window_set_resizable(GTK_WINDOW(ctx.window), (ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE) != 0); } -static void -calculate_component_size(enum component component, - int *component_x, int *component_y, - int *component_width, int *component_height){ - int content_width, content_height; +static Extent2D +extent2d_from_component(enum component component){ + Extent2D result = {0}; + int width = ctx.frame_content_width; + int height = ctx.frame_content_height; + int title_height = 0; - 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(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(ctx.header); - /* reuse product of function call above */ - *component_height = title_height; - return; - } + if (GTK_IS_WIDGET(ctx.header)){ + title_height = gtk_widget_get_allocated_height(ctx.header); } - abort(); + switch (component){ + case NONE: break; + + case SHADOW: { + result.x = -(int)SHADOW_MARGIN; + result.y = -(int)(SHADOW_MARGIN + title_height); + result.w = width + 2*SHADOW_MARGIN; + result.h = title_height + height + 2*SHADOW_MARGIN; + }break; + + case HEADER: { + result.x = 0; + result.y = -title_height; + result.w = gtk_widget_get_allocated_width(ctx.header); + result.h = title_height; + }break; + } + + return(result); } static void @@ -2208,43 +1940,9 @@ array_append(enum header_element **array, size_t *n, enum header_element item){ (*array)[(*n)-1] = item; } -static void -draw_header_background(cairo_t *cr){ - /* background */ - GtkAllocation allocation; - GtkStyleContext* style; - - 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); -} - -static void -draw_header_title(cairo_surface_t *surface){ - /* title */ - GtkWidget *label; - GtkAllocation allocation; - cairo_surface_t *label_surface = NULL; - cairo_t *cr; - - label = find_widget_by_type(ctx.header, HEADER_TITLE).widget; - gtk_widget_get_allocation(label, &allocation); - - /* create subsection in which to draw label */ - label_surface = cairo_surface_create_for_rectangle( - surface, - allocation.x, allocation.y, - allocation.width, allocation.height); - cr = cairo_create(label_surface); - gtk_widget_size_allocate(label, &allocation); - gtk_widget_draw(label, cr); - cairo_destroy(cr); - cairo_surface_destroy(label_surface); -} - static void draw_header_button(cairo_t *cr, cairo_surface_t *surface, - enum header_element button_type, enum libdecor_window_state window_state){ + enum header_element button_type){ struct header_element_data elem; GtkWidget *button; GtkStyleContext* button_style; @@ -2277,7 +1975,7 @@ draw_header_button(cairo_t *cr, cairo_surface_t *surface, style_state = elem.state; /* change style based on window state and focus */ - if (!(window_state & LIBDECOR_WINDOW_STATE_ACTIVE)) { + if (!(ctx.frame_window_state & LIBDECOR_WINDOW_STATE_ACTIVE)) { style_state |= GTK_STATE_FLAG_BACKDROP; } if (ctx.hdr_focus.widget == button) { @@ -2307,7 +2005,7 @@ draw_header_button(cairo_t *cr, cairo_surface_t *surface, }break; case HEADER_MAX:{ - icon_name = (window_state & LIBDECOR_WINDOW_STATE_MAXIMIZED) ? + icon_name = (ctx.frame_window_state & LIBDECOR_WINDOW_STATE_MAXIMIZED) ? "window-restore-symbolic" : "window-maximize-symbolic"; }break; @@ -2381,173 +2079,180 @@ draw_header_button(cairo_t *cr, cairo_surface_t *surface, } } -static void -draw_header_buttons(cairo_t *cr, cairo_surface_t *surface){ - /* buttons */ - enum libdecor_window_state window_state; - enum header_element *buttons = NULL; - size_t nbuttons = 0; - - window_state = ctx.frame_window_state; - - /* set buttons by capability */ - if ((ctx.frame_capabilities & LIBDECOR_ACTION_MINIMIZE)){ - array_append(&buttons, &nbuttons, HEADER_MIN); - } - if ((ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){ - array_append(&buttons, &nbuttons, HEADER_MAX); - } - if ((ctx.frame_capabilities & LIBDECOR_ACTION_CLOSE)){ - array_append(&buttons, &nbuttons, HEADER_CLOSE); - } - - for (size_t i = 0; i < nbuttons; i++) { - draw_header_button(cr, surface, buttons[i], window_state); - } - free(buttons); -} - -static void -draw_header(cairo_t *cr, cairo_surface_t *surface){ - draw_header_background(cr); - draw_header_title(surface); - draw_header_buttons(cr, surface); -} - -static void -draw_component_content(struct buffer *buffer, int component_width, int component_height, enum component component){ - cairo_surface_t *surface; - cairo_t *cr; - - /* clear buffer */ - memset(buffer->data, 0, buffer->data_size); - - surface = cairo_image_surface_create_for_data(buffer->data, CAIRO_FORMAT_ARGB32, - buffer->buffer_width, buffer->buffer_height, - cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, - buffer->buffer_width)); - - cr = cairo_create(surface); - - cairo_surface_set_device_scale(surface, buffer->scale, buffer->scale); - - /* background */ - switch (component) { - case NONE: break; - - case SHADOW: { - render_shadow(cr, ctx.shadow_blur, - -(int)SHADOW_MARGIN/2, -(int)SHADOW_MARGIN/2, - buffer->width + SHADOW_MARGIN, buffer->height + SHADOW_MARGIN, - 64, 64); - }break; - - case HEADER: { - draw_header(cr, surface); - }break; - } - - /* mask the toplevel surface */ - if (component == SHADOW) { - int component_x, component_y, component_width, component_height; - calculate_component_size(component, &component_x, &component_y, &component_width, &component_height); - cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); - cairo_rectangle(cr, -component_x, -component_y, - ctx.frame_content_width, - ctx.frame_content_height); - cairo_fill(cr); - } - - cairo_destroy(cr); - cairo_surface_destroy(surface); -} - static void set_component_input_region(struct border_component *border_component){ if (border_component->type == SHADOW && ctx.shadow_showing){ struct wl_region *input_region; - int component_x; - int component_y; - int component_width; - int component_height; - - calculate_component_size(border_component->type, - &component_x, &component_y, - &component_width, &component_height); + Extent2D extent = extent2d_from_component(border_component->type); /* * the input region is the outer surface size minus the inner * content size */ input_region = wl_compositor_create_region(ctx.wl_compositor); - wl_region_add(input_region, 0, 0, - component_width, component_height); - wl_region_subtract(input_region, -component_x, -component_y, - ctx.frame_content_width, - ctx.frame_content_height); + wl_region_add(input_region, 0, 0, extent.w, extent.h); + wl_region_subtract(input_region, -extent.x, -extent.y, ctx.frame_content_width, ctx.frame_content_height); wl_surface_set_input_region(border_component->wl_surface, input_region); wl_region_destroy(input_region); } } static void -draw_border_component(struct border_component *border_component, enum component component){ +draw_border_component(struct border_component *border_component){ struct buffer *old_buffer; - struct buffer *buffer = NULL; - int component_x; - int component_y; - int component_width; - int component_height; + struct buffer *buffer = 0; int scale = border_component->scale; + enum component component = border_component->type; - if (border_component->wl_surface == NULL) - return; - - calculate_component_size(component, - &component_x, &component_y, - &component_width, &component_height); - - set_component_input_region(border_component); - - old_buffer = border_component->buffer; - if (old_buffer){ - if (!old_buffer->in_use && - old_buffer->buffer_width == component_width * scale && - old_buffer->buffer_height == component_height * scale){ - buffer = old_buffer; + if (border_component->wl_surface != 0){ + Extent2D extent = extent2d_from_component(component); + + set_component_input_region(border_component); + + old_buffer = border_component->buffer; + if (old_buffer != 0){ + if (!old_buffer->in_use && + old_buffer->buffer_width == extent.w*scale && + old_buffer->buffer_height == extent.h*scale){ + buffer = old_buffer; + } + else{ + buffer_free(old_buffer); + border_component->buffer = 0; + } } - else{ - buffer_free(old_buffer); - border_component->buffer = NULL; + + if (buffer == 0){ + int width = extent.w; + int height = extent.h; + bool opaque = border_component->opaque; + + struct wl_shm_pool *pool; + int fd, size, buffer_width, buffer_height, stride; + void *data; + enum wl_shm_format buf_fmt; + + buffer_width = width * scale; + buffer_height = height * scale; + stride = buffer_width * 4; + size = stride * buffer_height; + + fd = libdecor_os_create_anonymous_file(size); + if (fd >= 0){ + data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (data != MAP_FAILED){ + buf_fmt = opaque ? WL_SHM_FORMAT_XRGB8888 : WL_SHM_FORMAT_ARGB8888; + + pool = wl_shm_create_pool(ctx.wl_shm, fd, size); + buffer = calloc(1, sizeof *buffer); + buffer->wl_buffer = wl_shm_pool_create_buffer(pool, 0, + buffer_width, buffer_height, + stride, + buf_fmt); + wl_buffer_add_listener(buffer->wl_buffer, &buffer_listener, buffer); + wl_shm_pool_destroy(pool); + + buffer->data = data; + buffer->data_size = size; + buffer->width = width; + buffer->height = height; + buffer->scale = scale; + buffer->buffer_width = buffer_width; + buffer->buffer_height = buffer_height; + } + + close(fd); + } } + + memset(buffer->data, 0, buffer->data_size); + + { + int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, buffer->buffer_width); + cairo_surface_t *surface = cairo_image_surface_create_for_data(buffer->data, CAIRO_FORMAT_ARGB32, + buffer->buffer_width, buffer->buffer_height, stride); + cairo_t *cr = cairo_create(surface); + cairo_surface_set_device_scale(surface, buffer->scale, buffer->scale); + + switch (component) { + case NONE: break; + + case SHADOW: { + render_shadow(cr, ctx.shadow_blur, + -(int)SHADOW_MARGIN/2, -(int)SHADOW_MARGIN/2, + buffer->width + SHADOW_MARGIN, buffer->height + SHADOW_MARGIN, + 64, 64); + cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); + cairo_rectangle(cr, -extent.x, -extent.y, ctx.frame_content_width, ctx.frame_content_height); + cairo_fill(cr); + }break; + + case HEADER: { + /* background */ + { + GtkAllocation allocation; + GtkStyleContext* style; + 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); + } + + /* title */ + { + GtkWidget *label; + GtkAllocation allocation; + cairo_surface_t *label_surface = NULL; + cairo_t *cr; + + label = find_widget_by_type(ctx.header, HEADER_TITLE).widget; + gtk_widget_get_allocation(label, &allocation); + label_surface = cairo_surface_create_for_rectangle(surface, allocation.x, allocation.y, allocation.width, allocation.height); + cr = cairo_create(label_surface); + gtk_widget_size_allocate(label, &allocation); + gtk_widget_draw(label, cr); + cairo_destroy(cr); + cairo_surface_destroy(label_surface); + } + + /* buttons */ + { + enum header_element buttons[3] = {0}; + size_t nbuttons = 0; + + if ((ctx.frame_capabilities & LIBDECOR_ACTION_MINIMIZE)){ + buttons[nbuttons] = HEADER_MIN; + nbuttons += 1; + } + if ((ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){ + buttons[nbuttons] = HEADER_MAX; + nbuttons += 1; + } + if ((ctx.frame_capabilities & LIBDECOR_ACTION_CLOSE)){ + buttons[nbuttons] = HEADER_CLOSE; + nbuttons += 1; + } + + for (size_t i = 0; i < nbuttons; i += 1){ + enum header_element button_type = buttons[i]; + draw_header_button(cr, surface, button_type); + } + } + }break; + } + + cairo_destroy(cr); + cairo_surface_destroy(surface); + } + + wl_surface_attach(border_component->wl_surface, buffer->wl_buffer, 0, 0); + wl_surface_set_buffer_scale(border_component->wl_surface, buffer->scale); + buffer->in_use = true; + wl_surface_commit(border_component->wl_surface); + wl_surface_damage_buffer(border_component->wl_surface, 0, 0, extent.w*scale, extent.h*scale); + wl_subsurface_set_position(border_component->wl_subsurface, extent.x, extent.y); + + border_component->buffer = buffer; } - - if (!buffer){ - buffer = create_shm_buffer(component_width, - component_height, - border_component->opaque, - border_component->scale); - } - - draw_component_content(buffer, component_width, component_height, component); - - wl_surface_attach(border_component->wl_surface, buffer->wl_buffer, 0, 0); - wl_surface_set_buffer_scale(border_component->wl_surface, buffer->scale); - buffer->in_use = true; - wl_surface_commit(border_component->wl_surface); - wl_surface_damage_buffer(border_component->wl_surface, 0, 0, - component_width * scale, - component_height * scale); - wl_subsurface_set_position(border_component->wl_subsurface, - component_x, component_y); - - border_component->buffer = buffer; -} - -static void -draw_border(void){ - draw_border_component(&ctx.shadow, SHADOW); - ctx.shadow_showing = true; } static void @@ -2598,35 +2303,32 @@ draw_title_bar(void){ /* set default height */ gtk_widget_get_preferred_height(ctx.header, 0, &allocation.height); gtk_widget_size_allocate(ctx.header, &allocation); - draw_border_component(&ctx.headerbar, HEADER); + draw_border_component(&ctx.headerbar); } } static void draw_decoration(void){ - switch (ctx.decoration_type) { + switch (ctx.decoration_type){ case DECORATION_TYPE_NONE: { - if (is_border_surfaces_showing()){ - hide_border_surfaces(); - } + hide_border_component(&ctx.shadow); + ctx.shadow_showing = false; hide_border_component(&ctx.headerbar); }break; case DECORATION_TYPE_ALL: { - /* show borders */ - ensure_border_surfaces(); - draw_border(); - /* show title bar */ + ctx.shadow.type = SHADOW; + ctx.shadow.opaque = false; + ensure_component(&ctx.shadow); + draw_border_component(&ctx.shadow); + ctx.shadow_showing = true; ensure_title_bar_surfaces(); draw_title_bar(); }break; case DECORATION_TYPE_TITLE_ONLY: { - /* hide borders */ - if (is_border_surfaces_showing()){ - hide_border_surfaces(); - } - /* show title bar */ + hide_border_component(&ctx.shadow); + ctx.shadow_showing = false; ensure_title_bar_surfaces(); draw_title_bar(); }break; @@ -2634,23 +2336,19 @@ draw_decoration(void){ } static enum decoration_type -window_state_to_decoration_type(enum libdecor_window_state window_state) -{ +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){ - return DECORATION_TYPE_NONE; + 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)){ - /* title bar, no shadows */ - return DECORATION_TYPE_TITLE_ONLY; - } - else{ - /* title bar, shadows */ - return DECORATION_TYPE_ALL; + result = DECORATION_TYPE_TITLE_ONLY; } + return(result); } static void @@ -2671,27 +2369,27 @@ libdecor_plugin_gtk_frame_commit(struct libdecor_state *state, struct libdecor_c new_content_height = ctx.frame_content_height; old_decoration_type = ctx.decoration_type; - new_decoration_type = window_state_to_decoration_type(new_window_state); + 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) - return; - - 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.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; + 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.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; + } } } @@ -2701,18 +2399,13 @@ update_component_focus(struct wl_surface *surface, struct seat *seat){ static struct border_component *child_component; static struct border_component *focus_component; - border_component = get_component_for_surface(surface); + border_component = border_component_from_wl_surface(surface); focus_component = border_component; wl_list_for_each(child_component, &border_component->child_components, link) { - int component_x = 0, component_y = 0; - int component_width = 0, component_height = 0; - - calculate_component_size(child_component->type, &component_x, &component_y, &component_width, &component_height); - if (seat->pointer_x >= component_x && - seat->pointer_x < component_x + component_width && - seat->pointer_y >= component_y && - seat->pointer_y < component_y + component_height) { + Extent2D extent = extent2d_from_component(child_component->type); + if (seat->pointer_x >= extent.x && seat->pointer_x < extent.x + extent.w && + seat->pointer_y >= extent.y && seat->pointer_y < extent.y + extent.h) { focus_component = child_component; break; } @@ -2727,30 +2420,12 @@ update_component_focus(struct wl_surface *surface, struct seat *seat){ ctx.focus = focus_component; } -static void -sync_active_component(struct seat *seat){ - struct border_component *old_active; - - if (seat->pointer_focus){ - old_active = ctx.active; - update_component_focus(seat->pointer_focus, seat); - if (old_active != ctx.active) { - draw_decoration(); - wl_surface_commit(ctx.wl_surface); - } - - if (update_local_cursor(seat)){ - send_cursor(seat); - } - } -} - static void synthesize_pointer_enter(struct seat *seat){ struct wl_surface *surface; surface = seat->pointer_focus; - if (surface && own_surface(surface)){ + if (surface && own_proxy(surface)){ update_component_focus(seat->pointer_focus, seat); ctx.grab = 0; if (ctx.active) { @@ -2765,7 +2440,7 @@ synthesize_pointer_enter(struct seat *seat){ static void synthesize_pointer_leave(struct seat *seat){ struct wl_surface *surface = seat->pointer_focus; - if (surface != 0 && own_surface(surface)){ + if (surface != 0 && own_proxy(surface)){ if (ctx.active != 0){ ctx.active = 0; draw_decoration(); @@ -2796,37 +2471,41 @@ libdecor_plugin_gtk_frame_popup_grab(const char *seat_name){ static void libdecor_plugin_gtk_frame_popup_ungrab(const char *seat_name){ struct seat *seat; - + bool got_seat = 0; wl_list_for_each(seat, &ctx.seat_list, link) { if (STREQL(seat->name, seat_name)) { - if (!seat->grabbed) { - fprintf(stderr, "libdecor-WARNING: Application " - "tried to ungrab seat twice\n"); + got_seat = 1; + break; + } + } + + if (got_seat){ + if (!seat->grabbed){ + fprintf(stderr, "libdecor-WARNING: Application tried to ungrab seat twice\n"); + } + seat->grabbed = false; + synthesize_pointer_enter(seat); + + if (seat->pointer_focus){ + struct border_component *old_active = ctx.active; + update_component_focus(seat->pointer_focus, seat); + if (old_active != ctx.active) { + draw_decoration(); + wl_surface_commit(ctx.wl_surface); + } + + if (update_local_cursor(seat)){ + send_cursor(seat); } - seat->grabbed = false; - synthesize_pointer_enter(seat); - sync_active_component(seat); - return; } } fprintf(stderr, "libdecor-WARNING: Application tried to ungrab unknown seat\n"); } -static bool -libdecor_plugin_gtk_frame_get_border_size(struct libdecor_configuration *configuration, +static void +libdecor_plugin_gtk_frame_get_border_size(enum libdecor_window_state window_state, 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)){ - return false; - } - } - else{ - window_state = ctx.frame_window_state; - } - if (left){ *left = 0; } @@ -2837,19 +2516,19 @@ libdecor_plugin_gtk_frame_get_border_size(struct libdecor_configuration *configu *bottom = 0; } if (top) { - enum decoration_type type = window_state_to_decoration_type(window_state); - - switch (type) { + switch (decoration_type_from_window_state(window_state)) { case DECORATION_TYPE_NONE: { *top = 0; }break; - case DECORATION_TYPE_ALL:{ - ensure_border_surfaces(); + case DECORATION_TYPE_ALL: { + ctx.shadow.type = SHADOW; + ctx.shadow.opaque = false; + ensure_component(&ctx.shadow); } G_GNUC_FALLTHROUGH; case DECORATION_TYPE_TITLE_ONLY: { - if (!ctx.header){ + if (ctx.header == 0){ ensure_title_bar_surfaces(); } gtk_widget_show_all(ctx.window); @@ -2857,20 +2536,20 @@ libdecor_plugin_gtk_frame_get_border_size(struct libdecor_configuration *configu }break; } } - - return true; } static void cursor_surface_enter(void *data, struct wl_surface *wl_surface, struct wl_output *wl_output){ struct seat *seat = data; - if (own_output(wl_output)) { + if (own_proxy(wl_output)) { struct cursor_output *cursor_output; cursor_output = calloc(1, sizeof *cursor_output); cursor_output->output = wl_output_get_user_data(wl_output); wl_list_insert(&seat->cursor_outputs, &cursor_output->link); - if (update_local_cursor(seat)) + + if (update_local_cursor(seat)){ send_cursor(seat); + } } } @@ -2878,17 +2557,18 @@ static void cursor_surface_leave(void *data, struct wl_surface *wl_surface, struct wl_output *wl_output){ struct seat *seat = data; - if (own_output(wl_output)) { + if (own_proxy(wl_output)){ struct cursor_output *cursor_output, *tmp; - wl_list_for_each_safe(cursor_output, tmp, &seat->cursor_outputs, link) { - if (cursor_output->output->wl_output == wl_output) { + wl_list_for_each_safe(cursor_output, tmp, &seat->cursor_outputs, link){ + if (cursor_output->output->wl_output == wl_output){ wl_list_remove(&cursor_output->link); free(cursor_output); } } - if (update_local_cursor(seat)) + if (update_local_cursor(seat)){ send_cursor(seat); + } } } @@ -2898,55 +2578,18 @@ static struct wl_surface_listener cursor_surface_listener = { }; static void -ensure_cursor_surface(struct seat *seat) -{ +ensure_cursor_surface(struct seat *seat){ struct wl_compositor *wl_compositor = ctx.wl_compositor; - if (seat->cursor_surface) + if (seat->cursor_surface){ return; + } seat->cursor_surface = wl_compositor_create_surface(wl_compositor); wl_surface_add_listener(seat->cursor_surface, &cursor_surface_listener, seat); } -static bool -ensure_cursor_theme(struct seat *seat){ - int scale = 1; - struct wl_cursor_theme *theme; - struct cursor_output *cursor_output; - - wl_list_for_each(cursor_output, &seat->cursor_outputs, link) { - scale = MAX(scale, cursor_output->output->scale); - } - - if (seat->cursor_theme && seat->cursor_scale == scale) - return false; - - seat->cursor_scale = scale; - theme = wl_cursor_theme_load(ctx.cursor_theme_name, ctx.cursor_size*scale, - ctx.wl_shm); - if (theme == NULL) - return false; - - if (seat->cursor_theme) - wl_cursor_theme_destroy(seat->cursor_theme); - - seat->cursor_theme = theme; - - for (unsigned int i = 0; i < ARRAY_LENGTH(cursor_names); i++) { - seat->cursors[i] = wl_cursor_theme_get_cursor( - seat->cursor_theme, - cursor_names[i]); - } - - seat->cursor_left_ptr = wl_cursor_theme_get_cursor(seat->cursor_theme, - "left_ptr"); - seat->current_cursor = seat->cursor_left_ptr; - - return true; -} - enum libdecor_resize_edge component_edge(const struct border_component *cmpnt, const int pointer_x, const int pointer_y, @@ -2985,44 +2628,73 @@ component_edge(const struct border_component *cmpnt, static bool update_local_cursor(struct seat *seat){ + bool result = false; + if (!seat->pointer_focus){ seat->current_cursor = seat->cursor_left_ptr; - return false; - } - - if (!own_surface(seat->pointer_focus)){ - return false; - } - - struct wl_cursor *wl_cursor = NULL; - - if (!ctx.active){ - seat->current_cursor = seat->cursor_left_ptr; - return false; - } - - bool theme_updated = ensure_cursor_theme(seat); - - if (ctx.active->type == SHADOW && - is_border_surfaces_showing() && - (ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){ - enum libdecor_resize_edge edge; - edge = component_edge(ctx.active, seat->pointer_x, seat->pointer_y, SHADOW_MARGIN); - - if (edge != LIBDECOR_RESIZE_EDGE_NONE){ - wl_cursor = seat->cursors[edge - 1]; - } } else{ - wl_cursor = seat->cursor_left_ptr; + if (own_proxy(seat->pointer_focus)){ + if (!ctx.active){ + seat->current_cursor = seat->cursor_left_ptr; + } + else{ + bool theme_updated = false; + { + int scale = 1; + struct cursor_output *cursor_output; + wl_list_for_each(cursor_output, &seat->cursor_outputs, link){ + scale = MAX(scale, cursor_output->output->scale); + } + + if (seat->cursor_theme == 0 || seat->cursor_scale != scale){ + struct wl_cursor_theme *theme; + + seat->cursor_scale = scale; + theme = wl_cursor_theme_load(ctx.cursor_theme_name, ctx.cursor_size*scale, ctx.wl_shm); + if (theme != 0){ + if (seat->cursor_theme){ + wl_cursor_theme_destroy(seat->cursor_theme); + } + + seat->cursor_theme = theme; + + for (unsigned int i = 0; i < ARRAY_LENGTH(cursor_names); i++) { + seat->cursors[i] = wl_cursor_theme_get_cursor(seat->cursor_theme, cursor_names[i]); + } + + seat->cursor_left_ptr = wl_cursor_theme_get_cursor(seat->cursor_theme, "left_ptr"); + seat->current_cursor = seat->cursor_left_ptr; + theme_updated = true; + } + } + } + + struct wl_cursor *wl_cursor = NULL; + if (ctx.active->type == SHADOW && ctx.shadow_showing && + (ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){ + enum libdecor_resize_edge edge; + edge = component_edge(ctx.active, seat->pointer_x, seat->pointer_y, SHADOW_MARGIN); + if (edge != LIBDECOR_RESIZE_EDGE_NONE){ + wl_cursor = seat->cursors[edge - 1]; + } + } + else{ + wl_cursor = seat->cursor_left_ptr; + } + + if (seat->current_cursor != wl_cursor) { + seat->current_cursor = wl_cursor; + result = true; + } + else{ + result = theme_updated; + } + } + } } - if (seat->current_cursor != wl_cursor) { - seat->current_cursor = wl_cursor; - return true; - } - - return theme_updated; + return(result); } static void @@ -3054,10 +2726,9 @@ pointer_enter(void *data, struct wl_pointer *wl_pointer, uint32_t serial, if (surface){ struct seat *seat = data; - bool is_own_surface = own_surface(surface); + bool is_own_surface = own_proxy(surface); if (is_own_surface || ctx.handle_cursor){ ensure_cursor_surface(seat); - seat->pointer_x = wl_fixed_to_int(surface_x); seat->pointer_y = wl_fixed_to_int(surface_y); seat->serial = serial; @@ -3065,7 +2736,7 @@ pointer_enter(void *data, struct wl_pointer *wl_pointer, uint32_t serial, } if (is_own_surface){ - ctx.active = get_component_for_surface(surface); + ctx.active = border_component_from_wl_surface(surface); if (ctx.active){ draw_decoration(); wl_surface_commit(ctx.wl_surface); @@ -3082,7 +2753,7 @@ pointer_leave(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct seat->pointer_focus = NULL; - if (surface != 0 && own_surface(surface)){ + if (surface != 0 && own_proxy(surface)){ ctx.titlebar_gesture.state = TITLEBAR_GESTURE_STATE_INIT; ctx.titlebar_gesture.first_pressed_button = 0; @@ -3101,7 +2772,7 @@ pointer_motion(void *data, struct wl_pointer *wl_pointer, uint32_t time, struct seat *seat = data; struct header_element_data new_focus; - if (!seat->pointer_focus || !own_surface(seat->pointer_focus)) + if (!seat->pointer_focus || !own_proxy(seat->pointer_focus)) return; seat->pointer_x = wl_fixed_to_int(surface_x); @@ -3166,7 +2837,7 @@ handle_titlebar_gesture(struct seat *seat, uint32_t serial, enum titlebar_gestur case TITLEBAR_GESTURE_RIGHT_CLICK: { const int title_height = gtk_widget_get_allocated_height(ctx.header); - libdecor_frame_show_window_menu(seat->wl_seat, serial, seat->pointer_x, seat->pointer_y -title_height); + xdg_toplevel_show_window_menu(ctx.xdg_toplevel, seat->wl_seat, serial, seat->pointer_x, -title_height); }break; } } @@ -3286,7 +2957,7 @@ static void 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; - if (seat->pointer_focus && own_surface(seat->pointer_focus)){ + if (seat->pointer_focus && own_proxy(seat->pointer_focus)){ switch (ctx.active->type) { case SHADOW: { handle_button_on_shadow(seat, serial, time, button, state); @@ -3335,65 +3006,65 @@ touch_down(void *data, struct wl_touch *wl_touch, uint32_t serial, wl_fixed_t x, wl_fixed_t y){ struct seat *seat = data; - if (!surface || !own_surface(surface)) - return; - - seat->touch_focus = surface; - ctx.touch_active = get_component_for_surface(surface); - - if (!ctx.touch_active) - return; - - update_touch_focus(seat, x, y); - - /* update decorations */ - draw_decoration(); - wl_surface_commit(ctx.wl_surface); - - enum libdecor_resize_edge edge = LIBDECOR_RESIZE_EDGE_NONE; - switch (ctx.touch_active->type) { - case SHADOW: { - edge = component_edge(ctx.touch_active, wl_fixed_to_int(x), wl_fixed_to_int(y), SHADOW_MARGIN); - }break; + if (surface != 0 && own_proxy(surface)){ - case HEADER: { - switch (ctx.hdr_focus.type){ - case HEADER_MIN: - case HEADER_MAX: - case HEADER_CLOSE: { - ctx.hdr_focus.state |= GTK_STATE_FLAG_ACTIVE; - draw_title_bar(); - wl_surface_commit(ctx.wl_surface); + seat->touch_focus = surface; + ctx.touch_active = border_component_from_wl_surface(surface); + + if (ctx.touch_active){ + update_touch_focus(seat, x, y); + + /* update decorations */ + draw_decoration(); + wl_surface_commit(ctx.wl_surface); + + enum libdecor_resize_edge edge = LIBDECOR_RESIZE_EDGE_NONE; + switch (ctx.touch_active->type) { + case SHADOW: { + edge = component_edge(ctx.touch_active, wl_fixed_to_int(x), wl_fixed_to_int(y), SHADOW_MARGIN); }break; - default: { - if (time - seat->touch_down_time_stamp < (uint32_t)ctx.double_click_time_ms) { - if ((ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){ - toggle_maximized(); - } - } - else{ - if (ctx.frame_capabilities & LIBDECOR_ACTION_MOVE){ - seat->touch_down_time_stamp = time; - libdecor_frame_move(seat->wl_seat, serial); - } + case HEADER: { + switch (ctx.hdr_focus.type){ + case HEADER_MIN: + case HEADER_MAX: + case HEADER_CLOSE: { + ctx.hdr_focus.state |= GTK_STATE_FLAG_ACTIVE; + draw_title_bar(); + wl_surface_commit(ctx.wl_surface); + }break; + + default: { + if (time - seat->touch_down_time_stamp < (uint32_t)ctx.double_click_time_ms) { + if ((ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){ + toggle_maximized(); + } + } + else{ + if (ctx.frame_capabilities & LIBDECOR_ACTION_MOVE){ + seat->touch_down_time_stamp = time; + libdecor_frame_move(seat->wl_seat, serial); + } + } + }break; } }break; + + default: break; } - }break; - - default: break; - } - if (edge != LIBDECOR_RESIZE_EDGE_NONE && - (ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)) { - libdecor_frame_resize(seat->wl_seat, serial, edge); + + if (edge != LIBDECOR_RESIZE_EDGE_NONE && + (ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)) { + libdecor_frame_resize(seat->wl_seat, serial, edge); + } + } } } static void touch_up(void *data, struct wl_touch *wl_touch, uint32_t serial, uint32_t time, int32_t id){ struct seat *seat = data; - if (seat->touch_focus && own_surface(seat->touch_focus)){ + if (seat->touch_focus && own_proxy(seat->touch_focus)){ if (ctx.touch_active != 0){ if (ctx.touch_active->type == HEADER){ switch (ctx.hdr_focus.type) { @@ -3441,8 +3112,7 @@ static void touch_motion(void *data, struct wl_touch *wl_touch, uint32_t time, int32_t id, wl_fixed_t x, wl_fixed_t y){ struct seat *seat = data; - - if (seat->touch_focus && own_surface(seat->touch_focus)){ + if (seat->touch_focus && own_proxy(seat->touch_focus)){ update_touch_focus(seat, x, y); } } @@ -3479,14 +3149,12 @@ output_done(void *data, struct wl_output *wl_output){ struct seat *seat; if (ctx.decoration_type != DECORATION_TYPE_NONE){ - bool updated = redraw_scale(&ctx.shadow); - if (updated){ - wl_surface_commit(ctx.wl_surface); - } + redraw_scale(&ctx.shadow); } wl_list_for_each(seat, &ctx.seat_list, link) { - if (update_local_cursor(seat)) + if (update_local_cursor(seat)){ send_cursor(seat); + } } } @@ -3541,20 +3209,16 @@ output_removed(struct output *output){ static bool get_cursor_settings_from_env(char **theme, int *size){ - char *env_xtheme; - char *env_xsize; + char *env_xtheme = getenv("XCURSOR_THEME"); + char *env_xsize = getenv("XCURSOR_SIZE"); + bool got_theme = (env_xtheme != 0 && env_xsize != 0); - env_xtheme = getenv("XCURSOR_THEME"); - if (env_xtheme != 0){ + if (got_theme){ *theme = strdup(env_xtheme); - } - - env_xsize = getenv("XCURSOR_SIZE"); - if (env_xsize != 0){ *size = atoi(env_xsize); } - return env_xtheme != NULL && env_xsize != NULL; + return(got_theme); } #ifdef HAS_DBUS @@ -3562,61 +3226,51 @@ get_cursor_settings_from_env(char **theme, int *size){ static DBusMessage * get_setting_sync(DBusConnection *const connection, const char *key, const char *value){ - DBusError error; - dbus_bool_t success; + DBusMessage *reply = 0; DBusMessage *message; - DBusMessage *reply; message = dbus_message_new_method_call("org.freedesktop.portal.Desktop", "/org/freedesktop/portal/desktop", "org.freedesktop.portal.Settings", "Read"); - success = dbus_message_append_args(message, - DBUS_TYPE_STRING, &key, - DBUS_TYPE_STRING, &value, - DBUS_TYPE_INVALID); - - if (!success) - return NULL; - - dbus_error_init(&error); - - reply = dbus_connection_send_with_reply_and_block(connection, - message, - DBUS_TIMEOUT_USE_DEFAULT, - &error); - - dbus_message_unref(message); - - if (dbus_error_is_set(&error)) { - dbus_error_free(&error); - return NULL; + if (message != 0){ + dbus_bool_t success = dbus_message_append_args(message, + DBUS_TYPE_STRING, &key, + DBUS_TYPE_STRING, &value, + DBUS_TYPE_INVALID); + if (success){ + DBusError error; + dbus_error_init(&error); + reply = dbus_connection_send_with_reply_and_block(connection, message, DBUS_TIMEOUT_USE_DEFAULT, &error); + if (dbus_error_is_set(&error) && reply != 0){ + dbus_message_unref(reply); + reply = 0; + } + dbus_error_free(&error); + } + dbus_message_unref(message); } - dbus_error_free(&error); - return reply; + return(reply); } static bool parse_type(DBusMessage *const reply, const int type, void *value){ + bool result = false; DBusMessageIter iter[3]; - dbus_message_iter_init(reply, &iter[0]); - if (dbus_message_iter_get_arg_type(&iter[0]) != DBUS_TYPE_VARIANT) - return false; - - dbus_message_iter_recurse(&iter[0], &iter[1]); - if (dbus_message_iter_get_arg_type(&iter[1]) != DBUS_TYPE_VARIANT) - return false; - - dbus_message_iter_recurse(&iter[1], &iter[2]); - if (dbus_message_iter_get_arg_type(&iter[2]) != type) - return false; - - dbus_message_iter_get_basic(&iter[2], value); - - return true; + if (dbus_message_iter_get_arg_type(&iter[0]) == DBUS_TYPE_VARIANT){ + dbus_message_iter_recurse(&iter[0], &iter[1]); + if (dbus_message_iter_get_arg_type(&iter[1]) == DBUS_TYPE_VARIANT){ + dbus_message_iter_recurse(&iter[1], &iter[2]); + if (dbus_message_iter_get_arg_type(&iter[2]) == type){ + dbus_message_iter_get_basic(&iter[2], value); + result = true; + } + } + } + return(result); } bool @@ -3625,46 +3279,40 @@ libdecor_get_cursor_settings(char **theme, int *size){ static const char key_theme[] = "cursor-theme"; static const char key_size[] = "cursor-size"; + bool got_theme = false; + const char *value_theme = 0; + DBusError error; DBusConnection *connection; - DBusMessage *reply; - const char *value_theme = NULL; dbus_error_init(&error); - connection = dbus_bus_get(DBUS_BUS_SESSION, &error); - if (dbus_error_is_set(&error)) - goto fallback; - - reply = get_setting_sync(connection, name, key_theme); - if (!reply) - goto fallback; - - if (!parse_type(reply, DBUS_TYPE_STRING, &value_theme)) { - dbus_message_unref(reply); - goto fallback; + if (!dbus_error_is_set(&error)){ + DBusMessage *reply = get_setting_sync(connection, name, key_theme); + if (reply != 0){ + if (parse_type(reply, DBUS_TYPE_STRING, &value_theme)) { + *theme = strdup(value_theme); + } + dbus_message_unref(reply); + } } - *theme = strdup(value_theme); - - dbus_message_unref(reply); - - reply = get_setting_sync(connection, name, key_size); - if (!reply) - goto fallback; - - if (!parse_type(reply, DBUS_TYPE_INT32, size)) { - dbus_message_unref(reply); - goto fallback; + if (value_theme != 0){ + DBusMessage *reply = get_setting_sync(connection, name, key_size); + if (reply){ + if (parse_type(reply, DBUS_TYPE_INT32, size)){ + got_theme = true; + } + dbus_message_unref(reply); + } } - dbus_message_unref(reply); + if (!got_theme){ + got_theme = get_cursor_settings_from_env(theme, size); + } - return true; - - fallback: - return get_cursor_settings_from_env(theme, size); + return(got_theme); } enum libdecor_color_scheme @@ -3678,36 +3326,31 @@ libdecor_get_color_scheme(){ DBusMessage *reply; dbus_error_init(&error); - connection = dbus_bus_get(DBUS_BUS_SESSION, &error); - if (dbus_error_is_set(&error)) - return 0; - - reply = get_setting_sync(connection, name, key_color_scheme); - if (!reply) - return 0; - - if (!parse_type(reply, DBUS_TYPE_UINT32, &color)) { - dbus_message_unref(reply); - return 0; + if (!dbus_error_is_set(&error)){ + reply = get_setting_sync(connection, name, key_color_scheme); + if (reply){ + if (!parse_type(reply, DBUS_TYPE_UINT32, &color)) { + color = 0; + } + dbus_message_unref(reply); + } } - dbus_message_unref(reply); - - return color; + return(color); } #else bool libdecor_get_cursor_settings(char **theme, int *size){ - return get_cursor_settings_from_env(theme, size); + return(get_cursor_settings_from_env(theme, size)); } uint32_t libdecor_get_color_scheme(){ - return LIBDECOR_COLOR_SCHEME_DEFAULT; + return(LIBDECOR_COLOR_SCHEME_DEFAULT); } #endif diff --git a/digesting_libdecor.h b/digesting_libdecor.h index 0eba988..ad1fd87 100644 --- a/digesting_libdecor.h +++ b/digesting_libdecor.h @@ -50,6 +50,15 @@ #define STREQL(a,b) (((a)==0 && (b)==0) || \ ((a)!=0 && (b)!=0 && strcmp((a),(b))==0)) +// mine + +typedef struct Extent2D{ + int x; + int y; + int w; + int h; +} Extent2D; + // libdecor.h struct libdecor_configuration; @@ -275,11 +284,7 @@ enum titlebar_gesture { // libdecor.h -void libdecor_frame_unref(void); void libdecor_frame_set_visibility(bool visible); - -void libdecor_frame_set_title(const char *title); -void libdecor_frame_set_app_id(const char *app_id); void libdecor_frame_show_window_menu(struct wl_seat *wl_seat, uint32_t serial, int x, int y); void libdecor_frame_popup_grab(const char *seat_name); @@ -295,7 +300,6 @@ bool libdecor_frame_is_floating(void); void libdecor_frame_map(void); bool libdecor_configuration_get_content_size(struct libdecor_configuration *configuration, int *width, int *height); -bool libdecor_configuration_get_window_state(struct libdecor_configuration *configuration, enum libdecor_window_state *window_state); int libdecor_dispatch(int timeout); @@ -318,8 +322,6 @@ int libdecor_os_create_anonymous_file(off_t size); static void init_shell_surface(void); -static void set_capabilities(const enum libdecor_capabilities new_capabilities); - static void do_map(void); //#include "plugins/gtk/libdecor-gtk.c" @@ -329,6 +331,8 @@ static void init_wl_output( uint32_t id, uint32_t version); static void output_removed(struct output *output); +static void draw_header_button(cairo_t *cr, cairo_surface_t *surface, enum header_element button_type); + static const char *libdecor_gtk_proxy_tag = "libdecor-gtk"; static int libdecor_plugin_gtk_dispatch(int timeout); @@ -337,7 +341,7 @@ static void libdecor_plugin_gtk_frame_free(void); static void libdecor_plugin_gtk_frame_commit(struct libdecor_state *state, struct libdecor_configuration *configuration); static void libdecor_plugin_gtk_frame_popup_grab(const char *seat_name); static void libdecor_plugin_gtk_frame_popup_ungrab(const char *seat_name); -static bool libdecor_plugin_gtk_frame_get_border_size(struct libdecor_configuration *configuration, int *left, int *right, int *top, int *bottom); +static void libdecor_plugin_gtk_frame_get_border_size(enum libdecor_window_state window_state, int *left, int *right, int *top, int *bottom); static void draw_decoration(void); @@ -359,7 +363,6 @@ typedef struct Ctx{ struct zxdg_decoration_manager_v1 *decoration_manager; struct wl_callback *wl_callback; - struct wl_list visible_frame_list; struct wl_list seat_list; struct wl_list output_list; @@ -389,7 +392,6 @@ typedef struct Ctx{ struct libdecor_configuration cached_config; //struct libdecor_frame_private; - char *app_id; char *title; struct libdecor_limits content_limits; struct xdg_toplevel *parent; @@ -423,7 +425,6 @@ typedef struct Ctx{ struct border_component *active; struct border_component *touch_active; - struct border_component *focus; struct border_component *grab;