menu: underline explicitly defined accelerators

This commit is contained in:
Alex Chernika 2026-04-14 17:21:22 +02:00
parent 1c646af144
commit dc28d0caf3
No known key found for this signature in database
GPG key ID: 6029FAD8ABFB076A
4 changed files with 28 additions and 8 deletions

View file

@ -4,6 +4,7 @@
#include <cairo.h> #include <cairo.h>
#include <pango/pango-font.h> #include <pango/pango-font.h>
#include <stdbool.h>
struct lab_data_buffer; struct lab_data_buffer;
@ -43,10 +44,11 @@ void font_get_buffer_size(int max_width, const char *text, struct font *font,
* @font: font description * @font: font description
* @color: foreground color in rgba format * @color: foreground color in rgba format
* @bg_pattern: background pattern * @bg_pattern: background pattern
* @use_markup: flag to render pango markup
*/ */
void font_buffer_create(struct lab_data_buffer **buffer, int max_width, void font_buffer_create(struct lab_data_buffer **buffer, int max_width,
int height, const char *text, struct font *font, const float *color, int height, const char *text, struct font *font, const float *color,
cairo_pattern_t *bg_pattern, double scale); cairo_pattern_t *bg_pattern, double scale, bool use_markup);
/** /**
* font_finish - free some font related resources * font_finish - free some font related resources

View file

@ -79,7 +79,7 @@ font_get_buffer_size(int max_width, const char *text, struct font *font,
void void
font_buffer_create(struct lab_data_buffer **buffer, int max_width, font_buffer_create(struct lab_data_buffer **buffer, int max_width,
int height, const char *text, struct font *font, const float *color, int height, const char *text, struct font *font, const float *color,
cairo_pattern_t *bg_pattern, double scale) cairo_pattern_t *bg_pattern, double scale, bool use_markup)
{ {
if (string_null_or_empty(text)) { if (string_null_or_empty(text)) {
return; return;
@ -123,7 +123,7 @@ font_buffer_create(struct lab_data_buffer **buffer, int max_width,
PangoLayout *layout = pango_cairo_create_layout(cairo); PangoLayout *layout = pango_cairo_create_layout(cairo);
pango_context_set_round_glyph_positions(pango_layout_get_context(layout), false); pango_context_set_round_glyph_positions(pango_layout_get_context(layout), false);
pango_layout_set_width(layout, width * PANGO_SCALE); pango_layout_set_width(layout, width * PANGO_SCALE);
pango_layout_set_text(layout, text, -1); use_markup ? pango_layout_set_markup(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);
if (!opaque_bg) { if (!opaque_bg) {

View file

@ -143,18 +143,31 @@ item_create(struct menu *menu, char *text, const char *icon_name, bool show_arro
menuitem->parent = menu; menuitem->parent = menu;
menuitem->selectable = true; menuitem->selectable = true;
menuitem->type = LAB_MENU_ITEM; menuitem->type = LAB_MENU_ITEM;
menuitem->text = xstrdup(text);
menuitem->arrow = show_arrow ? "" : NULL; menuitem->arrow = show_arrow ? "" : NULL;
const char *it = text;
uint32_t accelerator = 0; uint32_t accelerator = 0;
char *new_text = NULL;
char *it = text;
while (*it != '\0') { while (*it != '\0') {
if (*it == '_') { if (*it == '_') {
char32_t codepoint = 0; char32_t codepoint = 0;
mbstate_t state = {0}; mbstate_t state = {0};
size_t bytes = mbrtoc32(&codepoint, it + 1, MB_CUR_MAX, &state); size_t bytes = mbrtoc32(&codepoint, it + 1,
MB_CUR_MAX, &state);
if (bytes > 0 && bytes <= 4) { if (bytes > 0 && bytes <= 4) {
accelerator = (uint32_t)towlower((wint_t)codepoint); accelerator =
(uint32_t)towlower((wint_t)codepoint);
}
if (*(it + 1) != '\0') {
int underscore_index = it - text;
new_text = malloc(strlen(text) + 8);
if (!new_text) {
break;
}
memcpy(new_text, text, underscore_index);
sprintf(new_text + underscore_index, "<u>%c</u>%s",
*(it + 1), it + 2);
} }
break; break;
@ -174,6 +187,11 @@ item_create(struct menu *menu, char *text, const char *icon_name, bool show_arro
} }
menuitem->accelerator = accelerator; menuitem->accelerator = accelerator;
if (new_text) {
menuitem->text = xstrdup(new_text);
} else {
menuitem->text = xstrdup(text);
}
#if HAVE_LIBSFDO #if HAVE_LIBSFDO
if (rc.menu_show_icons && !string_null_or_empty(icon_name)) { if (rc.menu_show_icons && !string_null_or_empty(icon_name)) {

View file

@ -26,7 +26,7 @@ _create_buffer(struct scaled_buffer *scaled_buffer, double scale)
/* Buffer gets free'd automatically along the backing wlr_buffer */ /* Buffer gets free'd automatically along the backing wlr_buffer */
font_buffer_create(&buffer, self->max_width, self->height, self->text, font_buffer_create(&buffer, self->max_width, self->height, self->text,
&self->font, self->color, bg_pattern, scale); &self->font, self->color, bg_pattern, scale, true);
if (!buffer) { if (!buffer) {
wlr_log(WLR_ERROR, "font_buffer_create() failed"); wlr_log(WLR_ERROR, "font_buffer_create() failed");