keyboard: Relax matching criteria on shift level

Clients behave differently when it comes to sending release events for keys,
so it's hard to rely on any one kind of behaviour.
pull/40/head
Andri Yngvason 2020-05-01 17:34:17 +00:00
parent 405268fc58
commit f5453ffe1e
1 changed files with 24 additions and 34 deletions

View File

@ -276,26 +276,30 @@ static void keyboard_apply_mods(struct keyboard* self, xkb_keycode_t code,
latched, locked, group); latched, locked, group);
} }
bool keyboard_symbol_is_mod(xkb_keysym_t symbol) static struct table_entry* match_level(struct keyboard* self,
struct table_entry* entry)
{ {
switch (symbol) { xkb_keysym_t symbol = entry->symbol;
case XKB_KEY_Shift_L:
case XKB_KEY_Shift_R: while (true) {
case XKB_KEY_Control_L: int layout, level;
case XKB_KEY_Caps_Lock:
case XKB_KEY_Shift_Lock: layout = xkb_state_key_get_layout(self->state, entry->code);
case XKB_KEY_Meta_L: level = xkb_state_key_get_level(self->state, entry->code, layout);
case XKB_KEY_Meta_R:
case XKB_KEY_Alt_L: if (entry->level == level)
case XKB_KEY_Alt_R: return entry;
case XKB_KEY_Super_L:
case XKB_KEY_Super_R: if (++entry >= &self->lookup_table[self->lookup_table_length] ||
case XKB_KEY_Hyper_L: entry->symbol != symbol)
case XKB_KEY_Hyper_R: break;
return true;
} }
return false; char name[256];
log_debug("Failed to match level on symbol: %s\n",
get_symbol_name(symbol, name, sizeof(name)));
return NULL;
} }
void keyboard_feed(struct keyboard* self, xkb_keysym_t symbol, bool is_pressed) void keyboard_feed(struct keyboard* self, xkb_keysym_t symbol, bool is_pressed)
@ -308,23 +312,9 @@ void keyboard_feed(struct keyboard* self, xkb_keysym_t symbol, bool is_pressed)
return; return;
} }
while (!keyboard_symbol_is_mod(symbol)) { struct table_entry* level_entry = match_level(self, entry);
int layout, level; if (level_entry)
entry = level_entry;
layout = xkb_state_key_get_layout(self->state, entry->code);
level = xkb_state_key_get_level(self->state, entry->code, layout);
if (entry->level == level)
break;
if (++entry >= &self->lookup_table[self->lookup_table_length] ||
entry->symbol != symbol) {
char name[256];
log_error("Failed to match level on symbol: %s\n",
get_symbol_name(symbol, name, sizeof(name)));
return;
}
}
bool was_pressed = intset_is_set(&self->key_state, entry->code); bool was_pressed = intset_is_set(&self->key_state, entry->code);
if (was_pressed == is_pressed) if (was_pressed == is_pressed)