mirror of
https://github.com/labwc/labwc.git
synced 2025-10-29 05:40:24 -04:00
Merge pull request #2088 from xi/titlelayout
theme: implement titleLayout
This commit is contained in:
commit
228a74ca48
13 changed files with 261 additions and 179 deletions
|
|
@ -432,6 +432,18 @@ extending outward from the snapped edge.
|
|||
*<theme><name>*
|
||||
The name of the Openbox theme to use. It is not set by default.
|
||||
|
||||
*<theme><titleLayout>*
|
||||
Selection and order of buttons in a window's titlebar.
|
||||
The following letters can be used, each only once:
|
||||
- L: window label (aka. title)
|
||||
- |: empty space (can be used instead of a title)
|
||||
- W: window menu
|
||||
- I: iconify
|
||||
- M: maximize
|
||||
- C: close
|
||||
|
||||
Example: WLIMC
|
||||
|
||||
*<theme><cornerRadius>*
|
||||
The radius of server side decoration top corners. Default is 8.
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
<!-- <font><theme> can be defined without an attribute to set all places -->
|
||||
<theme>
|
||||
<name></name>
|
||||
<titleLayout>WLIMC</titleLayout>
|
||||
<cornerRadius>8</cornerRadius>
|
||||
<keepBorder>yes</keepBorder>
|
||||
<dropShadows>no</dropShadows>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include "config/tablet-tool.h"
|
||||
#include "config/libinput.h"
|
||||
#include "resize-indicator.h"
|
||||
#include "ssd.h"
|
||||
#include "theme.h"
|
||||
|
||||
enum view_placement_policy {
|
||||
|
|
@ -45,6 +46,11 @@ enum tiling_events_mode {
|
|||
(LAB_TILING_EVENTS_REGION | LAB_TILING_EVENTS_EDGE),
|
||||
};
|
||||
|
||||
struct title_button {
|
||||
enum ssd_part_type type;
|
||||
struct wl_list link;
|
||||
};
|
||||
|
||||
struct usable_area_override {
|
||||
struct border margin;
|
||||
char *output;
|
||||
|
|
@ -75,7 +81,11 @@ struct rcxml {
|
|||
|
||||
/* theme */
|
||||
char *theme_name;
|
||||
struct wl_list title_buttons_left;
|
||||
struct wl_list title_buttons_right;
|
||||
int corner_radius;
|
||||
bool show_title;
|
||||
bool title_layout_loaded;
|
||||
bool ssd_keep_border;
|
||||
bool shadows_enabled;
|
||||
struct font font_activewindow;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ struct ssd_button {
|
|||
struct wlr_scene_node *hover;
|
||||
struct wlr_scene_node *toggled;
|
||||
struct wlr_scene_node *toggled_hover;
|
||||
struct wlr_scene_node *background;
|
||||
struct wlr_scene_tree *icon_tree;
|
||||
struct wlr_scene_tree *hover_tree;
|
||||
|
||||
|
|
@ -127,17 +126,11 @@ 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, float *bg_color,
|
||||
struct wlr_buffer *icon_buffer, struct wlr_buffer *hover_buffer,
|
||||
int x, struct view *view);
|
||||
struct wlr_scene_tree *parent, struct wlr_buffer *icon_buffer,
|
||||
struct wlr_buffer *hover_buffer, int x, struct view *view);
|
||||
void add_toggled_icon(struct ssd_button *button, struct wl_list *part_list,
|
||||
enum ssd_part_type type, struct wlr_buffer *icon_buffer,
|
||||
struct wlr_buffer *hover_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,
|
||||
struct wlr_buffer *hover_buffer, int x, struct view *view);
|
||||
|
||||
/* SSD internal helpers */
|
||||
struct ssd_part *ssd_get_part(
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
#include <wayland-server-core.h>
|
||||
#include "common/border.h"
|
||||
|
||||
#define SSD_BUTTON_COUNT 4
|
||||
#define SSD_EXTENDED_AREA 8
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -117,6 +117,59 @@ parse_window_type(const char *type)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fill_title_layout(char *nodename, char *content)
|
||||
{
|
||||
char *c, *c2;
|
||||
enum ssd_part_type type;
|
||||
struct title_button *item;
|
||||
struct wl_list *list = &rc.title_buttons_left;
|
||||
|
||||
for (c = content; *c != '\0'; c++) {
|
||||
for (c2 = content; c2 < c; c2++) {
|
||||
if (*c2 == *c) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (c2 != c) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (*c) {
|
||||
/* case 'N': icon */
|
||||
case 'L':
|
||||
list = &rc.title_buttons_right;
|
||||
rc.show_title = true;
|
||||
continue;
|
||||
case '|':
|
||||
list = &rc.title_buttons_right;
|
||||
continue;
|
||||
case 'W':
|
||||
type = LAB_SSD_BUTTON_WINDOW_MENU;
|
||||
break;
|
||||
case 'I':
|
||||
type = LAB_SSD_BUTTON_ICONIFY;
|
||||
break;
|
||||
case 'M':
|
||||
type = LAB_SSD_BUTTON_MAXIMIZE;
|
||||
break;
|
||||
case 'C':
|
||||
type = LAB_SSD_BUTTON_CLOSE;
|
||||
break;
|
||||
/* case 'S': shade */
|
||||
/* case 'D': omnipresent */
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
item = znew(*item);
|
||||
item->type = type;
|
||||
wl_list_append(list, &item->link);
|
||||
}
|
||||
|
||||
rc.title_layout_loaded = true;
|
||||
}
|
||||
|
||||
static void
|
||||
fill_usable_area_override(char *nodename, char *content)
|
||||
{
|
||||
|
|
@ -928,6 +981,8 @@ entry(xmlNode *node, char *nodename, char *content)
|
|||
rc.placement_cascade_offset_y = atoi(content);
|
||||
} else if (!strcmp(nodename, "name.theme")) {
|
||||
rc.theme_name = xstrdup(content);
|
||||
} else if (!strcmp(nodename, "titlelayout.theme")) {
|
||||
fill_title_layout(nodename, content);
|
||||
} else if (!strcmp(nodename, "cornerradius.theme")) {
|
||||
rc.corner_radius = atoi(content);
|
||||
} else if (!strcasecmp(nodename, "keepBorder.theme")) {
|
||||
|
|
@ -1248,6 +1303,8 @@ rcxml_init(void)
|
|||
static bool has_run;
|
||||
|
||||
if (!has_run) {
|
||||
wl_list_init(&rc.title_buttons_left);
|
||||
wl_list_init(&rc.title_buttons_right);
|
||||
wl_list_init(&rc.usable_area_overrides);
|
||||
wl_list_init(&rc.keybinds);
|
||||
wl_list_init(&rc.mousebinds);
|
||||
|
|
@ -1265,6 +1322,8 @@ rcxml_init(void)
|
|||
rc.placement_cascade_offset_y = 0;
|
||||
|
||||
rc.xdg_shell_server_side_deco = true;
|
||||
rc.show_title = false;
|
||||
rc.title_layout_loaded = false;
|
||||
rc.ssd_keep_border = true;
|
||||
rc.corner_radius = 8;
|
||||
rc.shadows_enabled = false;
|
||||
|
|
@ -1507,6 +1566,10 @@ post_processing(void)
|
|||
load_default_mouse_bindings();
|
||||
}
|
||||
|
||||
if (!rc.title_layout_loaded) {
|
||||
fill_title_layout("titlelayout.theme", "WLIMC");
|
||||
}
|
||||
|
||||
/*
|
||||
* Replace all earlier bindings by later ones
|
||||
* and clear the ones with an empty action list.
|
||||
|
|
@ -1737,6 +1800,16 @@ rcxml_finish(void)
|
|||
zfree(rc.theme_name);
|
||||
zfree(rc.workspace_config.prefix);
|
||||
|
||||
struct title_button *p, *p_tmp;
|
||||
wl_list_for_each_safe(p, p_tmp, &rc.title_buttons_left, link) {
|
||||
wl_list_remove(&p->link);
|
||||
zfree(p);
|
||||
}
|
||||
wl_list_for_each_safe(p, p_tmp, &rc.title_buttons_right, link) {
|
||||
wl_list_remove(&p->link);
|
||||
zfree(p);
|
||||
}
|
||||
|
||||
struct usable_area_override *area, *area_tmp;
|
||||
wl_list_for_each_safe(area, area_tmp, &rc.usable_area_overrides, link) {
|
||||
wl_list_remove(&area->link);
|
||||
|
|
|
|||
|
|
@ -220,7 +220,8 @@ snap_shrink_to_next_edge(struct view *view,
|
|||
|
||||
*geo = view->pending;
|
||||
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
|
||||
|
|
|
|||
|
|
@ -78,42 +78,6 @@ add_scene_buffer(struct wl_list *list, enum ssd_part_type type,
|
|||
return part;
|
||||
}
|
||||
|
||||
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,
|
||||
struct wlr_buffer *hover_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");
|
||||
wlr_log(WLR_ERROR, "invalid corner button type");
|
||||
abort();
|
||||
}
|
||||
|
||||
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, hover_buffer, 0, view);
|
||||
return button_root;
|
||||
}
|
||||
|
||||
static struct wlr_box
|
||||
get_scale_box(struct wlr_buffer *buffer, double container_width,
|
||||
double container_height)
|
||||
|
|
@ -142,19 +106,19 @@ get_scale_box(struct wlr_buffer *buffer, double container_width,
|
|||
|
||||
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, struct wlr_buffer *hover_buffer,
|
||||
int x, struct view *view)
|
||||
struct wlr_scene_tree *parent, struct wlr_buffer *icon_buffer,
|
||||
struct wlr_buffer *hover_buffer, int x, 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);
|
||||
|
||||
/* Background */
|
||||
struct ssd_part *bg_rect = add_scene_rect(part_list, type, parent,
|
||||
/* 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,
|
||||
bg_color);
|
||||
invisible);
|
||||
|
||||
/* Icon */
|
||||
struct wlr_scene_tree *icon_tree = wlr_scene_tree_create(parent);
|
||||
|
|
@ -186,7 +150,6 @@ add_scene_button(struct wl_list *part_list, enum ssd_part_type type,
|
|||
button->view = view;
|
||||
button->normal = icon_part->node;
|
||||
button->hover = hover_part->node;
|
||||
button->background = bg_rect->node;
|
||||
button->toggled = NULL;
|
||||
button->toggled_hover = NULL;
|
||||
button->icon_tree = icon_tree;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,64 @@
|
|||
static void set_squared_corners(struct ssd *ssd, bool enable);
|
||||
static void set_maximize_alt_icon(struct ssd *ssd, bool enable);
|
||||
|
||||
static void
|
||||
add_button(struct ssd *ssd, struct ssd_sub_tree *subtree, enum ssd_part_type type, int x)
|
||||
{
|
||||
struct view *view = ssd->view;
|
||||
struct theme *theme = view->server->theme;
|
||||
struct wlr_scene_tree *parent = subtree->tree;
|
||||
bool active = subtree == &ssd->titlebar.active;
|
||||
|
||||
struct ssd_part *btn_max_root;
|
||||
struct ssd_button *btn_max;
|
||||
|
||||
switch (type) {
|
||||
case LAB_SSD_BUTTON_WINDOW_MENU:
|
||||
add_scene_button(&subtree->parts, type, parent,
|
||||
active ? &theme->button_menu_active_unpressed->base
|
||||
: &theme->button_menu_inactive_unpressed->base,
|
||||
active ? &theme->button_menu_active_hover->base
|
||||
: &theme->button_menu_inactive_hover->base,
|
||||
x, view);
|
||||
break;
|
||||
case LAB_SSD_BUTTON_ICONIFY:
|
||||
add_scene_button(&subtree->parts, type, parent,
|
||||
active ? &theme->button_iconify_active_unpressed->base
|
||||
: &theme->button_iconify_inactive_unpressed->base,
|
||||
active ? &theme->button_iconify_active_hover->base
|
||||
: &theme->button_iconify_inactive_hover->base,
|
||||
x, view);
|
||||
break;
|
||||
case LAB_SSD_BUTTON_MAXIMIZE:
|
||||
/* Maximize button has an alternate state when maximized */
|
||||
btn_max_root = add_scene_button(&subtree->parts, type, parent,
|
||||
active ? &theme->button_maximize_active_unpressed->base
|
||||
: &theme->button_maximize_inactive_unpressed->base,
|
||||
active ? &theme->button_maximize_active_hover->base
|
||||
: &theme->button_maximize_inactive_hover->base,
|
||||
x, view);
|
||||
btn_max = node_ssd_button_from_node(btn_max_root->node);
|
||||
add_toggled_icon(btn_max, &subtree->parts, LAB_SSD_BUTTON_MAXIMIZE,
|
||||
active ? &theme->button_restore_active_unpressed->base
|
||||
: &theme->button_restore_inactive_unpressed->base,
|
||||
active ? &theme->button_restore_active_hover->base
|
||||
: &theme->button_restore_inactive_hover->base);
|
||||
break;
|
||||
case LAB_SSD_BUTTON_CLOSE:
|
||||
add_scene_button(&subtree->parts, type, parent,
|
||||
active ? &theme->button_close_active_unpressed->base
|
||||
: &theme->button_close_inactive_unpressed->base,
|
||||
active ? &theme->button_close_active_hover->base
|
||||
: &theme->button_close_inactive_hover->base,
|
||||
x, view);
|
||||
break;
|
||||
default:
|
||||
assert(false && "invalid titlebar part");
|
||||
wlr_log(WLR_ERROR, "invalid titlebar type");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ssd_titlebar_create(struct ssd *ssd)
|
||||
{
|
||||
|
|
@ -33,18 +91,6 @@ ssd_titlebar_create(struct ssd *ssd)
|
|||
struct wlr_buffer *corner_top_left;
|
||||
struct wlr_buffer *corner_top_right;
|
||||
|
||||
struct wlr_buffer *menu_button_unpressed;
|
||||
struct wlr_buffer *iconify_button_unpressed;
|
||||
struct wlr_buffer *maximize_button_unpressed;
|
||||
struct wlr_buffer *restore_button_unpressed;
|
||||
struct wlr_buffer *close_button_unpressed;
|
||||
|
||||
struct wlr_buffer *menu_button_hover;
|
||||
struct wlr_buffer *iconify_button_hover;
|
||||
struct wlr_buffer *maximize_button_hover;
|
||||
struct wlr_buffer *restore_button_hover;
|
||||
struct wlr_buffer *close_button_hover;
|
||||
|
||||
ssd->titlebar.tree = wlr_scene_tree_create(ssd->tree);
|
||||
|
||||
struct ssd_sub_tree *subtree;
|
||||
|
|
@ -56,63 +102,38 @@ ssd_titlebar_create(struct ssd *ssd)
|
|||
color = theme->window_active_title_bg_color;
|
||||
corner_top_left = &theme->corner_top_left_active_normal->base;
|
||||
corner_top_right = &theme->corner_top_right_active_normal->base;
|
||||
menu_button_unpressed = &theme->button_menu_active_unpressed->base;
|
||||
iconify_button_unpressed = &theme->button_iconify_active_unpressed->base;
|
||||
close_button_unpressed = &theme->button_close_active_unpressed->base;
|
||||
maximize_button_unpressed = &theme->button_maximize_active_unpressed->base;
|
||||
restore_button_unpressed = &theme->button_restore_active_unpressed->base;
|
||||
|
||||
menu_button_hover = &theme->button_menu_active_hover->base;
|
||||
iconify_button_hover = &theme->button_iconify_active_hover->base;
|
||||
close_button_hover = &theme->button_close_active_hover->base;
|
||||
maximize_button_hover = &theme->button_maximize_active_hover->base;
|
||||
restore_button_hover = &theme->button_restore_active_hover->base;
|
||||
} else {
|
||||
color = theme->window_inactive_title_bg_color;
|
||||
corner_top_left = &theme->corner_top_left_inactive_normal->base;
|
||||
corner_top_right = &theme->corner_top_right_inactive_normal->base;
|
||||
menu_button_unpressed = &theme->button_menu_inactive_unpressed->base;
|
||||
iconify_button_unpressed = &theme->button_iconify_inactive_unpressed->base;
|
||||
maximize_button_unpressed =
|
||||
&theme->button_maximize_inactive_unpressed->base;
|
||||
restore_button_unpressed = &theme->button_restore_inactive_unpressed->base;
|
||||
close_button_unpressed = &theme->button_close_inactive_unpressed->base;
|
||||
|
||||
menu_button_hover = &theme->button_menu_inactive_hover->base;
|
||||
iconify_button_hover = &theme->button_iconify_inactive_hover->base;
|
||||
close_button_hover = &theme->button_close_inactive_hover->base;
|
||||
maximize_button_hover = &theme->button_maximize_inactive_hover->base;
|
||||
restore_button_hover = &theme->button_restore_inactive_hover->base;
|
||||
|
||||
wlr_scene_node_set_enabled(&parent->node, false);
|
||||
}
|
||||
wl_list_init(&subtree->parts);
|
||||
|
||||
/* Title */
|
||||
/* Background */
|
||||
add_scene_rect(&subtree->parts, LAB_SSD_PART_TITLEBAR, parent,
|
||||
width - theme->window_button_width * SSD_BUTTON_COUNT,
|
||||
theme->title_height, theme->window_button_width, 0, color);
|
||||
width - theme->window_button_width * 2, theme->title_height,
|
||||
theme->window_button_width, 0, color);
|
||||
add_scene_buffer(&subtree->parts, LAB_SSD_PART_CORNER_TOP_LEFT, parent,
|
||||
corner_top_left, -rc.theme->border_width, -rc.theme->border_width);
|
||||
add_scene_buffer(&subtree->parts, LAB_SSD_PART_CORNER_TOP_RIGHT, parent,
|
||||
corner_top_right, width - theme->window_button_width,
|
||||
-rc.theme->border_width);
|
||||
|
||||
/* Buttons */
|
||||
add_scene_button_corner(&subtree->parts,
|
||||
LAB_SSD_BUTTON_WINDOW_MENU, LAB_SSD_PART_CORNER_TOP_LEFT, parent,
|
||||
corner_top_left, menu_button_unpressed, menu_button_hover, 0, view);
|
||||
add_scene_button(&subtree->parts, LAB_SSD_BUTTON_ICONIFY, parent,
|
||||
color, iconify_button_unpressed, iconify_button_hover,
|
||||
width - theme->window_button_width * 3, view);
|
||||
struct title_button *b;
|
||||
int x = 0;
|
||||
wl_list_for_each(b, &rc.title_buttons_left, link) {
|
||||
add_button(ssd, subtree, b->type, x);
|
||||
x += theme->window_button_width;
|
||||
}
|
||||
|
||||
/* Maximize button has an alternate state when maximized */
|
||||
struct ssd_part *btn_max_root = add_scene_button(
|
||||
&subtree->parts, LAB_SSD_BUTTON_MAXIMIZE, parent,
|
||||
color, maximize_button_unpressed, maximize_button_hover,
|
||||
width - theme->window_button_width * 2, view);
|
||||
struct ssd_button *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);
|
||||
|
||||
add_scene_button_corner(&subtree->parts,
|
||||
LAB_SSD_BUTTON_CLOSE, LAB_SSD_PART_CORNER_TOP_RIGHT, parent,
|
||||
corner_top_right, close_button_unpressed, close_button_hover,
|
||||
width - theme->window_button_width * 1, view);
|
||||
x = width;
|
||||
wl_list_for_each_reverse(b, &rc.title_buttons_right, link) {
|
||||
x -= theme->window_button_width;
|
||||
add_button(ssd, subtree, b->type, x);
|
||||
}
|
||||
} FOR_EACH_END
|
||||
|
||||
ssd_update_title(ssd);
|
||||
|
|
@ -129,36 +150,28 @@ 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
|
||||
set_squared_corners(struct ssd *ssd, bool enable)
|
||||
{
|
||||
struct view *view = ssd->view;
|
||||
int width = view->current.width;
|
||||
struct theme *theme = view->server->theme;
|
||||
|
||||
struct ssd_part *part;
|
||||
struct ssd_sub_tree *subtree;
|
||||
enum ssd_part_type ssd_type[2] = { LAB_SSD_BUTTON_WINDOW_MENU, LAB_SSD_BUTTON_CLOSE };
|
||||
int x = enable ? 0 : theme->window_button_width;
|
||||
|
||||
FOR_EACH_STATE(ssd, subtree) {
|
||||
for (size_t i = 0; i < ARRAY_SIZE(ssd_type); i++) {
|
||||
part = ssd_get_part(&subtree->parts, ssd_type[i]);
|
||||
struct ssd_button *button = node_ssd_button_from_node(part->node);
|
||||
part = ssd_get_part(&subtree->parts, LAB_SSD_PART_TITLEBAR);
|
||||
wlr_scene_node_set_position(part->node, x, 0);
|
||||
wlr_scene_rect_set_size(
|
||||
wlr_scene_rect_from_node(part->node), width - 2 * x, theme->title_height);
|
||||
|
||||
/* Toggle background between invisible and titlebar background color */
|
||||
struct wlr_scene_rect *rect = wlr_scene_rect_from_node(button->background);
|
||||
wlr_scene_rect_set_color(rect, !enable ? (float[4]) {0, 0, 0, 0} : (
|
||||
subtree == &ssd->titlebar.active
|
||||
? rc.theme->window_active_title_bg_color
|
||||
: rc.theme->window_inactive_title_bg_color));
|
||||
part = ssd_get_part(&subtree->parts, LAB_SSD_PART_CORNER_TOP_LEFT);
|
||||
wlr_scene_node_set_enabled(part->node, !enable);
|
||||
|
||||
/* Toggle rounded corner image itself */
|
||||
struct wlr_scene_node *rounded_corner =
|
||||
wl_container_of(part->node->link.prev, rounded_corner, link);
|
||||
wlr_scene_node_set_enabled(rounded_corner, !enable);
|
||||
}
|
||||
part = ssd_get_part(&subtree->parts, LAB_SSD_PART_CORNER_TOP_RIGHT);
|
||||
wlr_scene_node_set_enabled(part->node, !enable);
|
||||
} FOR_EACH_END
|
||||
}
|
||||
|
||||
|
|
@ -171,6 +184,10 @@ set_maximize_alt_icon(struct ssd *ssd, bool enable)
|
|||
|
||||
FOR_EACH_STATE(ssd, subtree) {
|
||||
part = ssd_get_part(&subtree->parts, LAB_SSD_BUTTON_MAXIMIZE);
|
||||
if (!part) {
|
||||
return;
|
||||
}
|
||||
|
||||
button = node_ssd_button_from_node(part->node);
|
||||
|
||||
if (button->toggled) {
|
||||
|
|
@ -210,38 +227,31 @@ ssd_titlebar_update(struct ssd *ssd)
|
|||
return;
|
||||
}
|
||||
|
||||
int x;
|
||||
struct ssd_part *part;
|
||||
struct ssd_sub_tree *subtree;
|
||||
struct title_button *b;
|
||||
int bg_offset = maximized || tiled_not_maximized ? 0 : theme->window_button_width;
|
||||
FOR_EACH_STATE(ssd, subtree) {
|
||||
wl_list_for_each(part, &subtree->parts, link) {
|
||||
switch (part->type) {
|
||||
case LAB_SSD_PART_TITLEBAR:
|
||||
wlr_scene_rect_set_size(
|
||||
wlr_scene_rect_from_node(part->node),
|
||||
width - theme->window_button_width * SSD_BUTTON_COUNT,
|
||||
theme->title_height);
|
||||
continue;
|
||||
case LAB_SSD_BUTTON_ICONIFY:
|
||||
if (is_direct_child(part->node, subtree)) {
|
||||
wlr_scene_node_set_position(part->node,
|
||||
width - theme->window_button_width * 3, 0);
|
||||
}
|
||||
continue;
|
||||
case LAB_SSD_BUTTON_MAXIMIZE:
|
||||
if (is_direct_child(part->node, subtree)) {
|
||||
wlr_scene_node_set_position(part->node,
|
||||
width - theme->window_button_width * 2, 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, 0);
|
||||
}
|
||||
continue;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
part = ssd_get_part(&subtree->parts, LAB_SSD_PART_TITLEBAR);
|
||||
wlr_scene_rect_set_size(
|
||||
wlr_scene_rect_from_node(part->node),
|
||||
width - bg_offset * 2, theme->title_height);
|
||||
|
||||
x = 0;
|
||||
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);
|
||||
x += theme->window_button_width;
|
||||
}
|
||||
|
||||
x = width - theme->window_button_width;
|
||||
part = ssd_get_part(&subtree->parts, LAB_SSD_PART_CORNER_TOP_RIGHT);
|
||||
wlr_scene_node_set_position(part->node, x, -rc.theme->border_width);
|
||||
wl_list_for_each_reverse(b, &rc.title_buttons_right, link) {
|
||||
part = ssd_get_part(&subtree->parts, b->type);
|
||||
wlr_scene_node_set_position(part->node, x, 0);
|
||||
x -= theme->window_button_width;
|
||||
}
|
||||
} FOR_EACH_END
|
||||
ssd_update_title(ssd);
|
||||
|
|
@ -288,7 +298,9 @@ ssd_update_title_positions(struct ssd *ssd)
|
|||
struct view *view = ssd->view;
|
||||
struct theme *theme = view->server->theme;
|
||||
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 buffer_height, buffer_width;
|
||||
|
|
@ -304,7 +316,7 @@ ssd_update_title_positions(struct ssd *ssd)
|
|||
|
||||
buffer_width = part->buffer ? part->buffer->width : 0;
|
||||
buffer_height = part->buffer ? part->buffer->height : 0;
|
||||
x = theme->window_button_width;
|
||||
x = offset_left;
|
||||
y = (theme->title_height - buffer_height) / 2;
|
||||
|
||||
if (title_bg_width <= 0) {
|
||||
|
|
@ -314,7 +326,7 @@ ssd_update_title_positions(struct ssd *ssd)
|
|||
wlr_scene_node_set_enabled(part->node, true);
|
||||
|
||||
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 */
|
||||
x = (width - buffer_width) / 2;
|
||||
} else {
|
||||
|
|
@ -337,7 +349,7 @@ ssd_update_title_positions(struct ssd *ssd)
|
|||
void
|
||||
ssd_update_title(struct ssd *ssd)
|
||||
{
|
||||
if (!ssd) {
|
||||
if (!ssd || !rc.show_title) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -357,8 +369,9 @@ ssd_update_title(struct ssd *ssd)
|
|||
struct ssd_part *part;
|
||||
struct ssd_sub_tree *subtree;
|
||||
struct ssd_state_title_width *dstate;
|
||||
int title_bg_width = view->current.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 = view->current.width - offset_left - offset_right;
|
||||
|
||||
FOR_EACH_STATE(ssd, subtree) {
|
||||
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 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_height = view_effective_height(ssd->view, /* use_pending */ false);
|
||||
|
||||
if (eff_width > 0 && eff_width < min_view_width) {
|
||||
/*
|
||||
* 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,
|
||||
"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);
|
||||
|
||||
/*
|
||||
* TODO: Once we implement titleLayout we can make the
|
||||
* return values depend on parsed config values.
|
||||
*/
|
||||
if (!strcmp(icon_name, "menu")) {
|
||||
return LAB_CORNER_TOP_LEFT;
|
||||
} else if (!strcmp(icon_name, "close")) {
|
||||
return LAB_CORNER_TOP_RIGHT;
|
||||
struct title_button *b;
|
||||
wl_list_for_each(b, &rc.title_buttons_left, 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_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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -617,7 +617,8 @@ view_adjust_size(struct view *view, int *w, int *h)
|
|||
{
|
||||
assert(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
|
||||
|
|
|
|||
|
|
@ -611,7 +611,8 @@ check_natural_geometry(struct view *view)
|
|||
* un-maximized size when started maximized. Try to detect this
|
||||
* 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)
|
||||
&& (view->natural_geometry.width < min_view_width
|
||||
|| view->natural_geometry.height < LAB_MIN_VIEW_HEIGHT)) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue