From f1ada7e40744d6f1f28c908d01ff0a68c7688665 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Wed, 8 Jun 2022 14:37:30 +0200 Subject: [PATCH] src/ssd: Use LAB_SSD_PART_CORNER_x for rounded corner backgrounds This matches the behavior of the surrounding borders and will usually cause resizing instead of triggering the button itself. This effect is only really visible when using a border width settings of > 1. Fixes #379 --- include/node.h | 1 + include/ssd.h | 7 +-- src/desktop.c | 5 ++ src/node.c | 3 +- src/ssd/ssd_part.c | 106 ++++++++++++++++++++--------------------- src/ssd/ssd_titlebar.c | 17 +++---- 6 files changed, 74 insertions(+), 65 deletions(-) diff --git a/include/node.h b/include/node.h index 07e6aff4..e8d6535b 100644 --- a/include/node.h +++ b/include/node.h @@ -16,6 +16,7 @@ enum node_descriptor_type { LAB_NODE_DESC_LAYER_POPUP, LAB_NODE_DESC_MENUITEM, LAB_NODE_DESC_TREE, + LAB_NODE_DESC_SSD_BUTTON, }; struct node_descriptor { diff --git a/include/ssd.h b/include/ssd.h index 69b82c99..0f9ff624 100644 --- a/include/ssd.h +++ b/include/ssd.h @@ -158,11 +158,12 @@ struct ssd_part *add_scene_buffer( struct ssd_part *add_scene_button( struct wl_list *part_list, enum ssd_part_type type, struct wlr_scene_tree *parent, float *bg_color, - struct wlr_buffer *icon_buffer, int x); + struct wlr_buffer *icon_buffer, int x, struct view *view); struct ssd_part *add_scene_button_corner( struct wl_list *part_list, enum ssd_part_type type, - struct wlr_scene_tree *parent, struct wlr_buffer *corner_buffer, - struct wlr_buffer *icon_buffer, int x); + enum ssd_part_type corner_type, struct wlr_scene_tree *parent, + struct wlr_buffer *corner_buffer, struct wlr_buffer *icon_buffer, + int x, struct view *view); /* SSD internal helpers */ struct ssd_part *ssd_get_part( diff --git a/src/desktop.c b/src/desktop.c index 3ad77207..30f38264 100644 --- a/src/desktop.c +++ b/src/desktop.c @@ -294,6 +294,11 @@ desktop_node_and_view_at(struct server *server, double lx, double ly, if (desc->type == LAB_NODE_DESC_XDG_POPUP) { goto has_view_data; } + if (desc->type == LAB_NODE_DESC_SSD_BUTTON) { + /* Always return the top scene node for SSD buttons */ + *scene_node = node; + goto has_view_data; + } if (desc->type == LAB_NODE_DESC_LAYER_SURFACE) { /* FIXME: we shouldn't have to set *view_area */ *view_area = LAB_SSD_CLIENT; diff --git a/src/node.c b/src/node.c index f667d82a..6386fc81 100644 --- a/src/node.c +++ b/src/node.c @@ -43,7 +43,8 @@ node_view_from_node(struct wlr_scene_node *wlr_scene_node) assert(wlr_scene_node->data); struct node_descriptor *node_descriptor = wlr_scene_node->data; assert(node_descriptor->type == LAB_NODE_DESC_VIEW - || node_descriptor->type == LAB_NODE_DESC_XDG_POPUP); + || node_descriptor->type == LAB_NODE_DESC_XDG_POPUP + || node_descriptor->type == LAB_NODE_DESC_SSD_BUTTON); return (struct view *)node_descriptor->data; } diff --git a/src/ssd/ssd_part.c b/src/ssd/ssd_part.c index ddd09014..95c3ab70 100644 --- a/src/ssd/ssd_part.c +++ b/src/ssd/ssd_part.c @@ -3,6 +3,7 @@ #include #include "labwc.h" #include "ssd.h" +#include "node.h" struct ssd_part * add_scene_part(struct wl_list *part_list, enum ssd_part_type type) @@ -45,70 +46,69 @@ add_scene_buffer(struct wl_list *list, enum ssd_part_type type, return part; } -static void -finish_scene_button(struct wl_list *part_list, enum ssd_part_type type, - struct wlr_scene_tree *parent, struct wlr_buffer *icon_buffer) +struct ssd_part * +add_scene_button_corner(struct wl_list *part_list, enum ssd_part_type type, + enum ssd_part_type corner_type, struct wlr_scene_tree *parent, + struct wlr_buffer *corner_buffer, struct wlr_buffer *icon_buffer, + int x, struct view *view) { + int offset_x; + float invisible[4] = { 0, 0, 0, 0 }; + + if (corner_type == LAB_SSD_PART_CORNER_TOP_LEFT) { + offset_x = rc.theme->border_width; + } else if (corner_type == LAB_SSD_PART_CORNER_TOP_RIGHT) { + offset_x = 0; + } else { + assert(false && "invalid corner button type"); + } + + struct ssd_part *button_root = add_scene_part(part_list, corner_type); + parent = wlr_scene_tree_create(parent); + button_root->node = &parent->node; + wlr_scene_node_set_position(button_root->node, x, 0); + + /* + * Background, x and y adjusted for border_width which is + * already included in rendered theme.c / corner_buffer + */ + add_scene_buffer(part_list, corner_type, parent, corner_buffer, + -offset_x, -rc.theme->border_width); + + /* Finally just put a usual theme button on top, using an invisible hitbox */ + add_scene_button(part_list, type, parent, invisible, icon_buffer, 0, view); + return button_root; +} + +struct ssd_part * +add_scene_button(struct wl_list *part_list, enum ssd_part_type type, + struct wlr_scene_tree *parent, float *bg_color, + struct wlr_buffer *icon_buffer, int x, struct view *view) +{ + struct ssd_part *part; float hover_bg[4] = {0.15f, 0.15f, 0.15f, 0.3f}; + struct ssd_part *button_root = add_scene_part(part_list, type); + parent = wlr_scene_tree_create(parent); + button_root->node = &parent->node; + wlr_scene_node_set_position(button_root->node, x, 0); + node_descriptor_create(button_root->node, LAB_NODE_DESC_SSD_BUTTON, view); + + /* Background */ + part = add_scene_rect(part_list, type, parent, + BUTTON_WIDTH, rc.theme->title_height, 0, 0, bg_color); + /* Icon */ add_scene_buffer(part_list, type, parent, icon_buffer, (BUTTON_WIDTH - icon_buffer->width) / 2, (rc.theme->title_height - icon_buffer->height) / 2); /* Hover overlay */ - struct ssd_part *hover_part; - hover_part = add_scene_rect(part_list, type, parent, BUTTON_WIDTH, + part = add_scene_rect(part_list, type, parent, BUTTON_WIDTH, rc.theme->title_height, 0, 0, hover_bg); - wlr_scene_node_set_enabled(hover_part->node, false); -} + wlr_scene_node_set_enabled(part->node, false); -struct ssd_part * -add_scene_button_corner(struct wl_list *part_list, enum ssd_part_type type, - struct wlr_scene_tree *parent, struct wlr_buffer *corner_buffer, - struct wlr_buffer *icon_buffer, int x) -{ - struct ssd_part *button_root = add_scene_part(part_list, type); - parent = wlr_scene_tree_create(parent); - button_root->node = &parent->node; - wlr_scene_node_set_position(button_root->node, x, 0); - - int offset_x; - if (type == LAB_SSD_BUTTON_WINDOW_MENU) { - offset_x = rc.theme->border_width; - } else if (type == LAB_SSD_BUTTON_CLOSE) { - offset_x = 0; - } else { - assert(false && "invalid corner button type"); - } - - struct ssd_part *part; - /* - * Background, y adjusted for border_width which is - * already included in rendered theme.c / corner_buffer - */ - part = add_scene_buffer(part_list, type, parent, corner_buffer, - -offset_x, -rc.theme->border_width); - finish_scene_button(part_list, type, parent, icon_buffer); - return part; -} - -struct ssd_part * -add_scene_button(struct wl_list *part_list, enum ssd_part_type type, - struct wlr_scene_tree *parent, float *bg_color, - struct wlr_buffer *icon_buffer, int x) -{ - struct ssd_part *button_root = add_scene_part(part_list, type); - parent = wlr_scene_tree_create(parent); - button_root->node = &parent->node; - wlr_scene_node_set_position(button_root->node, x, 0); - - struct ssd_part *part; - /* Background */ - part = add_scene_rect(part_list, type, parent, - BUTTON_WIDTH, rc.theme->title_height, 0, 0, bg_color); - finish_scene_button(part_list, type, parent, icon_buffer); - return part; + return button_root; } struct ssd_part * diff --git a/src/ssd/ssd_titlebar.c b/src/ssd/ssd_titlebar.c index 80aed120..6c27943f 100644 --- a/src/ssd/ssd_titlebar.c +++ b/src/ssd/ssd_titlebar.c @@ -46,18 +46,19 @@ ssd_titlebar_create(struct view *view) width - BUTTON_WIDTH * BUTTON_COUNT, theme->title_height, BUTTON_WIDTH, 0, color); /* Buttons */ - add_scene_button_corner(&subtree->parts, LAB_SSD_BUTTON_WINDOW_MENU, - parent, corner_top_left, - &theme->xbm_menu_active_unpressed->base, 0); + add_scene_button_corner(&subtree->parts, + LAB_SSD_BUTTON_WINDOW_MENU, LAB_SSD_PART_CORNER_TOP_LEFT, parent, + corner_top_left, &theme->xbm_menu_active_unpressed->base, 0, view); add_scene_button(&subtree->parts, LAB_SSD_BUTTON_ICONIFY, parent, color, &theme->xbm_iconify_active_unpressed->base, - width - BUTTON_WIDTH * 3); + width - BUTTON_WIDTH * 3, view); add_scene_button(&subtree->parts, LAB_SSD_BUTTON_MAXIMIZE, parent, color, &theme->xbm_maximize_active_unpressed->base, - width - BUTTON_WIDTH * 2); - add_scene_button_corner(&subtree->parts, LAB_SSD_BUTTON_CLOSE, parent, + width - BUTTON_WIDTH * 2, view); + add_scene_button_corner(&subtree->parts, + LAB_SSD_BUTTON_CLOSE, LAB_SSD_PART_CORNER_TOP_RIGHT, parent, corner_top_right, &theme->xbm_close_active_unpressed->base, - width - BUTTON_WIDTH * 1); + width - BUTTON_WIDTH * 1, view); } FOR_EACH_END ssd_update_title(view); } @@ -100,7 +101,7 @@ ssd_titlebar_update(struct view *view) width - BUTTON_WIDTH * 2, 0); } continue; - case LAB_SSD_BUTTON_CLOSE: + case LAB_SSD_PART_CORNER_TOP_RIGHT: if (is_direct_child(part->node, subtree)) { wlr_scene_node_set_position(part->node, width - BUTTON_WIDTH * 1, 0);