ssd: apply title layout

This commit is contained in:
Tobias Bengfort 2024-08-18 10:49:18 +02:00
parent 9a252249c9
commit 39ff873d5b
7 changed files with 140 additions and 78 deletions

View file

@ -5,7 +5,6 @@
#include <wayland-server-core.h> #include <wayland-server-core.h>
#include "common/border.h" #include "common/border.h"
#define SSD_BUTTON_COUNT 4
#define SSD_EXTENDED_AREA 8 #define SSD_EXTENDED_AREA 8
/* /*

View file

@ -220,7 +220,8 @@ snap_shrink_to_next_edge(struct view *view,
*geo = view->pending; *geo = view->pending;
uint32_t resize_edges; uint32_t resize_edges;
int min_view_width = rc.theme->window_button_width * SSD_BUTTON_COUNT; int min_view_width = rc.theme->window_button_width * (
wl_list_length(&rc.title_buttons_left) + wl_list_length(&rc.title_buttons_right));
/* /*
* First shrink the view along the relevant edge. The maximum shrink * First shrink the view along the relevant edge. The maximum shrink

View file

@ -99,24 +99,82 @@ ssd_titlebar_create(struct ssd *ssd)
-rc.theme->border_width); -rc.theme->border_width);
/* Buttons */ /* Buttons */
add_scene_button(&subtree->parts, LAB_SSD_BUTTON_WINDOW_MENU, parent, int x = 0;
menu_button_unpressed, menu_button_hover, 0, view); struct ssd_part *btn_max_root;
add_scene_button(&subtree->parts, LAB_SSD_BUTTON_ICONIFY, parent, struct ssd_button *btn_max;
iconify_button_unpressed, iconify_button_hover, struct title_button *b;
width - theme->window_button_width * 3, view); wl_list_for_each(b, &rc.title_buttons_left, link) {
switch (b->type) {
case LAB_SSD_BUTTON_WINDOW_MENU:
add_scene_button(&subtree->parts, LAB_SSD_BUTTON_WINDOW_MENU,
parent, menu_button_unpressed, menu_button_hover, x,
view);
x += theme->window_button_width;
continue;
case LAB_SSD_BUTTON_ICONIFY:
add_scene_button(&subtree->parts, LAB_SSD_BUTTON_ICONIFY, parent,
iconify_button_unpressed, iconify_button_hover, x,
view);
x += theme->window_button_width;
continue;
case LAB_SSD_BUTTON_MAXIMIZE:
/* Maximize button has an alternate state when maximized */
btn_max_root = add_scene_button(
&subtree->parts, LAB_SSD_BUTTON_MAXIMIZE, parent,
maximize_button_unpressed, maximize_button_hover, x, view);
btn_max = node_ssd_button_from_node(btn_max_root->node);
add_toggled_icon(btn_max, &subtree->parts, LAB_SSD_BUTTON_MAXIMIZE,
restore_button_unpressed, restore_button_hover);
x += theme->window_button_width;
continue;
case LAB_SSD_BUTTON_CLOSE:
add_scene_button(&subtree->parts, LAB_SSD_BUTTON_CLOSE, parent,
close_button_unpressed, close_button_hover, x, view);
x += theme->window_button_width;
continue;
default:
assert(false && "invalid titlebar part");
wlr_log(WLR_ERROR, "invalid titlebar type");
abort();
}
}
/* Maximize button has an alternate state when maximized */ x = width - theme->window_button_width;
struct ssd_part *btn_max_root = add_scene_button( wl_list_for_each_reverse(b, &rc.title_buttons_right, link) {
&subtree->parts, LAB_SSD_BUTTON_MAXIMIZE, parent, switch (b->type) {
maximize_button_unpressed, maximize_button_hover, case LAB_SSD_BUTTON_WINDOW_MENU:
width - theme->window_button_width * 2, view); add_scene_button(&subtree->parts, LAB_SSD_BUTTON_WINDOW_MENU,
struct ssd_button *btn_max = node_ssd_button_from_node(btn_max_root->node); parent, menu_button_unpressed, menu_button_hover, x,
add_toggled_icon(btn_max, &subtree->parts, LAB_SSD_BUTTON_MAXIMIZE, view);
restore_button_unpressed, restore_button_hover); x -= theme->window_button_width;
continue;
add_scene_button(&subtree->parts, LAB_SSD_BUTTON_CLOSE, parent, case LAB_SSD_BUTTON_ICONIFY:
close_button_unpressed, close_button_hover, add_scene_button(&subtree->parts, LAB_SSD_BUTTON_ICONIFY, parent,
width - theme->window_button_width * 1, view); iconify_button_unpressed, iconify_button_hover, x,
view);
x -= theme->window_button_width;
continue;
case LAB_SSD_BUTTON_MAXIMIZE:
/* Maximize button has an alternate state when maximized */
btn_max_root = add_scene_button(
&subtree->parts, LAB_SSD_BUTTON_MAXIMIZE, parent,
maximize_button_unpressed, maximize_button_hover, x, view);
btn_max = node_ssd_button_from_node(btn_max_root->node);
add_toggled_icon(btn_max, &subtree->parts, LAB_SSD_BUTTON_MAXIMIZE,
restore_button_unpressed, restore_button_hover);
x -= theme->window_button_width;
continue;
case LAB_SSD_BUTTON_CLOSE:
add_scene_button(&subtree->parts, LAB_SSD_BUTTON_CLOSE, parent,
close_button_unpressed, close_button_hover, x, view);
x -= theme->window_button_width;
continue;
default:
assert(false && "invalid titlebar part");
wlr_log(WLR_ERROR, "invalid titlebar type");
abort();
}
}
} FOR_EACH_END } FOR_EACH_END
ssd_update_title(ssd); ssd_update_title(ssd);
@ -133,12 +191,6 @@ ssd_titlebar_create(struct ssd *ssd)
} }
} }
static bool
is_direct_child(struct wlr_scene_node *node, struct ssd_sub_tree *subtree)
{
return node->parent == subtree->tree;
}
static void static void
set_squared_corners(struct ssd *ssd, bool enable) set_squared_corners(struct ssd *ssd, bool enable)
{ {
@ -173,6 +225,10 @@ set_maximize_alt_icon(struct ssd *ssd, bool enable)
FOR_EACH_STATE(ssd, subtree) { FOR_EACH_STATE(ssd, subtree) {
part = ssd_get_part(&subtree->parts, LAB_SSD_BUTTON_MAXIMIZE); part = ssd_get_part(&subtree->parts, LAB_SSD_BUTTON_MAXIMIZE);
if (!part) {
return;
}
button = node_ssd_button_from_node(part->node); button = node_ssd_button_from_node(part->node);
if (button->toggled) { if (button->toggled) {
@ -212,45 +268,31 @@ ssd_titlebar_update(struct ssd *ssd)
return; return;
} }
int x;
struct ssd_part *part; struct ssd_part *part;
struct ssd_sub_tree *subtree; struct ssd_sub_tree *subtree;
struct title_button *b;
int bg_offset = maximized || tiled_not_maximized ? 0 : theme->window_button_width; int bg_offset = maximized || tiled_not_maximized ? 0 : theme->window_button_width;
FOR_EACH_STATE(ssd, subtree) { FOR_EACH_STATE(ssd, subtree) {
wl_list_for_each(part, &subtree->parts, link) { part = ssd_get_part(&subtree->parts, LAB_SSD_PART_TITLEBAR);
switch (part->type) { wlr_scene_rect_set_size(
case LAB_SSD_PART_TITLEBAR: wlr_scene_rect_from_node(part->node),
wlr_scene_rect_set_size( width - bg_offset * 2, theme->title_height);
wlr_scene_rect_from_node(part->node),
width - bg_offset * 2, theme->title_height); x = 0;
continue; wl_list_for_each(b, &rc.title_buttons_left, link) {
case LAB_SSD_BUTTON_ICONIFY: part = ssd_get_part(&subtree->parts, b->type);
if (is_direct_child(part->node, subtree)) { wlr_scene_node_set_position(part->node, x, 0);
wlr_scene_node_set_position(part->node, x += theme->window_button_width;
width - theme->window_button_width * 3, 0); }
}
continue; x = width - theme->window_button_width;
case LAB_SSD_BUTTON_MAXIMIZE: part = ssd_get_part(&subtree->parts, LAB_SSD_PART_CORNER_TOP_RIGHT);
if (is_direct_child(part->node, subtree)) { wlr_scene_node_set_position(part->node, x, -rc.theme->border_width);
wlr_scene_node_set_position(part->node, wl_list_for_each_reverse(b, &rc.title_buttons_right, link) {
width - theme->window_button_width * 2, 0); part = ssd_get_part(&subtree->parts, b->type);
} wlr_scene_node_set_position(part->node, x, 0);
continue; x -= theme->window_button_width;
case LAB_SSD_BUTTON_CLOSE:
if (is_direct_child(part->node, subtree)) {
wlr_scene_node_set_position(part->node,
width - theme->window_button_width * 1, 0);
}
continue;
case LAB_SSD_PART_CORNER_TOP_RIGHT:
if (is_direct_child(part->node, subtree)) {
wlr_scene_node_set_position(part->node,
width - theme->window_button_width * 1,
-rc.theme->border_width);
}
continue;
default:
continue;
}
} }
} FOR_EACH_END } FOR_EACH_END
ssd_update_title(ssd); ssd_update_title(ssd);
@ -297,7 +339,9 @@ ssd_update_title_positions(struct ssd *ssd)
struct view *view = ssd->view; struct view *view = ssd->view;
struct theme *theme = view->server->theme; struct theme *theme = view->server->theme;
int width = view->current.width; int width = view->current.width;
int title_bg_width = width - theme->window_button_width * SSD_BUTTON_COUNT; int offset_left = theme->window_button_width * wl_list_length(&rc.title_buttons_left);
int offset_right = theme->window_button_width * wl_list_length(&rc.title_buttons_right);
int title_bg_width = width - offset_left - offset_right;
int x, y; int x, y;
int buffer_height, buffer_width; int buffer_height, buffer_width;
@ -313,7 +357,7 @@ ssd_update_title_positions(struct ssd *ssd)
buffer_width = part->buffer ? part->buffer->width : 0; buffer_width = part->buffer ? part->buffer->width : 0;
buffer_height = part->buffer ? part->buffer->height : 0; buffer_height = part->buffer ? part->buffer->height : 0;
x = theme->window_button_width; x = offset_left;
y = (theme->title_height - buffer_height) / 2; y = (theme->title_height - buffer_height) / 2;
if (title_bg_width <= 0) { if (title_bg_width <= 0) {
@ -323,7 +367,7 @@ ssd_update_title_positions(struct ssd *ssd)
wlr_scene_node_set_enabled(part->node, true); wlr_scene_node_set_enabled(part->node, true);
if (theme->window_label_text_justify == LAB_JUSTIFY_CENTER) { if (theme->window_label_text_justify == LAB_JUSTIFY_CENTER) {
if (buffer_width + theme->window_button_width * 2 <= title_bg_width) { if (buffer_width + MAX(offset_left, offset_right) * 2 <= width) {
/* Center based on the full width */ /* Center based on the full width */
x = (width - buffer_width) / 2; x = (width - buffer_width) / 2;
} else { } else {
@ -346,7 +390,7 @@ ssd_update_title_positions(struct ssd *ssd)
void void
ssd_update_title(struct ssd *ssd) ssd_update_title(struct ssd *ssd)
{ {
if (!ssd) { if (!ssd || !rc.show_title) {
return; return;
} }
@ -366,8 +410,9 @@ ssd_update_title(struct ssd *ssd)
struct ssd_part *part; struct ssd_part *part;
struct ssd_sub_tree *subtree; struct ssd_sub_tree *subtree;
struct ssd_state_title_width *dstate; struct ssd_state_title_width *dstate;
int title_bg_width = view->current.width int offset_left = theme->window_button_width * wl_list_length(&rc.title_buttons_left);
- theme->window_button_width * SSD_BUTTON_COUNT; int offset_right = theme->window_button_width * wl_list_length(&rc.title_buttons_right);
int title_bg_width = view->current.width - offset_left - offset_right;
FOR_EACH_STATE(ssd, subtree) { FOR_EACH_STATE(ssd, subtree) {
if (subtree == &ssd->titlebar.active) { if (subtree == &ssd->titlebar.active) {

View file

@ -233,14 +233,17 @@ ssd_update_geometry(struct ssd *ssd)
struct wlr_box cached = ssd->state.geometry; struct wlr_box cached = ssd->state.geometry;
struct wlr_box current = ssd->view->current; struct wlr_box current = ssd->view->current;
int min_view_width = rc.theme->window_button_width * SSD_BUTTON_COUNT; int min_view_width = rc.theme->window_button_width * (
wl_list_length(&rc.title_buttons_left) + wl_list_length(&rc.title_buttons_right));
int eff_width = current.width; int eff_width = current.width;
int eff_height = view_effective_height(ssd->view, /* use_pending */ false); int eff_height = view_effective_height(ssd->view, /* use_pending */ false);
if (eff_width > 0 && eff_width < min_view_width) { if (eff_width > 0 && eff_width < min_view_width) {
/* /*
* Prevent negative values in calculations like * Prevent negative values in calculations like
* `width - SSD_BUTTON_WIDTH * SSD_BUTTON_COUNT` * `width - theme->window_button_width
* * (wl_list_length(&rc.title_buttons_left)
* + wl_list_length(&rc.title_buttons_right))`
*/ */
wlr_log(WLR_ERROR, wlr_log(WLR_ERROR,
"view width is smaller than its minimal value"); "view width is smaller than its minimal value");

View file

@ -84,14 +84,26 @@ corner_from_icon_name(const char *icon_name)
{ {
assert(icon_name); assert(icon_name);
/* struct title_button *b;
* TODO: Once we implement titleLayout we can make the wl_list_for_each(b, &rc.title_buttons_left, link) {
* return values depend on parsed config values. if ((b->type == LAB_SSD_BUTTON_WINDOW_MENU && !strcmp(icon_name, "menu"))
*/ || (b->type == LAB_SSD_BUTTON_ICONIFY && !strcmp(icon_name, "iconify"))
if (!strcmp(icon_name, "menu")) { || (b->type == LAB_SSD_BUTTON_MAXIMIZE && !strcmp(icon_name, "max"))
return LAB_CORNER_TOP_LEFT; || (b->type == LAB_SSD_BUTTON_MAXIMIZE && !strcmp(icon_name, "max_toggled"))
} else if (!strcmp(icon_name, "close")) { || (b->type == LAB_SSD_BUTTON_CLOSE && !strcmp(icon_name, "close"))) {
return LAB_CORNER_TOP_RIGHT; return LAB_CORNER_TOP_LEFT;
}
break;
}
wl_list_for_each_reverse(b, &rc.title_buttons_right, link) {
if ((b->type == LAB_SSD_BUTTON_WINDOW_MENU && !strcmp(icon_name, "menu"))
|| (b->type == LAB_SSD_BUTTON_ICONIFY && !strcmp(icon_name, "iconify"))
|| (b->type == LAB_SSD_BUTTON_MAXIMIZE && !strcmp(icon_name, "max"))
|| (b->type == LAB_SSD_BUTTON_MAXIMIZE && !strcmp(icon_name, "max_toggled"))
|| (b->type == LAB_SSD_BUTTON_CLOSE && !strcmp(icon_name, "close"))) {
return LAB_CORNER_TOP_RIGHT;
}
break;
} }
return LAB_CORNER_UNKNOWN; return LAB_CORNER_UNKNOWN;
} }

View file

@ -617,7 +617,8 @@ view_adjust_size(struct view *view, int *w, int *h)
{ {
assert(view); assert(view);
struct view_size_hints hints = view_get_size_hints(view); struct view_size_hints hints = view_get_size_hints(view);
int min_view_width = rc.theme->window_button_width * SSD_BUTTON_COUNT; int min_view_width = rc.theme->window_button_width * (
wl_list_length(&rc.title_buttons_left) + wl_list_length(&rc.title_buttons_right));
/* /*
* "If a base size is not provided, the minimum size is to be * "If a base size is not provided, the minimum size is to be

View file

@ -622,7 +622,8 @@ check_natural_geometry(struct view *view)
* un-maximized size when started maximized. Try to detect this * un-maximized size when started maximized. Try to detect this
* and set a fallback size. * and set a fallback size.
*/ */
int min_view_width = rc.theme->window_button_width * SSD_BUTTON_COUNT; int min_view_width = rc.theme->window_button_width * (
wl_list_length(&rc.title_buttons_left) + wl_list_length(&rc.title_buttons_right));
if (!view_is_floating(view) if (!view_is_floating(view)
&& (view->natural_geometry.width < min_view_width && (view->natural_geometry.width < min_view_width
|| view->natural_geometry.height < LAB_MIN_VIEW_HEIGHT)) { || view->natural_geometry.height < LAB_MIN_VIEW_HEIGHT)) {