config: Add support for font slant and weight

This commit is contained in:
John Lindgren 2022-09-15 10:53:49 -04:00 committed by Johan Malm
parent 1fafb89cba
commit 07a83c19f0
12 changed files with 126 additions and 98 deletions

View file

@ -15,8 +15,8 @@ No configuration files are needed to start and run labwc.
In accordance with XDG Base Directory Specification, configuration files are In accordance with XDG Base Directory Specification, configuration files are
searched for in the following order: searched for in the following order:
- ${XDG_CONFIG_HOME:-$HOME/.config}/labwc - ${XDG_CONFIG_HOME:-$HOME/.config}/labwc
- ${XDG_CONFIG_DIRS:-/etc/xdg}/labwc - ${XDG_CONFIG_DIRS:-/etc/xdg}/labwc
All configuration and theme files except autostart are re-loaded on receiving All configuration and theme files except autostart are re-loaded on receiving
signal SIGHUP. signal SIGHUP.
@ -136,6 +136,12 @@ The rest of this man page describes configuration options.
*<theme><font place=""><size>* *<theme><font place=""><size>*
Font size in pixels. Default is 10. Font size in pixels. Default is 10.
*<theme><font place=""><slant>*
Font slant (normal or italic). Default is normal.
*<theme><font place=""><weight>*
Font weight (normal or bold). Default is normal.
## KEYBOARD ## KEYBOARD
*<keyboard><keybind key="">* *<keyboard><keybind key="">*
@ -231,10 +237,10 @@ The rest of this man page describes configuration options.
## LIBINPUT ## LIBINPUT
*<libinput><device category="">* *<libinput><device category="">*
Define a category of devices to use the configuration values that Define a category of devices to use the configuration values that
follow. The category can be set to touch (devices that define a width follow. The category can be set to touch (devices that define a width
and height), non-touch, default, or the name of a device. You can obtain and height), non-touch, default, or the name of a device. You can obtain
your devices name by running *libinput list-devices* (you may need to your devices name by running *libinput list-devices* (you may need to
be root or a part of the input group to perform this.) Any members of be root or a part of the input group to perform this.) Any members of
this category that are not set use the default for the device. With the this category that are not set use the default for the device. With the
exception of tap-to-click, which is enabled by default. exception of tap-to-click, which is enabled by default.
@ -252,9 +258,9 @@ The rest of this man page describes configuration options.
*<libinput><device category=""><accelProfile>* [flat|adaptive] *<libinput><device category=""><accelProfile>* [flat|adaptive]
Set the pointer's acceleration profile for this category. Flat applies Set the pointer's acceleration profile for this category. Flat applies
no acceleration (the pointers velocity is constant), while adaptive no acceleration (the pointers velocity is constant), while adaptive
changes the pointers speed based the actual speed of your mouse or changes the pointers speed based the actual speed of your mouse or
finger on your touchpad. finger on your touchpad.
*<libinput><device category=""><tap>* [yes|no] *<libinput><device category=""><tap>* [yes|no]
Enable or disable tap-to-click for this category. This is enabled by Enable or disable tap-to-click for this category. This is enabled by
@ -273,7 +279,7 @@ The rest of this man page describes configuration options.
*<libinput>device category=""><disableWhileTyping>* [yes|no] *<libinput>device category=""><disableWhileTyping>* [yes|no]
Enable or disable disable while typing for this category. DWT ignores Enable or disable disable while typing for this category. DWT ignores
any motion events while a keyboard is typing, and for a short while any motion events while a keyboard is typing, and for a short while
after as well. after as well.
## ENVIRONMENT VARIABLES ## ENVIRONMENT VARIABLES
@ -289,7 +295,7 @@ The following keyboard-configuration variables are supported:
*XKB_DEFAULT_RULES*, *XKB_DEFAULT_MODEL*, *XKB_DEFAULT_LAYOUT*, *XKB_DEFAULT_RULES*, *XKB_DEFAULT_MODEL*, *XKB_DEFAULT_LAYOUT*,
*XKB_DEFAULT_VARIANT* and *XKB_DEFAULT_OPTIONS*. *XKB_DEFAULT_VARIANT* and *XKB_DEFAULT_OPTIONS*.
See xkeyboard-config(7) for details. See xkeyboard-config(7) for details.
# SEE ALSO # SEE ALSO

View file

@ -19,9 +19,24 @@
<theme> <theme>
<name></name> <name></name>
<cornerRadius>8</cornerRadius> <cornerRadius>8</cornerRadius>
<font place="ActiveWindow"><name>sans</name><size>10</size></font> <font place="ActiveWindow">
<font place="MenuItem"><name>sans</name><size>10</size></font> <name>sans</name>
<font place="OSD"><name>sans</name><size>10</size></font> <size>10</size>
<slant>normal</slant>
<weight>normal</weight>
</font>
<font place="MenuItem">
<name>sans</name>
<size>10</size>
<slant>normal</slant>
<weight>normal</weight>
</font>
<font place="OSD">
<name>sans</name>
<size>10</size>
<slant>normal</slant>
<weight>normal</weight>
</font>
</theme> </theme>
<!-- edge strength is in pixels --> <!-- edge strength is in pixels -->

View file

@ -4,11 +4,25 @@
struct lab_data_buffer; struct lab_data_buffer;
enum font_slant {
FONT_SLANT_NORMAL,
FONT_SLANT_ITALIC
};
enum font_weight {
FONT_WEIGHT_NORMAL,
FONT_WEIGHT_BOLD
};
struct font { struct font {
char *name; char *name;
int size; int size;
enum font_slant slant;
enum font_weight weight;
}; };
struct _PangoFontDescription *font_to_pango_desc(struct font *font);
/** /**
* font_height - get font vertical extents * font_height - get font vertical extents
* @font: description of font including family name and size * @font: description of font including family name and size

View file

@ -7,6 +7,7 @@
#include <wayland-server-core.h> #include <wayland-server-core.h>
#include "common/buf.h" #include "common/buf.h"
#include "common/font.h"
#include "config/libinput.h" #include "config/libinput.h"
#include "theme.h" #include "theme.h"
@ -25,12 +26,9 @@ struct rcxml {
/* theme */ /* theme */
char *theme_name; char *theme_name;
int corner_radius; int corner_radius;
char *font_name_activewindow; struct font font_activewindow;
char *font_name_menuitem; struct font font_menuitem;
char *font_name_osd; struct font font_osd;
int font_size_activewindow;
int font_size_menuitem;
int font_size_osd;
/* Pointer to current theme */ /* Pointer to current theme */
struct theme *theme; struct theme *theme;

View file

@ -11,6 +11,21 @@
#include "labwc.h" #include "labwc.h"
#include "buffer.h" #include "buffer.h"
PangoFontDescription *
font_to_pango_desc(struct font *font)
{
PangoFontDescription *desc = pango_font_description_new();
pango_font_description_set_family(desc, font->name);
pango_font_description_set_size(desc, font->size * PANGO_SCALE);
if (font->slant == FONT_SLANT_ITALIC) {
pango_font_description_set_style(desc, PANGO_STYLE_ITALIC);
}
if (font->weight == FONT_WEIGHT_BOLD) {
pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD);
}
return desc;
}
static PangoRectangle static PangoRectangle
font_extents(struct font *font, const char *string) font_extents(struct font *font, const char *string)
{ {
@ -25,9 +40,7 @@ font_extents(struct font *font, const char *string)
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1); surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1);
c = cairo_create(surface); c = cairo_create(surface);
layout = pango_cairo_create_layout(c); layout = pango_cairo_create_layout(c);
PangoFontDescription *desc = pango_font_description_new(); PangoFontDescription *desc = font_to_pango_desc(font);
pango_font_description_set_family(desc, font->name);
pango_font_description_set_size(desc, font->size * PANGO_SCALE);
pango_layout_set_font_description(layout, desc); pango_layout_set_font_description(layout, desc);
pango_layout_set_text(layout, string, -1); pango_layout_set_text(layout, string, -1);
@ -108,9 +121,7 @@ font_buffer_create(struct lab_data_buffer **buffer, int max_width,
pango_layout_set_text(layout, text, -1); pango_layout_set_text(layout, text, -1);
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
PangoFontDescription *desc = pango_font_description_new(); PangoFontDescription *desc = font_to_pango_desc(font);
pango_font_description_set_family(desc, font->name);
pango_font_description_set_size(desc, font->size * PANGO_SCALE);
pango_layout_set_font_description(layout, desc); pango_layout_set_font_description(layout, desc);
pango_font_description_free(desc); pango_font_description_free(desc);
pango_cairo_update_layout(cairo, layout); pango_cairo_update_layout(cairo, layout);

View file

@ -86,6 +86,8 @@ scaled_font_buffer_update(struct scaled_font_buffer *self, const char *text,
self->font.name = strdup(font->name); self->font.name = strdup(font->name);
} }
self->font.size = font->size; self->font.size = font->size;
self->font.slant = font->slant;
self->font.weight = font->weight;
memcpy(self->color, color, sizeof(self->color)); memcpy(self->color, color, sizeof(self->color));
self->arrow = arrow ? strdup(arrow) : NULL; self->arrow = arrow ? strdup(arrow) : NULL;

View file

@ -236,6 +236,23 @@ fill_libinput_category(char *nodename, char *content)
} }
} }
static void
set_font_attr(struct font *font, const char *nodename, const char *content)
{
if (!strcmp(nodename, "name")) {
zfree(font->name);
font->name = strdup(content);
} 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;
} else if (!strcmp(nodename, "weight")) {
font->weight = !strcasecmp(content, "bold") ?
FONT_WEIGHT_BOLD : FONT_WEIGHT_NORMAL;
}
}
static void static void
fill_font(char *nodename, char *content, enum font_place place) fill_font(char *nodename, char *content, enum font_place place)
{ {
@ -250,36 +267,18 @@ fill_font(char *nodename, char *content, enum font_place place)
* If <theme><font></font></theme> is used without a place="" * If <theme><font></font></theme> is used without a place=""
* attribute, we set all font variables * attribute, we set all font variables
*/ */
if (!strcmp(nodename, "name")) { set_font_attr(&rc.font_activewindow, nodename, content);
rc.font_name_activewindow = strdup(content); set_font_attr(&rc.font_menuitem, nodename, content);
rc.font_name_menuitem = strdup(content); set_font_attr(&rc.font_osd, nodename, content);
rc.font_name_osd = strdup(content);
} else if (!strcmp(nodename, "size")) {
rc.font_size_activewindow = atoi(content);
rc.font_size_menuitem = atoi(content);
rc.font_size_osd = atoi(content);
}
break; break;
case FONT_PLACE_ACTIVEWINDOW: case FONT_PLACE_ACTIVEWINDOW:
if (!strcmp(nodename, "name")) { set_font_attr(&rc.font_activewindow, nodename, content);
rc.font_name_activewindow = strdup(content);
} else if (!strcmp(nodename, "size")) {
rc.font_size_activewindow = atoi(content);
}
break; break;
case FONT_PLACE_MENUITEM: case FONT_PLACE_MENUITEM:
if (!strcmp(nodename, "name")) { set_font_attr(&rc.font_menuitem, nodename, content);
rc.font_name_menuitem = strdup(content);
} else if (!strcmp(nodename, "size")) {
rc.font_size_menuitem = atoi(content);
}
break; break;
case FONT_PLACE_OSD: case FONT_PLACE_OSD:
if (!strcmp(nodename, "name")) { set_font_attr(&rc.font_osd, nodename, content);
rc.font_name_osd = strdup(content);
} else if (!strcmp(nodename, "size")) {
rc.font_size_osd = atoi(content);
}
break; break;
/* TODO: implement for all font places */ /* TODO: implement for all font places */
@ -368,6 +367,10 @@ entry(xmlNode *node, char *nodename, char *content)
fill_font(nodename, content, font_place); fill_font(nodename, content, font_place);
} else if (!strcmp(nodename, "size.font.theme")) { } else if (!strcmp(nodename, "size.font.theme")) {
fill_font(nodename, content, font_place); fill_font(nodename, content, font_place);
} else if (!strcmp(nodename, "slant.font.theme")) {
fill_font(nodename, content, font_place);
} else if (!strcmp(nodename, "weight.font.theme")) {
fill_font(nodename, content, font_place);
} else if (!strcasecmp(nodename, "followMouse.focus")) { } else if (!strcasecmp(nodename, "followMouse.focus")) {
rc.focus_follow_mouse = get_bool(content); rc.focus_follow_mouse = get_bool(content);
} else if (!strcasecmp(nodename, "raiseOnFocus.focus")) { } else if (!strcasecmp(nodename, "raiseOnFocus.focus")) {
@ -491,9 +494,9 @@ rcxml_init()
wl_list_init(&rc.libinput_categories); wl_list_init(&rc.libinput_categories);
rc.xdg_shell_server_side_deco = true; rc.xdg_shell_server_side_deco = true;
rc.corner_radius = 8; rc.corner_radius = 8;
rc.font_size_activewindow = 10; rc.font_activewindow.size = 10;
rc.font_size_menuitem = 10; rc.font_menuitem.size = 10;
rc.font_size_osd = 10; rc.font_osd.size = 10;
rc.doubleclick_time = 500; rc.doubleclick_time = 500;
rc.repeat_rate = 25; rc.repeat_rate = 25;
rc.repeat_delay = 600; rc.repeat_delay = 600;
@ -666,14 +669,14 @@ post_processing(void)
/* Replace all earlier mousebindings by later ones */ /* Replace all earlier mousebindings by later ones */
merge_mouse_bindings(); merge_mouse_bindings();
if (!rc.font_name_activewindow) { if (!rc.font_activewindow.name) {
rc.font_name_activewindow = strdup("sans"); rc.font_activewindow.name = strdup("sans");
} }
if (!rc.font_name_menuitem) { if (!rc.font_menuitem.name) {
rc.font_name_menuitem = strdup("sans"); rc.font_menuitem.name = strdup("sans");
} }
if (!rc.font_name_osd) { if (!rc.font_osd.name) {
rc.font_name_osd = strdup("sans"); rc.font_osd.name = strdup("sans");
} }
if (!wl_list_length(&rc.libinput_categories)) { if (!wl_list_length(&rc.libinput_categories)) {
/* So we still allow tap to click by default */ /* So we still allow tap to click by default */
@ -759,9 +762,9 @@ no_config:
void void
rcxml_finish(void) rcxml_finish(void)
{ {
zfree(rc.font_name_activewindow); zfree(rc.font_activewindow.name);
zfree(rc.font_name_menuitem); zfree(rc.font_menuitem.name);
zfree(rc.font_name_osd); zfree(rc.font_osd.name);
zfree(rc.theme_name); zfree(rc.theme_name);
struct keybind *k, *k_tmp; struct keybind *k, *k_tmp;

View file

@ -88,13 +88,10 @@ item_create(struct menu *menu, const char *text, bool show_arrow)
menuitem->selectable = true; menuitem->selectable = true;
struct server *server = menu->server; struct server *server = menu->server;
struct theme *theme = server->theme; struct theme *theme = server->theme;
struct font font = {
.name = rc.font_name_menuitem,
.size = rc.font_size_menuitem,
};
if (!menu->item_height) { if (!menu->item_height) {
menu->item_height = font_height(&font) + 2 * MENU_ITEM_PADDING_Y; menu->item_height = font_height(&rc.font_menuitem)
+ 2 * MENU_ITEM_PADDING_Y;
} }
menuitem->height = menu->item_height; menuitem->height = menu->item_height;
@ -139,9 +136,9 @@ item_create(struct menu *menu, const char *text, bool show_arrow)
/* Font buffers */ /* Font buffers */
const char *arrow = show_arrow ? "" : NULL; const char *arrow = show_arrow ? "" : NULL;
scaled_font_buffer_update(menuitem->normal.buffer, text, item_max_width, scaled_font_buffer_update(menuitem->normal.buffer, text, item_max_width,
&font, theme->menu_items_text_color, arrow); &rc.font_menuitem, theme->menu_items_text_color, arrow);
scaled_font_buffer_update(menuitem->selected.buffer, text, item_max_width, scaled_font_buffer_update(menuitem->selected.buffer, text, item_max_width,
&font, theme->menu_items_active_text_color, arrow); &rc.font_menuitem, theme->menu_items_active_text_color, arrow);
/* Center font nodes */ /* Center font nodes */
x = MENU_ITEM_PADDING_X; x = MENU_ITEM_PADDING_X;

View file

@ -304,13 +304,7 @@ osd_update(struct server *server)
(OSD_ITEM_WIDTH - 2 * OSD_ITEM_PADDING) * PANGO_SCALE); (OSD_ITEM_WIDTH - 2 * OSD_ITEM_PADDING) * PANGO_SCALE);
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
struct font font = { PangoFontDescription *desc = font_to_pango_desc(&rc.font_osd);
.name = rc.font_name_osd,
.size = rc.font_size_osd,
};
PangoFontDescription *desc = pango_font_description_new();
pango_font_description_set_family(desc, font.name);
pango_font_description_set_size(desc, font.size * PANGO_SCALE);
pango_layout_set_font_description(layout, desc); pango_layout_set_font_description(layout, desc);
PangoTabArray *tabs = pango_tab_array_new_with_positions(2, TRUE, PangoTabArray *tabs = pango_tab_array_new_with_positions(2, TRUE,
@ -323,19 +317,20 @@ osd_update(struct server *server)
y = OSD_BORDER_WIDTH; y = OSD_BORDER_WIDTH;
/* Center text entries on the y axis */ /* Center text entries on the y axis */
int y_offset = (OSD_ITEM_HEIGHT - font_height(&font)) / 2; int y_offset = (OSD_ITEM_HEIGHT - font_height(&rc.font_osd)) / 2;
y += y_offset; y += y_offset;
if (show_workspace) { if (show_workspace) {
/* Center workspace indicator on the x axis */ /* Center workspace indicator on the x axis */
int x = font_width(&font, server->workspace_current->name); int x = font_width(&rc.font_osd, server->workspace_current->name);
x = (OSD_ITEM_WIDTH - x) / 2; x = (OSD_ITEM_WIDTH - x) / 2;
cairo_move_to(cairo, x, y); cairo_move_to(cairo, x, y);
PangoWeight weight = pango_font_description_get_weight(desc);
pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD); pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD);
pango_layout_set_font_description(layout, desc); pango_layout_set_font_description(layout, desc);
pango_layout_set_text(layout, server->workspace_current->name, -1); pango_layout_set_text(layout, server->workspace_current->name, -1);
pango_cairo_show_layout(cairo, layout); pango_cairo_show_layout(cairo, layout);
pango_font_description_set_weight(desc, PANGO_WEIGHT_NORMAL); pango_font_description_set_weight(desc, weight);
pango_layout_set_font_description(layout, desc); pango_layout_set_font_description(layout, desc);
y += OSD_ITEM_HEIGHT; y += OSD_ITEM_HEIGHT;
} }

View file

@ -216,12 +216,6 @@ ssd_update_title(struct view *view)
struct ssd_state_title *state = &view->ssd.state.title; struct ssd_state_title *state = &view->ssd.state.title;
bool title_unchanged = state->text && !strcmp(title, state->text); bool title_unchanged = state->text && !strcmp(title, state->text);
/* TODO: Do we only have active window fonts? */
struct font font = {
.name = rc.font_name_activewindow,
.size = rc.font_size_activewindow,
};
float *text_color; float *text_color;
struct ssd_part *part; struct ssd_part *part;
struct ssd_sub_tree *subtree; struct ssd_sub_tree *subtree;
@ -261,8 +255,10 @@ ssd_update_title(struct view *view)
} }
if (part->buffer) { if (part->buffer) {
/* TODO: Do we only have active window fonts? */
scaled_font_buffer_update(part->buffer, title, scaled_font_buffer_update(part->buffer, title,
title_bg_width, &font, text_color, NULL); title_bg_width, &rc.font_activewindow,
text_color, NULL);
} }
/* And finally update the cache */ /* And finally update the cache */

View file

@ -473,11 +473,8 @@ create_corners(struct theme *theme)
static void static void
post_processing(struct theme *theme) post_processing(struct theme *theme)
{ {
struct font font = { theme->title_height = font_height(&rc.font_activewindow)
.name = rc.font_name_activewindow, + 2 * theme->padding_height;
.size = rc.font_size_activewindow,
};
theme->title_height = font_height(&font) + 2 * theme->padding_height;
if (rc.corner_radius >= theme->title_height) { if (rc.corner_radius >= theme->title_height) {
theme->title_height = rc.corner_radius + 1; theme->title_height = rc.corner_radius + 1;

View file

@ -57,16 +57,12 @@ _osd_update(struct server *server)
uint16_t padding = 2; uint16_t padding = 2;
uint16_t rect_height = 20; uint16_t rect_height = 20;
uint16_t rect_width = 20; uint16_t rect_width = 20;
struct font font = {
.name = rc.font_name_osd,
.size = rc.font_size_osd,
};
/* Dimensions */ /* Dimensions */
size_t workspace_count = wl_list_length(&server->workspaces); size_t workspace_count = wl_list_length(&server->workspaces);
uint16_t marker_width = workspace_count * (rect_width + padding) - padding; uint16_t marker_width = workspace_count * (rect_width + padding) - padding;
uint16_t width = margin * 2 + (marker_width < 200 ? 200 : marker_width); uint16_t width = margin * 2 + (marker_width < 200 ? 200 : marker_width);
uint16_t height = margin * 3 + rect_height + font_height(&font); uint16_t height = margin * 3 + rect_height + font_height(&rc.font_osd);
cairo_t *cairo; cairo_t *cairo;
cairo_surface_t *surface; cairo_surface_t *surface;
@ -113,13 +109,11 @@ _osd_update(struct server *server)
pango_layout_set_width(layout, (width - 2 * margin) * PANGO_SCALE); pango_layout_set_width(layout, (width - 2 * margin) * PANGO_SCALE);
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
PangoFontDescription *desc = pango_font_description_new(); PangoFontDescription *desc = font_to_pango_desc(&rc.font_osd);
pango_font_description_set_family(desc, font.name);
pango_font_description_set_size(desc, font.size * PANGO_SCALE);
pango_layout_set_font_description(layout, desc); pango_layout_set_font_description(layout, desc);
/* Center workspace indicator on the x axis */ /* Center workspace indicator on the x axis */
x = font_width(&font, server->workspace_current->name); x = font_width(&rc.font_osd, server->workspace_current->name);
x = (width - x) / 2; x = (width - x) / 2;
cairo_move_to(cairo, x, margin * 2 + rect_height); cairo_move_to(cairo, x, margin * 2 + rect_height);
//pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD); //pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD);