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
This commit is contained in:
Consolatis 2022-06-08 14:37:30 +02:00 committed by Johan Malm
parent 32dac72734
commit f1ada7e407
6 changed files with 74 additions and 65 deletions

View file

@ -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 {

View file

@ -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(

View file

@ -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;

View file

@ -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;
}

View file

@ -3,6 +3,7 @@
#include <assert.h>
#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 *

View file

@ -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);