Merge pull request #2189 from johanmalm/window-button-height

Titlebar related breaking changes
This commit is contained in:
Johan Malm 2024-10-09 07:04:09 +01:00 committed by GitHub
commit 1f1ac27bf5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 87 additions and 71 deletions

View file

@ -50,20 +50,14 @@ labwc-config(5).
Line width (integer) of border drawn around window frames.
Default is 1.
*padding.width*
Horizontal padding size, in pixels, between border and first
*window.titlebar.padding.width*
Horizontal titlebar padding size, in pixels, between border and first
button on the left/right.
Default is 0.
*padding.height*
Vertical padding size, in pixels, used for spacing out elements
in the window decorations.
Default is 3.
*titlebar.height*
Window title bar height.
Default equals the vertical font extents of the title plus 2x
padding.height.
*window.titlebar.padding.height*
Vertical titlebar padding size, in pixels.
Default is 0.
*menu.items.padding.x*
Horizontal padding of menu text entries in pixels.

View file

@ -7,12 +7,13 @@
# general
border.width: 1
padding.width: 0
padding.height: 3
# The following options has no default, but fallbacks back to
# font-height + 2x padding.height if not set.
# titlebar.height:
#
# We do not support the global padding.{width,height} of openbox because
# the default labwc button geometry has deviates from that of openbox
#
window.titlebar.padding.width: 0
window.titlebar.padding.height: 0
# window border
window.active.border.color: #e1dedb

View file

@ -146,7 +146,7 @@ struct ssd_part *add_scene_buffer(
struct wlr_scene_tree *parent, struct wlr_buffer *buffer, int x, int y);
struct ssd_part *add_scene_button(struct wl_list *part_list,
enum ssd_part_type type, struct wlr_scene_tree *parent,
struct lab_data_buffer *buffers[LAB_BS_ALL + 1], int x,
struct lab_data_buffer *buffers[LAB_BS_ALL + 1], int x, int y,
struct view *view);
void update_window_icon_buffer(struct wlr_scene_node *button_node,
struct lab_data_buffer *buffer);

View file

@ -46,8 +46,8 @@ struct theme {
* the space between title bar border and
* buttons on the left/right/top
*/
int padding_width;
int padding_height;
int window_titlebar_padding_width;
int window_titlebar_padding_height;
int title_height;
int menu_overlap_x;
@ -67,10 +67,11 @@ struct theme {
enum lab_justification window_label_text_justify;
enum lab_justification menu_title_text_justify;
/* button width */
/* buttons */
int window_button_width;
/* the space between buttons */
int window_button_height;
int window_button_spacing;
/* the shape of the hover effect */
enum lab_shape window_button_hover_bg_shape;
@ -155,7 +156,10 @@ struct theme {
struct lab_data_buffer *shadow_corner_bottom_inactive;
struct lab_data_buffer *shadow_edge_inactive;
/* not set in rc.xml/themerc, but derived from font & padding_height */
/*
* Not set in rc.xml/themerc, but derived from the tallest titlebar
* object plus 2 * window_titlebar_padding_height
*/
int osd_window_switcher_item_height;
/* magnifier */

View file

@ -97,7 +97,7 @@ update_window_icon_buffer(struct wlr_scene_node *button_node,
struct wlr_box icon_geo = get_scale_box(buffer,
rc.theme->window_button_width,
rc.theme->title_height);
rc.theme->window_button_height);
wlr_scene_buffer_set_buffer(scene_buffer, &buffer->base);
wlr_scene_buffer_set_dest_size(scene_buffer,
@ -109,17 +109,17 @@ struct ssd_part *
add_scene_button(struct wl_list *part_list, enum ssd_part_type type,
struct wlr_scene_tree *parent,
struct lab_data_buffer *buffers[LAB_BS_ALL + 1],
int x, struct view *view)
int x, int y, struct view *view)
{
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);
wlr_scene_node_set_position(button_root->node, x, y);
/* Hitbox */
float invisible[4] = { 0, 0, 0, 0 };
add_scene_rect(part_list, type, parent,
rc.theme->window_button_width, rc.theme->title_height, 0, 0,
rc.theme->window_button_width, rc.theme->window_button_height, 0, 0,
invisible);
/* Icons */
@ -130,7 +130,7 @@ add_scene_button(struct wl_list *part_list, enum ssd_part_type type,
}
struct lab_data_buffer *icon_buffer = buffers[state_set];
struct wlr_box icon_geo = get_scale_box(icon_buffer,
rc.theme->window_button_width, rc.theme->title_height);
rc.theme->window_button_width, rc.theme->window_button_height);
struct ssd_part *icon_part = add_scene_buffer(part_list, type,
parent, &icon_buffer->base, icon_geo.x, icon_geo.y);
/* Make sure big icons are scaled down if necessary */

View file

@ -74,22 +74,26 @@ ssd_titlebar_create(struct ssd *ssd)
/* Buttons */
struct title_button *b;
int x = theme->padding_width;
int x = theme->window_titlebar_padding_width;
/* Center vertically within titlebar */
int y = (theme->title_height - theme->window_button_height) / 2;
wl_list_for_each(b, &rc.title_buttons_left, link) {
struct lab_data_buffer **buffers =
theme->window[active].buttons[b->type];
add_scene_button(&subtree->parts, b->type, parent,
buffers, x, view);
buffers, x, y, view);
x += theme->window_button_width + theme->window_button_spacing;
}
x = width - theme->padding_width + theme->window_button_spacing;
x = width - theme->window_titlebar_padding_width + theme->window_button_spacing;
wl_list_for_each_reverse(b, &rc.title_buttons_right, link) {
x -= theme->window_button_width + theme->window_button_spacing;
struct lab_data_buffer **buffers =
theme->window[active].buttons[b->type];
add_scene_button(&subtree->parts, b->type, parent,
buffers, x, view);
buffers, x, y, view);
}
} FOR_EACH_END
@ -207,7 +211,7 @@ static void
update_visible_buttons(struct ssd *ssd)
{
struct view *view = ssd->view;
int width = view->current.width - (2 * view->server->theme->padding_width);
int width = view->current.width - (2 * view->server->theme->window_titlebar_padding_width);
int button_width = view->server->theme->window_button_width;
int button_spacing = view->server->theme->window_button_spacing;
int button_count_left = wl_list_length(&rc.title_buttons_left);
@ -293,6 +297,8 @@ ssd_titlebar_update(struct ssd *ssd)
update_visible_buttons(ssd);
/* Center buttons vertically within titlebar */
int y = (theme->title_height - theme->window_button_height) / 2;
int x;
struct ssd_part *part;
struct ssd_sub_tree *subtree;
@ -304,10 +310,10 @@ ssd_titlebar_update(struct ssd *ssd)
wlr_scene_rect_from_node(part->node),
width - bg_offset * 2, theme->title_height);
x = theme->padding_width;
x = theme->window_titlebar_padding_width;
wl_list_for_each(b, &rc.title_buttons_left, link) {
part = ssd_get_part(&subtree->parts, b->type);
wlr_scene_node_set_position(part->node, x, 0);
wlr_scene_node_set_position(part->node, x, y);
x += theme->window_button_width + theme->window_button_spacing;
}
@ -315,11 +321,11 @@ ssd_titlebar_update(struct ssd *ssd)
part = ssd_get_part(&subtree->parts, LAB_SSD_PART_TITLEBAR_CORNER_RIGHT);
wlr_scene_node_set_position(part->node, x, -rc.theme->border_width);
x = width - theme->padding_width + theme->window_button_spacing;
x = width - theme->window_titlebar_padding_width + theme->window_button_spacing;
wl_list_for_each_reverse(b, &rc.title_buttons_right, link) {
part = ssd_get_part(&subtree->parts, b->type);
x -= theme->window_button_width + theme->window_button_spacing;
wlr_scene_node_set_position(part->node, x, 0);
wlr_scene_node_set_position(part->node, x, y);
}
} FOR_EACH_END
@ -426,7 +432,7 @@ get_title_offsets(struct ssd *ssd, int *offset_left, int *offset_right)
struct ssd_sub_tree *subtree = &ssd->titlebar.active;
int button_width = ssd->view->server->theme->window_button_width;
int button_spacing = ssd->view->server->theme->window_button_spacing;
int padding_width = ssd->view->server->theme->padding_width;
int padding_width = ssd->view->server->theme->window_titlebar_padding_width;
*offset_left = padding_width;
*offset_right = padding_width;
@ -603,7 +609,7 @@ ssd_update_window_icon(struct ssd *ssd)
*/
int hpad = theme->window_button_width / 10;
int icon_size = MIN(theme->window_button_width - 2 * hpad,
theme->title_height - 2 * theme->padding_height);
theme->window_button_height);
/*
* Load/render icons at the max scale of any usable output (at

View file

@ -91,7 +91,7 @@ copy_icon_buffer(struct theme *theme, struct lab_data_buffer *icon_buffer)
int icon_height = cairo_image_surface_get_height(icon.surface);
int width = theme->window_button_width;
int height = theme->title_height;
int height = theme->window_button_height;
/*
* Proportionately increase size of hover_buffer if the non-hover
@ -139,7 +139,7 @@ create_hover_fallback(struct theme *theme,
assert(!*hover_buffer);
int width = theme->window_button_width;
int height = theme->title_height;
int height = theme->window_button_height;
*hover_buffer = copy_icon_buffer(theme, icon_buffer);
cairo_t *cairo = (*hover_buffer)->cairo;
@ -171,17 +171,19 @@ create_rounded_buffer(struct theme *theme, enum corner corner,
cairo_t *cairo = (*rounded_buffer)->cairo;
int width = theme->window_button_width;
int height = theme->title_height;
int height = theme->window_button_height;
/*
* Round the hover overlay of corner buttons by
* cropping the region within the window border.
* Round the corner button by cropping the region within the window
* border. See the picture in #2189 for reference.
*/
int margin_x = theme->window_titlebar_padding_width;
int margin_y = (theme->title_height - theme->window_button_height) / 2;
float white[4] = {1, 1, 1, 1};
struct rounded_corner_ctx rounded_ctx = {
.box = &(struct wlr_box){
.width = theme->padding_width + width,
.height = height,
.width = margin_x + width,
.height = margin_y + height,
},
.radius = rc.corner_radius,
.line_width = theme->border_width,
@ -189,16 +191,11 @@ create_rounded_buffer(struct theme *theme, enum corner corner,
.border_color = white,
.corner = corner,
};
int mask_offset;
if (corner == LAB_CORNER_TOP_LEFT) {
mask_offset = -theme->padding_width;
} else {
mask_offset = 0;
}
struct lab_data_buffer *mask_buffer = rounded_rect(&rounded_ctx);
cairo_set_operator(cairo, CAIRO_OPERATOR_DEST_IN);
cairo_set_source_surface(cairo,
cairo_get_target(mask_buffer->cairo), mask_offset, 0);
cairo_set_source_surface(cairo, cairo_get_target(mask_buffer->cairo),
(corner == LAB_CORNER_TOP_LEFT) ? -margin_x : 0,
-margin_y);
cairo_paint(cairo);
cairo_surface_flush(cairo_get_target(cairo));
@ -246,7 +243,7 @@ load_button(struct theme *theme, struct button *b, int active)
zdrop(buffer);
int size = theme->title_height - 2 * theme->padding_height;
int size = theme->window_button_height;
float scale = 1; /* TODO: account for output scale */
/* PNG */
@ -573,7 +570,8 @@ static void
theme_builtin(struct theme *theme, struct server *server)
{
theme->border_width = 1;
theme->padding_height = 3;
theme->window_titlebar_padding_height = 0;
theme->window_titlebar_padding_width = 0;
theme->title_height = INT_MIN;
theme->menu_overlap_x = 0;
theme->menu_overlap_y = 0;
@ -591,8 +589,8 @@ theme_builtin(struct theme *theme, struct server *server)
theme->window_label_text_justify = parse_justification("Center");
theme->menu_title_text_justify = parse_justification("Center");
theme->padding_width = 0;
theme->window_button_width = 26;
theme->window_button_height = 26;
theme->window_button_spacing = 0;
theme->window_button_hover_bg_shape = LAB_RECTANGLE;
@ -706,17 +704,13 @@ entry(struct theme *theme, const char *key, const char *value)
theme->border_width = get_int_if_positive(
value, "border.width");
}
if (match_glob(key, "padding.width")) {
theme->padding_width = get_int_if_positive(
value, "padding.width");
if (match_glob(key, "window.titlebar.padding.width")) {
theme->window_titlebar_padding_width = get_int_if_positive(
value, "window.titlebar.padding.width");
}
if (match_glob(key, "padding.height")) {
theme->padding_height = get_int_if_positive(
value, "padding.height");
}
if (match_glob(key, "titlebar.height")) {
theme->title_height = get_int_if_positive(
value, "titlebar.height");
if (match_glob(key, "window.titlebar.padding.height")) {
theme->window_titlebar_padding_height = get_int_if_positive(
value, "window.titlebar.padding.height");
}
if (match_glob(key, "menu.items.padding.x")) {
theme->menu_item_padding_x = get_int_if_positive(
@ -779,6 +773,14 @@ entry(struct theme *theme, const char *key, const char *value)
theme->window_button_width = 1;
}
}
if (match_glob(key, "window.button.height")) {
theme->window_button_height = atoi(value);
if (theme->window_button_height < 1) {
wlr_log(WLR_ERROR, "window.button.height cannot "
"be less than 1, clamping it to 1.");
theme->window_button_height = 1;
}
}
if (match_glob(key, "window.button.spacing")) {
theme->window_button_spacing = get_int_if_positive(
value, "window.button.spacing");
@ -1461,13 +1463,22 @@ fill_colors_with_osd_theme(struct theme *theme, float colors[3][4])
memcpy(colors[2], theme->osd_bg_color, sizeof(colors[2]));
}
static int
get_titlebar_height(struct theme *theme)
{
int h = MAX(font_height(&rc.font_activewindow),
font_height(&rc.font_inactivewindow));
if (h < theme->window_button_height) {
h = theme->window_button_height;
}
h += 2 * theme->window_titlebar_padding_height;
return h;
}
static void
post_processing(struct theme *theme)
{
int h = MAX(font_height(&rc.font_activewindow), font_height(&rc.font_inactivewindow));
if (theme->title_height < h) {
theme->title_height = h + 2 * theme->padding_height;
}
theme->title_height = get_titlebar_height(theme);
theme->menu_item_height = font_height(&rc.font_menuitem)
+ 2 * theme->menu_item_padding_y;

View file

@ -2284,7 +2284,7 @@ view_get_min_width(void)
return (rc.theme->window_button_width * (button_count_left + button_count_right)) +
(rc.theme->window_button_spacing * MAX((button_count_right - 1), 0)) +
(rc.theme->window_button_spacing * MAX((button_count_left - 1), 0)) +
(2 * rc.theme->padding_width);
(2 * rc.theme->window_titlebar_padding_width);
}
void