mirror of
https://github.com/labwc/labwc.git
synced 2026-04-17 06:46:28 -04:00
menu: allow for Unicode accelerators
This commit is contained in:
parent
cea22422d5
commit
1c646af144
3 changed files with 32 additions and 34 deletions
|
|
@ -23,7 +23,7 @@ struct menuitem {
|
|||
char *text;
|
||||
char *icon_name;
|
||||
const char *arrow;
|
||||
char accelerator;
|
||||
uint32_t accelerator;
|
||||
struct menu *parent;
|
||||
struct menu *submenu;
|
||||
bool selectable;
|
||||
|
|
@ -78,7 +78,7 @@ void menu_item_select_previous(void);
|
|||
* Return: a boolean value that represents whether the newly selected item
|
||||
* needs to be executed.
|
||||
*/
|
||||
bool menu_item_select_by_accelerator(char accelerator);
|
||||
bool menu_item_select_by_accelerator(uint32_t accelerator);
|
||||
|
||||
void menu_submenu_enter(void);
|
||||
void menu_submenu_leave(void);
|
||||
|
|
|
|||
|
|
@ -419,20 +419,6 @@ handle_change_vt_key(struct keyboard *keyboard,
|
|||
return false;
|
||||
}
|
||||
|
||||
static char
|
||||
keysym_to_char(uint32_t keysym)
|
||||
{
|
||||
if (keysym >= 0x0020 && keysym <= 0x00FF) {
|
||||
return (char)keysym;
|
||||
}
|
||||
|
||||
if (keysym >= XKB_KEY_KP_0 && keysym <= XKB_KEY_KP_9) {
|
||||
return (char)('0' + (keysym - XKB_KEY_KP_0));
|
||||
}
|
||||
|
||||
return '\0';
|
||||
}
|
||||
|
||||
static void
|
||||
handle_menu_keys(struct keysyms *syms)
|
||||
{
|
||||
|
|
@ -454,15 +440,17 @@ handle_menu_keys(struct keysyms *syms)
|
|||
break;
|
||||
case XKB_KEY_Return:
|
||||
case XKB_KEY_KP_Enter:
|
||||
menu_call_selected_actions();
|
||||
if (!menu_call_selected_actions()) {
|
||||
menu_submenu_enter();
|
||||
};
|
||||
break;
|
||||
case XKB_KEY_Escape:
|
||||
menu_close_root();
|
||||
cursor_update_focus();
|
||||
break;
|
||||
default: {
|
||||
char accelerator = keysym_to_char(syms->syms[i]);
|
||||
if (accelerator == '\0') {
|
||||
uint32_t accelerator = xkb_keysym_to_utf32(syms->syms[i]);
|
||||
if (accelerator == 0) {
|
||||
continue;
|
||||
}
|
||||
if (menu_item_select_by_accelerator(accelerator)) {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <uchar.h>
|
||||
#include <unistd.h>
|
||||
#include <wctype.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include <wlr/types/wlr_xdg_shell.h>
|
||||
#include <wlr/util/log.h>
|
||||
|
|
@ -131,7 +133,7 @@ validate(void)
|
|||
}
|
||||
|
||||
static struct menuitem *
|
||||
item_create(struct menu *menu, const char *text, const char *icon_name, bool show_arrow)
|
||||
item_create(struct menu *menu, char *text, const char *icon_name, bool show_arrow)
|
||||
{
|
||||
assert(menu);
|
||||
assert(text);
|
||||
|
|
@ -145,26 +147,34 @@ item_create(struct menu *menu, const char *text, const char *icon_name, bool sho
|
|||
menuitem->arrow = show_arrow ? "›" : NULL;
|
||||
|
||||
const char *it = text;
|
||||
/* Skip emojis and whitespace */
|
||||
while (*it != '\0') {
|
||||
unsigned char c = (unsigned char)*it;
|
||||
|
||||
if (isspace(c) || c > 127) {
|
||||
it++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
menuitem->accelerator = tolower(*it);
|
||||
uint32_t accelerator = 0;
|
||||
while (*it != '\0') {
|
||||
if (*it == '_') {
|
||||
menuitem->accelerator = tolower(*(it + 1));
|
||||
char32_t codepoint = 0;
|
||||
mbstate_t state = {0};
|
||||
size_t bytes = mbrtoc32(&codepoint, it + 1, MB_CUR_MAX, &state);
|
||||
if (bytes > 0 && bytes <= 4) {
|
||||
accelerator = (uint32_t)towlower((wint_t)codepoint);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
it++;
|
||||
}
|
||||
|
||||
/* Fallback to the first character of the label */
|
||||
if (accelerator == 0 && text[0] != '\0') {
|
||||
char32_t codepoint = 0;
|
||||
mbstate_t state = {0};
|
||||
|
||||
size_t bytes = mbrtoc32(&codepoint, text, MB_CUR_MAX, &state);
|
||||
if (bytes > 0 && bytes <= 4) {
|
||||
accelerator = (uint32_t)towlower((wint_t)codepoint);
|
||||
}
|
||||
}
|
||||
|
||||
menuitem->accelerator = accelerator;
|
||||
|
||||
#if HAVE_LIBSFDO
|
||||
if (rc.menu_show_icons && !string_null_or_empty(icon_name)) {
|
||||
menuitem->icon_name = xstrdup(icon_name);
|
||||
|
|
@ -1483,7 +1493,7 @@ menu_item_select_previous(void)
|
|||
}
|
||||
|
||||
bool
|
||||
menu_item_select_by_accelerator(char accelerator)
|
||||
menu_item_select_by_accelerator(uint32_t accelerator)
|
||||
{
|
||||
struct menu *menu = get_selection_leaf();
|
||||
if (!menu || wl_list_empty(&menu->menuitems)) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue