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 *text;
|
||||||
char *icon_name;
|
char *icon_name;
|
||||||
const char *arrow;
|
const char *arrow;
|
||||||
char accelerator;
|
uint32_t accelerator;
|
||||||
struct menu *parent;
|
struct menu *parent;
|
||||||
struct menu *submenu;
|
struct menu *submenu;
|
||||||
bool selectable;
|
bool selectable;
|
||||||
|
|
@ -78,7 +78,7 @@ void menu_item_select_previous(void);
|
||||||
* Return: a boolean value that represents whether the newly selected item
|
* Return: a boolean value that represents whether the newly selected item
|
||||||
* needs to be executed.
|
* 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_enter(void);
|
||||||
void menu_submenu_leave(void);
|
void menu_submenu_leave(void);
|
||||||
|
|
|
||||||
|
|
@ -419,20 +419,6 @@ handle_change_vt_key(struct keyboard *keyboard,
|
||||||
return false;
|
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
|
static void
|
||||||
handle_menu_keys(struct keysyms *syms)
|
handle_menu_keys(struct keysyms *syms)
|
||||||
{
|
{
|
||||||
|
|
@ -454,15 +440,17 @@ handle_menu_keys(struct keysyms *syms)
|
||||||
break;
|
break;
|
||||||
case XKB_KEY_Return:
|
case XKB_KEY_Return:
|
||||||
case XKB_KEY_KP_Enter:
|
case XKB_KEY_KP_Enter:
|
||||||
menu_call_selected_actions();
|
if (!menu_call_selected_actions()) {
|
||||||
|
menu_submenu_enter();
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
case XKB_KEY_Escape:
|
case XKB_KEY_Escape:
|
||||||
menu_close_root();
|
menu_close_root();
|
||||||
cursor_update_focus();
|
cursor_update_focus();
|
||||||
break;
|
break;
|
||||||
default: {
|
default: {
|
||||||
char accelerator = keysym_to_char(syms->syms[i]);
|
uint32_t accelerator = xkb_keysym_to_utf32(syms->syms[i]);
|
||||||
if (accelerator == '\0') {
|
if (accelerator == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (menu_item_select_by_accelerator(accelerator)) {
|
if (menu_item_select_by_accelerator(accelerator)) {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,9 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
|
#include <uchar.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <wctype.h>
|
||||||
#include <wlr/types/wlr_scene.h>
|
#include <wlr/types/wlr_scene.h>
|
||||||
#include <wlr/types/wlr_xdg_shell.h>
|
#include <wlr/types/wlr_xdg_shell.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
|
|
@ -131,7 +133,7 @@ validate(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct menuitem *
|
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(menu);
|
||||||
assert(text);
|
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;
|
menuitem->arrow = show_arrow ? "›" : NULL;
|
||||||
|
|
||||||
const char *it = text;
|
const char *it = text;
|
||||||
/* Skip emojis and whitespace */
|
uint32_t accelerator = 0;
|
||||||
while (*it != '\0') {
|
|
||||||
unsigned char c = (unsigned char)*it;
|
|
||||||
|
|
||||||
if (isspace(c) || c > 127) {
|
|
||||||
it++;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
menuitem->accelerator = tolower(*it);
|
|
||||||
while (*it != '\0') {
|
while (*it != '\0') {
|
||||||
if (*it == '_') {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
it++;
|
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 HAVE_LIBSFDO
|
||||||
if (rc.menu_show_icons && !string_null_or_empty(icon_name)) {
|
if (rc.menu_show_icons && !string_null_or_empty(icon_name)) {
|
||||||
menuitem->icon_name = xstrdup(icon_name);
|
menuitem->icon_name = xstrdup(icon_name);
|
||||||
|
|
@ -1483,7 +1493,7 @@ menu_item_select_previous(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
menu_item_select_by_accelerator(char accelerator)
|
menu_item_select_by_accelerator(uint32_t accelerator)
|
||||||
{
|
{
|
||||||
struct menu *menu = get_selection_leaf();
|
struct menu *menu = get_selection_leaf();
|
||||||
if (!menu || wl_list_empty(&menu->menuitems)) {
|
if (!menu || wl_list_empty(&menu->menuitems)) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue