mirror of
https://github.com/labwc/labwc.git
synced 2025-11-02 09:01:47 -05:00
ssd: apply title layout
This commit is contained in:
parent
9a252249c9
commit
39ff873d5b
7 changed files with 140 additions and 78 deletions
|
|
@ -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
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
|
|
|
||||||
28
src/theme.c
28
src/theme.c
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue