menu: add title theme options (#2097)

Add theme options `menu.title.text.color` and `menu.title.text.justify`.

Add font place MenuHeader: `<font place="MenuHeader">`

Add `Oblique` font style

```
<theme>
  <font>
    <slant>Oblique</slant>
  </font>
</theme>
```
This commit is contained in:
droc12345 2024-08-21 12:27:07 -05:00 committed by GitHub
parent 6564e1bc8d
commit 8fda9968e6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 79 additions and 7 deletions

View file

@ -448,6 +448,7 @@ extending outward from the snapped edge.
- ActiveWindow - titlebar of active window - ActiveWindow - titlebar of active window
- InactiveWindow - titlebar of all windows that aren't focused by the - InactiveWindow - titlebar of all windows that aren't focused by the
cursor cursor
- MenuHeader - menu title
- MenuItem - menu item (currently only root menu) - MenuItem - menu item (currently only root menu)
- OnScreenDisplay - items in the on screen display - OnScreenDisplay - items in the on screen display
If no place attribute is provided, the setting will be applied to all If no place attribute is provided, the setting will be applied to all
@ -460,7 +461,7 @@ extending outward from the snapped edge.
Font size in pixels. Default is 10. Font size in pixels. Default is 10.
*<theme><font place=""><slant>* *<theme><font place=""><slant>*
Font slant (normal or italic). Default is normal. Font slant (normal, oblique or italic). Default is normal.
*<theme><font place=""><weight>* *<theme><font place=""><weight>*
Font weight (normal or bold). Default is normal. Font weight (normal or bold). Default is normal.

View file

@ -67,6 +67,10 @@ labwc-config(5).
Vertical padding of menu text entries in pixels. Vertical padding of menu text entries in pixels.
Default is 4. Default is 4.
*menu.title.text.justify*
Specifies how menu titles are aligned in the titlebar.
Type justification. Default Center.
*menu.overlap.x* *menu.overlap.x*
Horizontal overlap in pixels between submenus and their parents. A Horizontal overlap in pixels between submenus and their parents. A
positive value move submenus over the top of their parents, whereas a positive value move submenus over the top of their parents, whereas a
@ -178,6 +182,9 @@ elements are not listed here, but are supported.
Menu title color. Default #589bda. Menu title color. Default #589bda.
Note: A menu title is a separator with a label. Note: A menu title is a separator with a label.
*menu.title.text.color*
Text color of separator label. Default #ffffff.
*osd.bg.color* *osd.bg.color*
Background color of on-screen-display. Inherits Background color of on-screen-display. Inherits
*window.active.title.bg.color* if not set. *window.active.title.bg.color* if not set.

View file

@ -61,6 +61,12 @@
</menu> </menu>
<menu id="some-custom-menu"> <menu id="some-custom-menu">
<!--
Creates menu title.
To create an empty header with no text,
set label=" ", not label=""
-->
<separator label="custom menu" />
<item label="Reconfigure"> <item label="Reconfigure">
<action name="Reconfigure" /> <action name="Reconfigure" />
</item> </item>

View file

@ -43,6 +43,12 @@
<slant>normal</slant> <slant>normal</slant>
<weight>normal</weight> <weight>normal</weight>
</font> </font>
<font place="MenuHeader">
<name>sans</name>
<size>10</size>
<slant>normal</slant>
<weight>normal</weight>
</font>
<font place="MenuItem"> <font place="MenuItem">
<name>sans</name> <name>sans</name>
<size>10</size> <size>10</size>

View file

@ -63,6 +63,8 @@ menu.separator.padding.width: 6
menu.separator.padding.height: 3 menu.separator.padding.height: 3
menu.separator.color: #888888 menu.separator.color: #888888
menu.title.bg.color: #589bda menu.title.bg.color: #589bda
menu.title.text.color: #ffffff
menu.title.text.justify: Center
# on screen display (window-cycle dialog) # on screen display (window-cycle dialog)
osd.bg.color: #e1dedb osd.bg.color: #e1dedb

View file

@ -6,7 +6,8 @@ struct lab_data_buffer;
enum font_slant { enum font_slant {
FONT_SLANT_NORMAL = 0, FONT_SLANT_NORMAL = 0,
FONT_SLANT_ITALIC FONT_SLANT_ITALIC,
FONT_SLANT_OBLIQUE
}; };
enum font_weight { enum font_weight {

View file

@ -80,6 +80,7 @@ struct rcxml {
bool shadows_enabled; bool shadows_enabled;
struct font font_activewindow; struct font font_activewindow;
struct font font_inactivewindow; struct font font_inactivewindow;
struct font font_menuheader;
struct font font_menuitem; struct font font_menuitem;
struct font font_osd; struct font font_osd;

View file

@ -44,6 +44,7 @@ struct theme {
float window_active_label_text_color[4]; float window_active_label_text_color[4];
float window_inactive_label_text_color[4]; float window_inactive_label_text_color[4];
enum lab_justification window_label_text_justify; enum lab_justification window_label_text_justify;
enum lab_justification menu_title_text_justify;
/* button width */ /* button width */
int window_button_width; int window_button_width;
@ -78,6 +79,8 @@ struct theme {
float menu_title_bg_color[4]; float menu_title_bg_color[4];
float menu_title_text_color[4];
int osd_border_width; int osd_border_width;
float osd_bg_color[4]; float osd_bg_color[4];

View file

@ -20,6 +20,9 @@ font_to_pango_desc(struct font *font)
if (font->slant == FONT_SLANT_ITALIC) { if (font->slant == FONT_SLANT_ITALIC) {
pango_font_description_set_style(desc, PANGO_STYLE_ITALIC); pango_font_description_set_style(desc, PANGO_STYLE_ITALIC);
} }
if (font->slant == FONT_SLANT_OBLIQUE) {
pango_font_description_set_style(desc, PANGO_STYLE_OBLIQUE);
}
if (font->weight == FONT_WEIGHT_BOLD) { if (font->weight == FONT_WEIGHT_BOLD) {
pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD); pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD);
} }

View file

@ -69,6 +69,7 @@ enum font_place {
FONT_PLACE_UNKNOWN, FONT_PLACE_UNKNOWN,
FONT_PLACE_ACTIVEWINDOW, FONT_PLACE_ACTIVEWINDOW,
FONT_PLACE_INACTIVEWINDOW, FONT_PLACE_INACTIVEWINDOW,
FONT_PLACE_MENUHEADER,
FONT_PLACE_MENUITEM, FONT_PLACE_MENUITEM,
FONT_PLACE_OSD, FONT_PLACE_OSD,
/* TODO: Add all places based on Openbox's rc.xml */ /* TODO: Add all places based on Openbox's rc.xml */
@ -691,8 +692,13 @@ set_font_attr(struct font *font, const char *nodename, const char *content)
} else if (!strcmp(nodename, "size")) { } else if (!strcmp(nodename, "size")) {
font->size = atoi(content); font->size = atoi(content);
} else if (!strcmp(nodename, "slant")) { } else if (!strcmp(nodename, "slant")) {
font->slant = !strcasecmp(content, "italic") ? if (!strcasecmp(content, "italic")) {
FONT_SLANT_ITALIC : FONT_SLANT_NORMAL; font->slant = FONT_SLANT_ITALIC;
} else if (!strcasecmp(content, "oblique")) {
font->slant = FONT_SLANT_OBLIQUE;
} else {
font->slant = FONT_SLANT_NORMAL;
}
} else if (!strcmp(nodename, "weight")) { } else if (!strcmp(nodename, "weight")) {
font->weight = !strcasecmp(content, "bold") ? font->weight = !strcasecmp(content, "bold") ?
FONT_WEIGHT_BOLD : FONT_WEIGHT_NORMAL; FONT_WEIGHT_BOLD : FONT_WEIGHT_NORMAL;
@ -715,6 +721,7 @@ fill_font(char *nodename, char *content, enum font_place place)
*/ */
set_font_attr(&rc.font_activewindow, nodename, content); set_font_attr(&rc.font_activewindow, nodename, content);
set_font_attr(&rc.font_inactivewindow, nodename, content); set_font_attr(&rc.font_inactivewindow, nodename, content);
set_font_attr(&rc.font_menuheader, nodename, content);
set_font_attr(&rc.font_menuitem, nodename, content); set_font_attr(&rc.font_menuitem, nodename, content);
set_font_attr(&rc.font_osd, nodename, content); set_font_attr(&rc.font_osd, nodename, content);
break; break;
@ -724,6 +731,9 @@ fill_font(char *nodename, char *content, enum font_place place)
case FONT_PLACE_INACTIVEWINDOW: case FONT_PLACE_INACTIVEWINDOW:
set_font_attr(&rc.font_inactivewindow, nodename, content); set_font_attr(&rc.font_inactivewindow, nodename, content);
break; break;
case FONT_PLACE_MENUHEADER:
set_font_attr(&rc.font_menuheader, nodename, content);
break;
case FONT_PLACE_MENUITEM: case FONT_PLACE_MENUITEM:
set_font_attr(&rc.font_menuitem, nodename, content); set_font_attr(&rc.font_menuitem, nodename, content);
break; break;
@ -748,6 +758,8 @@ enum_font_place(const char *place)
return FONT_PLACE_ACTIVEWINDOW; return FONT_PLACE_ACTIVEWINDOW;
} else if (!strcasecmp(place, "InactiveWindow")) { } else if (!strcasecmp(place, "InactiveWindow")) {
return FONT_PLACE_INACTIVEWINDOW; return FONT_PLACE_INACTIVEWINDOW;
} else if (!strcasecmp(place, "MenuHeader")) {
return FONT_PLACE_MENUHEADER;
} else if (!strcasecmp(place, "MenuItem")) { } else if (!strcasecmp(place, "MenuItem")) {
return FONT_PLACE_MENUITEM; return FONT_PLACE_MENUITEM;
} else if (!strcasecmp(place, "OnScreenDisplay") } else if (!strcasecmp(place, "OnScreenDisplay")
@ -1265,6 +1277,7 @@ rcxml_init(void)
init_font_defaults(&rc.font_activewindow); init_font_defaults(&rc.font_activewindow);
init_font_defaults(&rc.font_inactivewindow); init_font_defaults(&rc.font_inactivewindow);
init_font_defaults(&rc.font_menuheader);
init_font_defaults(&rc.font_menuitem); init_font_defaults(&rc.font_menuitem);
init_font_defaults(&rc.font_osd); init_font_defaults(&rc.font_osd);
@ -1510,6 +1523,9 @@ post_processing(void)
if (!rc.font_inactivewindow.name) { if (!rc.font_inactivewindow.name) {
rc.font_inactivewindow.name = xstrdup("sans"); rc.font_inactivewindow.name = xstrdup("sans");
} }
if (!rc.font_menuheader.name) {
rc.font_menuheader.name = xstrdup("sans");
}
if (!rc.font_menuitem.name) { if (!rc.font_menuitem.name) {
rc.font_menuitem.name = xstrdup("sans"); rc.font_menuitem.name = xstrdup("sans");
} }
@ -1715,6 +1731,7 @@ rcxml_finish(void)
{ {
zfree(rc.font_activewindow.name); zfree(rc.font_activewindow.name);
zfree(rc.font_inactivewindow.name); zfree(rc.font_inactivewindow.name);
zfree(rc.font_menuheader.name);
zfree(rc.font_menuitem.name); zfree(rc.font_menuitem.name);
zfree(rc.font_osd.name); zfree(rc.font_osd.name);
zfree(rc.theme_name); zfree(rc.theme_name);

View file

@ -141,6 +141,19 @@ menu_update_width(struct menu *menu)
wlr_scene_rect_set_size( wlr_scene_rect_set_size(
wlr_scene_rect_from_node(item->normal.text), wlr_scene_rect_from_node(item->normal.text),
width, theme->menu_separator_line_thickness); width, theme->menu_separator_line_thickness);
} else if (item->type == LAB_MENU_TITLE) {
if (item->native_width > max_width) {
scaled_font_buffer_set_max_width(item->normal.buffer,
max_width);
}
if (theme->menu_title_text_justify == LAB_JUSTIFY_CENTER) {
int x, y;
x = (max_width - theme->menu_item_padding_x -
item->native_width) / 2;
x = x < 0 ? 0 : x;
y = (theme->menu_item_height - item->normal.buffer->height) / 2;
wlr_scene_node_set_position(item->normal.text, x, y);
}
} }
if (item->selectable) { if (item->selectable) {
@ -295,7 +308,7 @@ separator_create(struct menu *menu, const char *label)
if (menuitem->type == LAB_MENU_TITLE) { if (menuitem->type == LAB_MENU_TITLE) {
menuitem->height = theme->menu_item_height; menuitem->height = theme->menu_item_height;
menuitem->native_width = font_width(&rc.font_menuitem, label); menuitem->native_width = font_width(&rc.font_menuheader, label);
} else if (menuitem->type == LAB_MENU_SEPARATOR_LINE) { } else if (menuitem->type == LAB_MENU_SEPARATOR_LINE) {
menuitem->height = theme->menu_separator_line_thickness + menuitem->height = theme->menu_separator_line_thickness +
2 * theme->menu_separator_padding_height; 2 * theme->menu_separator_padding_height;
@ -312,6 +325,8 @@ separator_create(struct menu *menu, const char *label)
/* Item background nodes */ /* Item background nodes */
float *bg_color = menuitem->type == LAB_MENU_TITLE float *bg_color = menuitem->type == LAB_MENU_TITLE
? theme->menu_title_bg_color : theme->menu_items_bg_color; ? theme->menu_title_bg_color : theme->menu_items_bg_color;
float *text_color = menuitem->type == LAB_MENU_TITLE
? theme->menu_title_text_color : theme->menu_items_text_color;
menuitem->normal.background = &wlr_scene_rect_create( menuitem->normal.background = &wlr_scene_rect_create(
menuitem->normal.tree, menuitem->normal.tree,
menu->size.width, menuitem->height, bg_color)->node; menu->size.width, menuitem->height, bg_color)->node;
@ -328,8 +343,8 @@ separator_create(struct menu *menu, const char *label)
menuitem->normal.text = &menuitem->normal.buffer->scene_buffer->node; menuitem->normal.text = &menuitem->normal.buffer->scene_buffer->node;
/* Font buffer */ /* Font buffer */
scaled_font_buffer_update(menuitem->normal.buffer, label, scaled_font_buffer_update(menuitem->normal.buffer, label,
menuitem->native_width, &rc.font_menuitem, menuitem->native_width, &rc.font_menuheader,
theme->menu_items_text_color, bg_color, /* arrow */ NULL); text_color, bg_color, /* arrow */ NULL);
/* Center font nodes */ /* Center font nodes */
int x, y; int x, y;
x = theme->menu_item_padding_x; x = theme->menu_item_padding_x;

View file

@ -487,6 +487,7 @@ theme_builtin(struct theme *theme, struct server *server)
parse_hexstr("#000000", theme->window_active_label_text_color); parse_hexstr("#000000", theme->window_active_label_text_color);
parse_hexstr("#000000", theme->window_inactive_label_text_color); parse_hexstr("#000000", theme->window_inactive_label_text_color);
theme->window_label_text_justify = parse_justification("Center"); theme->window_label_text_justify = parse_justification("Center");
theme->menu_title_text_justify = parse_justification("Center");
theme->window_button_width = 26; theme->window_button_width = 26;
@ -530,6 +531,8 @@ theme_builtin(struct theme *theme, struct server *server)
parse_hexstr("#589bda", theme->menu_title_bg_color); parse_hexstr("#589bda", theme->menu_title_bg_color);
parse_hexstr("#ffffff", theme->menu_title_text_color);
theme->osd_window_switcher_width = 600; theme->osd_window_switcher_width = 600;
theme->osd_window_switcher_width_is_percent = false; theme->osd_window_switcher_width_is_percent = false;
theme->osd_window_switcher_padding = 4; theme->osd_window_switcher_padding = 4;
@ -606,6 +609,9 @@ entry(struct theme *theme, const char *key, const char *value)
if (match_glob(key, "menu.items.padding.y")) { if (match_glob(key, "menu.items.padding.y")) {
theme->menu_item_padding_y = atoi(value); theme->menu_item_padding_y = atoi(value);
} }
if (match_glob(key, "menu.title.text.justify")) {
theme->menu_title_text_justify = parse_justification(value);
}
if (match_glob(key, "menu.overlap.x")) { if (match_glob(key, "menu.overlap.x")) {
theme->menu_overlap_x = atoi(value); theme->menu_overlap_x = atoi(value);
} }
@ -772,6 +778,10 @@ entry(struct theme *theme, const char *key, const char *value)
parse_hexstr(value, theme->menu_title_bg_color); parse_hexstr(value, theme->menu_title_bg_color);
} }
if (match_glob(key, "menu.title.text.color")) {
parse_hexstr(value, theme->menu_title_text_color);
}
if (match_glob(key, "osd.bg.color")) { if (match_glob(key, "osd.bg.color")) {
parse_hexstr(value, theme->osd_bg_color); parse_hexstr(value, theme->osd_bg_color);
} }