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>
```
- ActiveWindow - titlebar of active window
- InactiveWindow - titlebar of all windows that aren't focused by the
cursor
+ - MenuHeader - menu title
- MenuItem - menu item (currently only root menu)
- OnScreenDisplay - items in the on screen display
If no place attribute is provided, the setting will be applied to all
Font size in pixels. Default is 10.
*<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>*
Font weight (normal or bold). Default is normal.
Vertical padding of menu text entries in pixels.
Default is 4.
+*menu.title.text.justify*
+ Specifies how menu titles are aligned in the titlebar.
+ Type justification. Default Center.
+
*menu.overlap.x*
Horizontal overlap in pixels between submenus and their parents. A
positive value move submenus over the top of their parents, whereas a
Menu title color. Default #589bda.
Note: A menu title is a separator with a label.
+*menu.title.text.color*
+ Text color of separator label. Default #ffffff.
+
*osd.bg.color*
Background color of on-screen-display. Inherits
*window.active.title.bg.color* if not set.
</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">
<action name="Reconfigure" />
</item>
<slant>normal</slant>
<weight>normal</weight>
</font>
+ <font place="MenuHeader">
+ <name>sans</name>
+ <size>10</size>
+ <slant>normal</slant>
+ <weight>normal</weight>
+ </font>
<font place="MenuItem">
<name>sans</name>
<size>10</size>
menu.separator.padding.height: 3
menu.separator.color: #888888
menu.title.bg.color: #589bda
+menu.title.text.color: #ffffff
+menu.title.text.justify: Center
# on screen display (window-cycle dialog)
osd.bg.color: #e1dedb
enum font_slant {
FONT_SLANT_NORMAL = 0,
- FONT_SLANT_ITALIC
+ FONT_SLANT_ITALIC,
+ FONT_SLANT_OBLIQUE
};
enum font_weight {
bool shadows_enabled;
struct font font_activewindow;
struct font font_inactivewindow;
+ struct font font_menuheader;
struct font font_menuitem;
struct font font_osd;
float window_active_label_text_color[4];
float window_inactive_label_text_color[4];
enum lab_justification window_label_text_justify;
+ enum lab_justification menu_title_text_justify;
/* button width */
int window_button_width;
float menu_title_bg_color[4];
+ float menu_title_text_color[4];
+
int osd_border_width;
float osd_bg_color[4];
if (font->slant == FONT_SLANT_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) {
pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD);
}
FONT_PLACE_UNKNOWN,
FONT_PLACE_ACTIVEWINDOW,
FONT_PLACE_INACTIVEWINDOW,
+ FONT_PLACE_MENUHEADER,
FONT_PLACE_MENUITEM,
FONT_PLACE_OSD,
/* TODO: Add all places based on Openbox's rc.xml */
} else if (!strcmp(nodename, "size")) {
font->size = atoi(content);
} else if (!strcmp(nodename, "slant")) {
- font->slant = !strcasecmp(content, "italic") ?
- FONT_SLANT_ITALIC : FONT_SLANT_NORMAL;
+ if (!strcasecmp(content, "italic")) {
+ 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")) {
font->weight = !strcasecmp(content, "bold") ?
FONT_WEIGHT_BOLD : FONT_WEIGHT_NORMAL;
*/
set_font_attr(&rc.font_activewindow, 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_osd, nodename, content);
break;
case FONT_PLACE_INACTIVEWINDOW:
set_font_attr(&rc.font_inactivewindow, nodename, content);
break;
+ case FONT_PLACE_MENUHEADER:
+ set_font_attr(&rc.font_menuheader, nodename, content);
+ break;
case FONT_PLACE_MENUITEM:
set_font_attr(&rc.font_menuitem, nodename, content);
break;
return FONT_PLACE_ACTIVEWINDOW;
} else if (!strcasecmp(place, "InactiveWindow")) {
return FONT_PLACE_INACTIVEWINDOW;
+ } else if (!strcasecmp(place, "MenuHeader")) {
+ return FONT_PLACE_MENUHEADER;
} else if (!strcasecmp(place, "MenuItem")) {
return FONT_PLACE_MENUITEM;
} else if (!strcasecmp(place, "OnScreenDisplay")
init_font_defaults(&rc.font_activewindow);
init_font_defaults(&rc.font_inactivewindow);
+ init_font_defaults(&rc.font_menuheader);
init_font_defaults(&rc.font_menuitem);
init_font_defaults(&rc.font_osd);
if (!rc.font_inactivewindow.name) {
rc.font_inactivewindow.name = xstrdup("sans");
}
+ if (!rc.font_menuheader.name) {
+ rc.font_menuheader.name = xstrdup("sans");
+ }
if (!rc.font_menuitem.name) {
rc.font_menuitem.name = xstrdup("sans");
}
{
zfree(rc.font_activewindow.name);
zfree(rc.font_inactivewindow.name);
+ zfree(rc.font_menuheader.name);
zfree(rc.font_menuitem.name);
zfree(rc.font_osd.name);
zfree(rc.theme_name);
wlr_scene_rect_set_size(
wlr_scene_rect_from_node(item->normal.text),
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 (menuitem->type == LAB_MENU_TITLE) {
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) {
menuitem->height = theme->menu_separator_line_thickness +
2 * theme->menu_separator_padding_height;
/* Item background nodes */
float *bg_color = menuitem->type == LAB_MENU_TITLE
? 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.tree,
menu->size.width, menuitem->height, bg_color)->node;
menuitem->normal.text = &menuitem->normal.buffer->scene_buffer->node;
/* Font buffer */
scaled_font_buffer_update(menuitem->normal.buffer, label,
- menuitem->native_width, &rc.font_menuitem,
- theme->menu_items_text_color, bg_color, /* arrow */ NULL);
+ menuitem->native_width, &rc.font_menuheader,
+ text_color, bg_color, /* arrow */ NULL);
/* Center font nodes */
int x, y;
x = theme->menu_item_padding_x;
parse_hexstr("#000000", theme->window_active_label_text_color);
parse_hexstr("#000000", theme->window_inactive_label_text_color);
theme->window_label_text_justify = parse_justification("Center");
+ theme->menu_title_text_justify = parse_justification("Center");
theme->window_button_width = 26;
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_is_percent = false;
theme->osd_window_switcher_padding = 4;
if (match_glob(key, "menu.items.padding.y")) {
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")) {
theme->menu_overlap_x = atoi(value);
}
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")) {
parse_hexstr(value, theme->osd_bg_color);
}