Differentiate between raw and translated keysyms

This commit is contained in:
buffet 2020-08-27 20:48:15 +00:00
parent a736f0281b
commit 34f5f1fc37
4 changed files with 104 additions and 48 deletions

View file

@ -8,6 +8,8 @@
#ifndef KIWMI_INPUT_KEYBOARD_H #ifndef KIWMI_INPUT_KEYBOARD_H
#define KIWMI_INPUT_KEYBOARD_H #define KIWMI_INPUT_KEYBOARD_H
#include <stdint.h>
#include <wayland-server.h> #include <wayland-server.h>
#include <xkbcommon/xkbcommon.h> #include <xkbcommon/xkbcommon.h>
@ -27,8 +29,11 @@ struct kiwmi_keyboard {
}; };
struct kiwmi_keyboard_key_event { struct kiwmi_keyboard_key_event {
const xkb_keysym_t *syms; const xkb_keysym_t *raw_syms;
int nsyms; const xkb_keysym_t *translated_syms;
int raw_syms_len;
int translated_syms_len;
uint32_t keycode;
struct kiwmi_keyboard *keyboard; struct kiwmi_keyboard *keyboard;
bool handled; bool handled;
}; };

View file

@ -59,22 +59,34 @@ keyboard_key_notify(struct wl_listener *listener, void *data)
struct kiwmi_keyboard *keyboard = wl_container_of(listener, keyboard, key); struct kiwmi_keyboard *keyboard = wl_container_of(listener, keyboard, key);
struct kiwmi_server *server = keyboard->server; struct kiwmi_server *server = keyboard->server;
struct wlr_event_keyboard_key *event = data; struct wlr_event_keyboard_key *event = data;
struct wlr_input_device *device = keyboard->device;
uint32_t keycode = event->keycode + 8; uint32_t keycode = event->keycode + 8;
const xkb_keysym_t *syms;
int nsyms = xkb_state_key_get_syms( const xkb_keysym_t *raw_syms;
keyboard->device->keyboard->xkb_state, keycode, &syms); xkb_layout_index_t layout_index =
xkb_state_key_get_layout(device->keyboard->xkb_state, keycode);
int raw_syms_len = xkb_keymap_key_get_syms_by_level(
device->keyboard->keymap, keycode, layout_index, 0, &raw_syms);
const xkb_keysym_t *translated_syms;
int translated_syms_len = xkb_state_key_get_syms(
keyboard->device->keyboard->xkb_state, keycode, &translated_syms);
bool handled = false; bool handled = false;
if (event->state == WLR_KEY_PRESSED) { if (event->state == WLR_KEY_PRESSED) {
handled = switch_vt(syms, nsyms, server->backend); handled =
switch_vt(translated_syms, translated_syms_len, server->backend);
} }
if (!handled) { if (!handled) {
struct kiwmi_keyboard_key_event data = { struct kiwmi_keyboard_key_event data = {
.syms = syms, .raw_syms = raw_syms,
.nsyms = nsyms, .translated_syms = translated_syms,
.raw_syms_len = raw_syms_len,
.translated_syms_len = translated_syms_len,
.keycode = keycode,
.keyboard = keyboard, .keyboard = keyboard,
.handled = false, .handled = false,
}; };

View file

@ -7,6 +7,8 @@
#include "luak/kiwmi_keyboard.h" #include "luak/kiwmi_keyboard.h"
#include <stdint.h>
#include <lauxlib.h> #include <lauxlib.h>
#include <wayland-server.h> #include <wayland-server.h>
#include <wlr/types/wlr_input_device.h> #include <wlr/types/wlr_input_device.h>
@ -145,27 +147,19 @@ kiwmi_keyboard_on_destroy_notify(struct wl_listener *listener, void *data)
} }
} }
static void static bool
kiwmi_keyboard_on_key_down_or_up_notify( send_key_event(
struct wl_listener *listener, struct kiwmi_lua_callback *lc,
void *data) xkb_keysym_t sym,
uint32_t keycode,
struct kiwmi_keyboard *keyboard,
bool raw)
{ {
struct kiwmi_lua_callback *lc = wl_container_of(listener, lc, listener);
struct kiwmi_server *server = lc->server; struct kiwmi_server *server = lc->server;
lua_State *L = server->lua->L; lua_State *L = server->lua->L;
struct kiwmi_keyboard_key_event *event = data;
struct kiwmi_keyboard *keyboard = event->keyboard;
const xkb_keysym_t *syms = event->syms; static char keysym_name[64];
int nsyms = event->nsyms; size_t namelen = xkb_keysym_get_name(sym, keysym_name, sizeof(keysym_name));
char keysym_name[64];
for (int i = 0; i < nsyms; ++i) {
xkb_keysym_t sym = syms[i];
size_t namelen =
xkb_keysym_get_name(sym, keysym_name, sizeof(keysym_name));
namelen = namelen > sizeof(keysym_name) ? sizeof(keysym_name) : namelen; namelen = namelen > sizeof(keysym_name) ? sizeof(keysym_name) : namelen;
@ -176,25 +170,65 @@ kiwmi_keyboard_on_key_down_or_up_notify(
lua_pushlstring(L, keysym_name, namelen); lua_pushlstring(L, keysym_name, namelen);
lua_setfield(L, -2, "key"); lua_setfield(L, -2, "key");
lua_pushnumber(L, keycode);
lua_setfield(L, -2, "keycode");
lua_pushboolean(L, raw);
lua_setfield(L, -2, "raw");
lua_pushcfunction(L, luaK_kiwmi_keyboard_new); lua_pushcfunction(L, luaK_kiwmi_keyboard_new);
lua_pushlightuserdata(L, server->lua); lua_pushlightuserdata(L, server->lua);
lua_pushlightuserdata(L, keyboard); lua_pushlightuserdata(L, keyboard);
if (lua_pcall(L, 2, 1, 0)) { if (lua_pcall(L, 2, 1, 0)) {
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1)); wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
lua_pop(L, 1); lua_pop(L, 1);
return; return false;
} }
lua_setfield(L, -2, "keyboard"); lua_setfield(L, -2, "keyboard");
if (lua_pcall(L, 1, 1, 0)) { if (lua_pcall(L, 1, 1, 0)) {
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1)); wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
lua_pop(L, 1); lua_pop(L, 1);
return; return false;
} }
event->handled |= lua_toboolean(L, -1); bool handled = lua_toboolean(L, -1);
lua_pop(L, 1); lua_pop(L, 1);
return handled;
}
static void
kiwmi_keyboard_on_key_down_or_up_notify(
struct wl_listener *listener,
void *data)
{
struct kiwmi_lua_callback *lc = wl_container_of(listener, lc, listener);
struct kiwmi_keyboard_key_event *event = data;
struct kiwmi_keyboard *keyboard = event->keyboard;
const xkb_keysym_t *raw_syms = event->raw_syms;
int raw_syms_len = event->raw_syms_len;
const xkb_keysym_t *translated_syms = event->translated_syms;
int translated_syms_len = event->translated_syms_len;
uint32_t keycode = event->keycode;
bool handled = false;
for (int i = 0; i < translated_syms_len; ++i) {
xkb_keysym_t sym = translated_syms[i];
handled |= send_key_event(lc, sym, keycode, keyboard, false);
} }
if (!handled) {
for (int i = 0; i < raw_syms_len; ++i) {
xkb_keysym_t sym = raw_syms[i];
handled |= send_key_event(lc, sym, keycode, keyboard, true);
}
}
event->handled = handled;
} }
static int static int

View file

@ -139,7 +139,10 @@ Callback receives the keyboard.
#### key_down #### key_down
A key got pressed. A key got pressed.
Callback receives a table containing the `key` and the `keyboard`).
Callback receives a table containing the `key`, `keycode`, `raw`, and the `keyboard`.
This event gets triggered twice, once with mods applied (i.e. `Shift+3` is `#`) and `raw` set to `false`, and then again with no mods applied and `raw` set to `true`.
The callback is supposed to return `true` if the event was handled. The callback is supposed to return `true` if the event was handled.
The compositor will not forward it to the focused view in that case. The compositor will not forward it to the focused view in that case.
@ -147,7 +150,9 @@ The compositor will not forward it to the focused view in that case.
#### key_up #### key_up
A key got released. A key got released.
Callback receives a table containing the `key` and the `keyboard`). Callback receives a table containing the `key`, `keycode`, `raw`, and the `keyboard`.
This event gets triggered twice, once with mods applied (i.e. `Shift+3` is `#`) and `raw` set to `false`, and then again with no mods applied and `raw` set to `true`.
The callback is supposed to return `true` if the event was handled. The callback is supposed to return `true` if the event was handled.
The compositor will not forward it to the focused view in that case. The compositor will not forward it to the focused view in that case.