mirror of
https://github.com/kovidgoyal/kitty.git
synced 2024-09-20 19:19:41 +03:00
Extract key event data to struct
This commit is contained in:
parent
fb1c318a09
commit
53275c9137
@ -185,6 +185,12 @@ def generate_wrappers(glfw_header):
|
|||||||
p = src.find('*/', p)
|
p = src.find('*/', p)
|
||||||
preamble = src[p + 2:first]
|
preamble = src[p + 2:first]
|
||||||
header = '''\
|
header = '''\
|
||||||
|
//
|
||||||
|
// THIS FILE IS GENERATED BY glfw.py
|
||||||
|
//
|
||||||
|
// SAVE YOURSELF SOME TIME, DO NOT MANUALLY EDIT
|
||||||
|
//
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
35
glfw/glfw3.h
vendored
35
glfw/glfw3.h
vendored
@ -1177,6 +1177,29 @@ typedef struct GLFWwindow GLFWwindow;
|
|||||||
*/
|
*/
|
||||||
typedef struct GLFWcursor GLFWcursor;
|
typedef struct GLFWcursor GLFWcursor;
|
||||||
|
|
||||||
|
typedef struct GLFWkeyevent
|
||||||
|
{
|
||||||
|
// The [keyboard key](@ref keys) that was pressed or released.
|
||||||
|
int key;
|
||||||
|
|
||||||
|
// The system-specific scancode of the key.
|
||||||
|
int scancode;
|
||||||
|
|
||||||
|
// The event action. Either `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`.
|
||||||
|
int action;
|
||||||
|
|
||||||
|
// Bit field describing which [modifier keys](@ref mods) were held down.
|
||||||
|
int mods;
|
||||||
|
|
||||||
|
// UTF-8 encoded text generated by this key event or empty string.
|
||||||
|
const char *text;
|
||||||
|
|
||||||
|
// Used for Input Method events. Zero for normal key events.
|
||||||
|
// A value of 1 means the pre-edit text for the input event has been changed.
|
||||||
|
// A value of 2 means the text should be committed.
|
||||||
|
int ime_state;
|
||||||
|
} GLFWkeyevent;
|
||||||
|
|
||||||
/*! @brief The function signature for error callbacks.
|
/*! @brief The function signature for error callbacks.
|
||||||
*
|
*
|
||||||
* This is the function signature for error callback functions.
|
* This is the function signature for error callback functions.
|
||||||
@ -1462,15 +1485,7 @@ typedef void (* GLFWscrollfun)(GLFWwindow*,double,double,int);
|
|||||||
* the "s" key will generate text "o" and GLFW_KEY_O.
|
* the "s" key will generate text "o" and GLFW_KEY_O.
|
||||||
*
|
*
|
||||||
* @param[in] window The window that received the event.
|
* @param[in] window The window that received the event.
|
||||||
* @param[in] key The [keyboard key](@ref keys) that was pressed or released.
|
* @param[in] ev TODO: blablabla
|
||||||
* @param[in] scancode The system-specific scancode of the key.
|
|
||||||
* @param[in] action `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`.
|
|
||||||
* @param[in] mods Bit field describing which [modifier keys](@ref mods) were
|
|
||||||
* held down.
|
|
||||||
* @param[in] text UTF-8 encoded text generated by this key event or empty string.
|
|
||||||
* @param[in] status Used for Input Method events. Zero for normal key events.
|
|
||||||
* A value of 1 means the pre-edit text for the input event has been changed.
|
|
||||||
* A value of 2 means the text should be committed.
|
|
||||||
*
|
*
|
||||||
* @note On X11/Wayland if a modifier other than the modifiers GLFW reports
|
* @note On X11/Wayland if a modifier other than the modifiers GLFW reports
|
||||||
* (ctrl/shift/alt/super) is used, GLFW will report the shifted key rather
|
* (ctrl/shift/alt/super) is used, GLFW will report the shifted key rather
|
||||||
@ -1484,7 +1499,7 @@ typedef void (* GLFWscrollfun)(GLFWwindow*,double,double,int);
|
|||||||
*
|
*
|
||||||
* @ingroup input
|
* @ingroup input
|
||||||
*/
|
*/
|
||||||
typedef void (* GLFWkeyboardfun)(GLFWwindow*, int, int, int, int, const char*, int);
|
typedef void (* GLFWkeyboardfun)(GLFWwindow*, GLFWkeyevent*);
|
||||||
|
|
||||||
/*! @brief The function signature for file drop callbacks.
|
/*! @brief The function signature for file drop callbacks.
|
||||||
*
|
*
|
||||||
|
29
glfw/ibus_glfw.c
vendored
29
glfw/ibus_glfw.c
vendored
@ -107,10 +107,14 @@ get_ibus_text_from_message(DBusMessage *msg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
send_text(const char *text, int state) {
|
send_text(const char *text, int ime_state) {
|
||||||
_GLFWwindow *w = _glfwFocusedWindow();
|
_GLFWwindow *w = _glfwFocusedWindow();
|
||||||
if (w && w->callbacks.keyboard) {
|
if (w && w->callbacks.keyboard) {
|
||||||
w->callbacks.keyboard((GLFWwindow*) w, GLFW_KEY_UNKNOWN, 0, GLFW_PRESS, 0, text, state);
|
GLFWkeyevent fake_ev;
|
||||||
|
_glfwInitializeKeyEvent(&fake_ev, GLFW_KEY_UNKNOWN, 0, GLFW_PRESS, 0);
|
||||||
|
fake_ev.text = text;
|
||||||
|
fake_ev.ime_state = ime_state;
|
||||||
|
w->callbacks.keyboard((GLFWwindow*) w, &fake_ev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,31 +397,36 @@ ibus_key_state(unsigned int glfw_modifiers, int action) {
|
|||||||
void
|
void
|
||||||
key_event_processed(DBusMessage *msg, const char* errmsg, void *data) {
|
key_event_processed(DBusMessage *msg, const char* errmsg, void *data) {
|
||||||
uint32_t handled = 0;
|
uint32_t handled = 0;
|
||||||
KeyEvent *ev = (KeyEvent*)data;
|
_GLFWIBUSKeyEvent *ev = (_GLFWIBUSKeyEvent*)data;
|
||||||
bool is_release = ev->action == GLFW_RELEASE;
|
// Restore key's text from the text embedded in the structure.
|
||||||
|
ev->glfw_ev.text = ev->__embedded_text;
|
||||||
|
bool is_release = ev->glfw_ev.action == GLFW_RELEASE;
|
||||||
bool failed = false;
|
bool failed = false;
|
||||||
if (errmsg) {
|
if (errmsg) {
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR, "IBUS: Failed to process key with error: %s", errmsg);
|
_glfwInputError(GLFW_PLATFORM_ERROR, "IBUS: Failed to process key with error: %s", errmsg);
|
||||||
failed = true;
|
failed = true;
|
||||||
} else {
|
} else {
|
||||||
glfw_dbus_get_args(msg, "Failed to get IBUS handled key from reply", DBUS_TYPE_BOOLEAN, &handled, DBUS_TYPE_INVALID);
|
glfw_dbus_get_args(msg, "Failed to get IBUS handled key from reply", DBUS_TYPE_BOOLEAN, &handled, DBUS_TYPE_INVALID);
|
||||||
debug("IBUS processed scancode: 0x%x release: %d handled: %u\n", ev->keycode, is_release, handled);
|
debug("IBUS processed scancode: 0x%x release: %d handled: %u\n", ev->glfw_ev.scancode, is_release, handled);
|
||||||
}
|
}
|
||||||
glfw_xkb_key_from_ime(ev, handled ? true : false, failed);
|
glfw_xkb_key_from_ime(ev, handled ? true : false, failed);
|
||||||
free(ev);
|
free(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ibus_process_key(const KeyEvent *ev_, _GLFWIBUSData *ibus) {
|
ibus_process_key(const _GLFWIBUSKeyEvent *ev_, _GLFWIBUSData *ibus) {
|
||||||
if (!check_connection(ibus)) return false;
|
if (!check_connection(ibus)) return false;
|
||||||
KeyEvent *ev = malloc(sizeof(KeyEvent));
|
_GLFWIBUSKeyEvent *ev = malloc(sizeof(_GLFWIBUSKeyEvent));
|
||||||
if (!ev) return false;
|
if (!ev) return false;
|
||||||
memcpy(ev, ev_, sizeof(KeyEvent));
|
memcpy(ev, ev_, sizeof(_GLFWIBUSKeyEvent));
|
||||||
uint32_t state = ibus_key_state(ev->glfw_modifiers, ev->action);
|
// Put the key's text in a field IN the structure, for proper serialization.
|
||||||
|
memcpy(ev->__embedded_text, ev->glfw_ev.text, sizeof(ev->__embedded_text));
|
||||||
|
ev->glfw_ev.text = NULL;
|
||||||
|
uint32_t state = ibus_key_state(ev->glfw_ev.mods, ev->glfw_ev.action);
|
||||||
if (!glfw_dbus_call_method_with_reply(
|
if (!glfw_dbus_call_method_with_reply(
|
||||||
ibus->conn, IBUS_SERVICE, ibus->input_ctx_path, IBUS_INPUT_INTERFACE, "ProcessKeyEvent",
|
ibus->conn, IBUS_SERVICE, ibus->input_ctx_path, IBUS_INPUT_INTERFACE, "ProcessKeyEvent",
|
||||||
3000, key_event_processed, ev,
|
3000, key_event_processed, ev,
|
||||||
DBUS_TYPE_UINT32, &ev->ibus_sym, DBUS_TYPE_UINT32, &ev->ibus_keycode, DBUS_TYPE_UINT32,
|
DBUS_TYPE_UINT32, &ev->ibus_keysym, DBUS_TYPE_UINT32, &ev->ibus_keycode, DBUS_TYPE_UINT32,
|
||||||
&state, DBUS_TYPE_INVALID)) {
|
&state, DBUS_TYPE_INVALID)) {
|
||||||
free(ev);
|
free(ev);
|
||||||
return false;
|
return false;
|
||||||
|
15
glfw/ibus_glfw.h
vendored
15
glfw/ibus_glfw.h
vendored
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
#include "dbus_glfw.h"
|
#include "dbus_glfw.h"
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
|
||||||
@ -38,18 +39,16 @@ typedef struct {
|
|||||||
} _GLFWIBUSData;
|
} _GLFWIBUSData;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
xkb_keycode_t keycode, ibus_keycode;
|
xkb_keycode_t ibus_keycode;
|
||||||
xkb_keysym_t keysym, ibus_sym;
|
xkb_keysym_t ibus_keysym;
|
||||||
unsigned int glfw_modifiers;
|
|
||||||
int action;
|
|
||||||
GLFWid window_id;
|
GLFWid window_id;
|
||||||
int glfw_keycode;
|
GLFWkeyevent glfw_ev;
|
||||||
char text[64];
|
char __embedded_text[64];
|
||||||
} KeyEvent;
|
} _GLFWIBUSKeyEvent;
|
||||||
|
|
||||||
void glfw_connect_to_ibus(_GLFWIBUSData *ibus);
|
void glfw_connect_to_ibus(_GLFWIBUSData *ibus);
|
||||||
void glfw_ibus_terminate(_GLFWIBUSData *ibus);
|
void glfw_ibus_terminate(_GLFWIBUSData *ibus);
|
||||||
void glfw_ibus_set_focused(_GLFWIBUSData *ibus, bool focused);
|
void glfw_ibus_set_focused(_GLFWIBUSData *ibus, bool focused);
|
||||||
void glfw_ibus_dispatch(_GLFWIBUSData *ibus);
|
void glfw_ibus_dispatch(_GLFWIBUSData *ibus);
|
||||||
bool ibus_process_key(const KeyEvent *ev_, _GLFWIBUSData *ibus);
|
bool ibus_process_key(const _GLFWIBUSKeyEvent *ev_, _GLFWIBUSData *ibus);
|
||||||
void glfw_ibus_set_cursor_geometry(_GLFWIBUSData *ibus, int x, int y, int w, int h);
|
void glfw_ibus_set_cursor_geometry(_GLFWIBUSData *ibus, int x, int y, int w, int h);
|
||||||
|
31
glfw/input.c
vendored
31
glfw/input.c
vendored
@ -256,33 +256,44 @@ static bool parseMapping(_GLFWmapping* mapping, const char* string)
|
|||||||
////// GLFW event API //////
|
////// GLFW event API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void _glfwInitializeKeyEvent(GLFWkeyevent *ev, int key, int scancode, int action, int mods)
|
||||||
|
{
|
||||||
|
ev->key = key;
|
||||||
|
ev->scancode = scancode;
|
||||||
|
ev->action = action;
|
||||||
|
ev->mods = mods;
|
||||||
|
ev->text = "";
|
||||||
|
ev->ime_state = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Notifies shared code of a physical key event
|
// Notifies shared code of a physical key event
|
||||||
//
|
//
|
||||||
void _glfwInputKeyboard(_GLFWwindow* window, int key, int scancode, int action, int mods, const char* text, int state)
|
void _glfwInputKeyboard(_GLFWwindow* window, GLFWkeyevent* ev)
|
||||||
{
|
{
|
||||||
if (key >= 0 && key <= GLFW_KEY_LAST)
|
if (ev->key >= 0 && ev->key <= GLFW_KEY_LAST)
|
||||||
{
|
{
|
||||||
bool repeated = false;
|
bool repeated = false;
|
||||||
|
|
||||||
if (action == GLFW_RELEASE && window->keys[key] == GLFW_RELEASE)
|
if (ev->action == GLFW_RELEASE && window->keys[ev->key] == GLFW_RELEASE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (action == GLFW_PRESS && window->keys[key] == GLFW_PRESS)
|
if (ev->action == GLFW_PRESS && window->keys[ev->key] == GLFW_PRESS)
|
||||||
repeated = true;
|
repeated = true;
|
||||||
|
|
||||||
if (action == GLFW_RELEASE && window->stickyKeys)
|
if (ev->action == GLFW_RELEASE && window->stickyKeys)
|
||||||
window->keys[key] = _GLFW_STICK;
|
window->keys[ev->key] = _GLFW_STICK;
|
||||||
else
|
else
|
||||||
window->keys[key] = (char) action;
|
window->keys[ev->key] = (char) ev->action;
|
||||||
|
|
||||||
if (repeated)
|
if (repeated)
|
||||||
action = GLFW_REPEAT;
|
ev->action = GLFW_REPEAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// FIXME: will need to update ev->virtual_mods here too?
|
||||||
if (window->callbacks.keyboard) {
|
if (window->callbacks.keyboard) {
|
||||||
if (!window->lockKeyMods) mods &= ~(GLFW_MOD_CAPS_LOCK | GLFW_MOD_NUM_LOCK);
|
if (!window->lockKeyMods) ev->mods &= ~(GLFW_MOD_CAPS_LOCK | GLFW_MOD_NUM_LOCK);
|
||||||
window->callbacks.keyboard((GLFWwindow*) window, key, scancode, action, mods, text, state);
|
window->callbacks.keyboard((GLFWwindow*) window, ev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
3
glfw/internal.h
vendored
3
glfw/internal.h
vendored
@ -756,7 +756,8 @@ void _glfwInputWindowDamage(_GLFWwindow* window);
|
|||||||
void _glfwInputWindowCloseRequest(_GLFWwindow* window);
|
void _glfwInputWindowCloseRequest(_GLFWwindow* window);
|
||||||
void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor);
|
void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor);
|
||||||
|
|
||||||
void _glfwInputKeyboard(_GLFWwindow* window, int key, int scancode, int action, int mods, const char* text, int state);
|
void _glfwInitializeKeyEvent(GLFWkeyevent *ev, int key, int scancode, int action, int mods);
|
||||||
|
void _glfwInputKeyboard(_GLFWwindow *window, GLFWkeyevent *ev);
|
||||||
void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset, int flags);
|
void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset, int flags);
|
||||||
void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods);
|
void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods);
|
||||||
void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos);
|
void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos);
|
||||||
|
4
glfw/window.c
vendored
4
glfw/window.c
vendored
@ -57,7 +57,9 @@ void _glfwInputWindowFocus(_GLFWwindow* window, bool focused)
|
|||||||
if (window->keys[key] == GLFW_PRESS)
|
if (window->keys[key] == GLFW_PRESS)
|
||||||
{
|
{
|
||||||
const int scancode = _glfwPlatformGetKeyScancode(key);
|
const int scancode = _glfwPlatformGetKeyScancode(key);
|
||||||
_glfwInputKeyboard(window, key, scancode, GLFW_RELEASE, 0, "", 0);
|
GLFWkeyevent ev;
|
||||||
|
_glfwInitializeKeyEvent(&ev, key, scancode, GLFW_RELEASE, 0);
|
||||||
|
_glfwInputKeyboard(window, &ev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
100
glfw/xkb_glfw.c
vendored
100
glfw/xkb_glfw.c
vendored
@ -445,16 +445,14 @@ glfw_xkb_should_repeat(_GLFWXKBData *xkb, xkb_keycode_t scancode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static KeyEvent key_event = {0};
|
|
||||||
|
|
||||||
static inline xkb_keysym_t
|
static inline xkb_keysym_t
|
||||||
compose_symbol(struct xkb_compose_state *composeState, xkb_keysym_t sym, int *compose_completed) {
|
compose_symbol(struct xkb_compose_state *composeState, xkb_keysym_t sym, int *compose_completed, char *key_text, int n) {
|
||||||
*compose_completed = 0;
|
*compose_completed = 0;
|
||||||
if (sym == XKB_KEY_NoSymbol || !composeState) return sym;
|
if (sym == XKB_KEY_NoSymbol || !composeState) return sym;
|
||||||
if (xkb_compose_state_feed(composeState, sym) != XKB_COMPOSE_FEED_ACCEPTED) return sym;
|
if (xkb_compose_state_feed(composeState, sym) != XKB_COMPOSE_FEED_ACCEPTED) return sym;
|
||||||
switch (xkb_compose_state_get_status(composeState)) {
|
switch (xkb_compose_state_get_status(composeState)) {
|
||||||
case XKB_COMPOSE_COMPOSED:
|
case XKB_COMPOSE_COMPOSED:
|
||||||
xkb_compose_state_get_utf8(composeState, key_event.text, sizeof(key_event.text));
|
xkb_compose_state_get_utf8(composeState, key_text, n);
|
||||||
*compose_completed = 1;
|
*compose_completed = 1;
|
||||||
return xkb_compose_state_get_one_sym(composeState);
|
return xkb_compose_state_get_one_sym(composeState);
|
||||||
case XKB_COMPOSE_COMPOSING:
|
case XKB_COMPOSE_COMPOSING:
|
||||||
@ -534,11 +532,14 @@ glfw_xkb_update_ime_state(_GLFWwindow *w, _GLFWXKBData *xkb, int which, int a, i
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
glfw_xkb_key_from_ime(KeyEvent *ev, bool handled_by_ime, bool failed) {
|
glfw_xkb_key_from_ime(_GLFWIBUSKeyEvent *ev, bool handled_by_ime, bool failed) {
|
||||||
_GLFWwindow *window = _glfwWindowForId(ev->window_id);
|
_GLFWwindow *window = _glfwWindowForId(ev->window_id);
|
||||||
if (failed && window && window->callbacks.keyboard) {
|
if (failed && window && window->callbacks.keyboard) {
|
||||||
// notify application to remove any existing pre-edit text
|
// notify application to remove any existing pre-edit text
|
||||||
window->callbacks.keyboard((GLFWwindow*) window, GLFW_KEY_UNKNOWN, 0, GLFW_PRESS, 0, "", 1);
|
GLFWkeyevent fake_ev;
|
||||||
|
_glfwInitializeKeyEvent(&fake_ev, GLFW_KEY_UNKNOWN, 0, GLFW_PRESS, 0);
|
||||||
|
fake_ev.ime_state = 1;
|
||||||
|
window->callbacks.keyboard((GLFWwindow*) window, &fake_ev);
|
||||||
}
|
}
|
||||||
static xkb_keycode_t last_handled_press_keycode = 0;
|
static xkb_keycode_t last_handled_press_keycode = 0;
|
||||||
// We filter out release events that correspond to the last press event
|
// We filter out release events that correspond to the last press event
|
||||||
@ -547,53 +548,58 @@ glfw_xkb_key_from_ime(KeyEvent *ev, bool handled_by_ime, bool failed) {
|
|||||||
// you'd need to implement a ring buffer to store pending key presses.
|
// you'd need to implement a ring buffer to store pending key presses.
|
||||||
xkb_keycode_t prev_handled_press = last_handled_press_keycode;
|
xkb_keycode_t prev_handled_press = last_handled_press_keycode;
|
||||||
last_handled_press_keycode = 0;
|
last_handled_press_keycode = 0;
|
||||||
bool is_release = ev->action == GLFW_RELEASE;
|
bool is_release = ev->glfw_ev.action == GLFW_RELEASE;
|
||||||
debug("From IBUS: scancode: 0x%x name: %s is_release: %d\n", ev->keycode, glfw_xkb_keysym_name(ev->keysym), is_release);
|
debug("From IBUS: scancode: 0x%x name: %s is_release: %d\n", ev->glfw_ev.scancode, glfw_xkb_keysym_name(ev->glfw_ev.key), is_release);
|
||||||
if (window && !handled_by_ime && !(is_release && ev->keycode == prev_handled_press)) {
|
if (window && !handled_by_ime && !(is_release && ev->glfw_ev.scancode == (int) prev_handled_press)) {
|
||||||
debug("↳ to application: glfw_keycode: 0x%x (%s) keysym: 0x%x (%s) action: %s %s text: %s\n",
|
debug("↳ to application: glfw_keycode: 0x%x (%s) keysym: 0x%x (%s) action: %s %s text: %s\n",
|
||||||
ev->glfw_keycode, _glfwGetKeyName(ev->glfw_keycode), ev->keysym, glfw_xkb_keysym_name(ev->keysym),
|
ev->glfw_ev.scancode, _glfwGetKeyName(ev->glfw_ev.scancode), ev->glfw_ev.key, glfw_xkb_keysym_name(ev->glfw_ev.key),
|
||||||
(ev->action == GLFW_RELEASE ? "RELEASE" : (ev->action == GLFW_PRESS ? "PRESS" : "REPEAT")),
|
(ev->glfw_ev.action == GLFW_RELEASE ? "RELEASE" : (ev->glfw_ev.action == GLFW_PRESS ? "PRESS" : "REPEAT")),
|
||||||
format_mods(ev->glfw_modifiers), ev->text
|
format_mods(ev->glfw_ev.mods), ev->glfw_ev.text
|
||||||
);
|
);
|
||||||
_glfwInputKeyboard(window, ev->glfw_keycode, ev->keysym, ev->action, ev->glfw_modifiers, ev->text, 0);
|
|
||||||
|
ev->glfw_ev.ime_state = 0;
|
||||||
|
_glfwInputKeyboard(window, &ev->glfw_ev);
|
||||||
} else debug("↳ discarded\n");
|
} else debug("↳ discarded\n");
|
||||||
if (!is_release && handled_by_ime) last_handled_press_keycode = ev->keycode;
|
if (!is_release && handled_by_ime) last_handled_press_keycode = ev->glfw_ev.scancode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char key_text[64] = {0};
|
||||||
|
|
||||||
void
|
void
|
||||||
glfw_xkb_handle_key_event(_GLFWwindow *window, _GLFWXKBData *xkb, xkb_keycode_t scancode, int action) {
|
glfw_xkb_handle_key_event(_GLFWwindow *window, _GLFWXKBData *xkb, xkb_keycode_t scancode, int action) {
|
||||||
const xkb_keysym_t *syms, *clean_syms, *default_syms;
|
const xkb_keysym_t *syms, *clean_syms, *default_syms;
|
||||||
xkb_keysym_t glfw_sym;
|
xkb_keysym_t xkb_sym;
|
||||||
xkb_keycode_t code_for_sym = scancode;
|
xkb_keycode_t code_for_sym = scancode, ibus_keycode = scancode;
|
||||||
key_event.ibus_keycode = scancode;
|
GLFWkeyevent glfw_ev;
|
||||||
|
_glfwInitializeKeyEvent(&glfw_ev, GLFW_KEY_UNKNOWN, 0, GLFW_PRESS, 0); // init with default values
|
||||||
#ifdef _GLFW_WAYLAND
|
#ifdef _GLFW_WAYLAND
|
||||||
code_for_sym += 8;
|
code_for_sym += 8;
|
||||||
#else
|
#else
|
||||||
key_event.ibus_keycode -= 8;
|
ibus_keycode -= 8;
|
||||||
#endif
|
#endif
|
||||||
debug("%s scancode: 0x%x ", action == GLFW_RELEASE ? "Release" : "Press", scancode);
|
debug("%s scancode: 0x%x ", action == GLFW_RELEASE ? "Release" : "Press", scancode);
|
||||||
XKBStateGroup *sg = &xkb->states;
|
XKBStateGroup *sg = &xkb->states;
|
||||||
int num_syms = xkb_state_key_get_syms(sg->state, code_for_sym, &syms);
|
int num_syms = xkb_state_key_get_syms(sg->state, code_for_sym, &syms);
|
||||||
int num_clean_syms = xkb_state_key_get_syms(sg->clean_state, code_for_sym, &clean_syms);
|
int num_clean_syms = xkb_state_key_get_syms(sg->clean_state, code_for_sym, &clean_syms);
|
||||||
key_event.text[0] = 0;
|
key_text[0] = 0;
|
||||||
// According to the documentation of xkb_compose_state_feed it does not
|
// According to the documentation of xkb_compose_state_feed it does not
|
||||||
// support multi-sym events, so we ignore them
|
// support multi-sym events, so we ignore them
|
||||||
if (num_syms != 1 || num_clean_syms != 1) {
|
if (num_syms != 1 || num_clean_syms != 1) {
|
||||||
debug("num_syms: %d num_clean_syms: %d ignoring event\n", num_syms, num_clean_syms);
|
debug("num_syms: %d num_clean_syms: %d ignoring event\n", num_syms, num_clean_syms);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
glfw_sym = clean_syms[0];
|
xkb_sym = clean_syms[0];
|
||||||
debug("clean_sym: %s ", glfw_xkb_keysym_name(clean_syms[0]));
|
debug("clean_sym: %s ", glfw_xkb_keysym_name(clean_syms[0]));
|
||||||
if (action == GLFW_PRESS || action == GLFW_REPEAT) {
|
if (action == GLFW_PRESS || action == GLFW_REPEAT) {
|
||||||
const char *text_type = "composed_text";
|
const char *text_type = "composed_text";
|
||||||
int compose_completed;
|
int compose_completed;
|
||||||
glfw_sym = compose_symbol(sg->composeState, syms[0], &compose_completed);
|
xkb_sym = compose_symbol(sg->composeState, syms[0], &compose_completed, key_text, sizeof(key_text));
|
||||||
if (glfw_sym == XKB_KEY_NoSymbol && !compose_completed) {
|
if (xkb_sym == XKB_KEY_NoSymbol && !compose_completed) {
|
||||||
debug("compose not complete, ignoring.\n");
|
debug("compose not complete, ignoring.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
debug("composed_sym: %s ", glfw_xkb_keysym_name(glfw_sym));
|
debug("composed_sym: %s ", glfw_xkb_keysym_name(xkb_sym));
|
||||||
if (glfw_sym == syms[0]) { // composed sym is the same as non-composed sym
|
if (xkb_sym == syms[0]) { // composed sym is the same as non-composed sym
|
||||||
// Only use the clean_sym if no mods other than the mods we report
|
// Only use the clean_sym if no mods other than the mods we report
|
||||||
// are active (for example if ISO_Shift_Level_* mods are active
|
// are active (for example if ISO_Shift_Level_* mods are active
|
||||||
// they are not reported by GLFW so the key should be the shifted
|
// they are not reported by GLFW so the key should be the shifted
|
||||||
@ -601,37 +607,49 @@ glfw_xkb_handle_key_event(_GLFWwindow *window, _GLFWXKBData *xkb, xkb_keycode_t
|
|||||||
xkb_mod_mask_t consumed_unknown_mods = xkb_state_key_get_consumed_mods(sg->state, code_for_sym) & sg->activeUnknownModifiers;
|
xkb_mod_mask_t consumed_unknown_mods = xkb_state_key_get_consumed_mods(sg->state, code_for_sym) & sg->activeUnknownModifiers;
|
||||||
if (sg->activeUnknownModifiers) debug("%s", format_xkb_mods(xkb, "active_unknown_mods", sg->activeUnknownModifiers));
|
if (sg->activeUnknownModifiers) debug("%s", format_xkb_mods(xkb, "active_unknown_mods", sg->activeUnknownModifiers));
|
||||||
if (consumed_unknown_mods) { debug("%s", format_xkb_mods(xkb, "consumed_unknown_mods", consumed_unknown_mods)); }
|
if (consumed_unknown_mods) { debug("%s", format_xkb_mods(xkb, "consumed_unknown_mods", consumed_unknown_mods)); }
|
||||||
else glfw_sym = clean_syms[0];
|
else xkb_sym = clean_syms[0];
|
||||||
// xkb returns text even if alt and/or super are pressed
|
// xkb returns text even if alt and/or super are pressed
|
||||||
if ( ((GLFW_MOD_CONTROL | GLFW_MOD_ALT | GLFW_MOD_SUPER) & sg->modifiers) == 0) xkb_state_key_get_utf8(sg->state, code_for_sym, key_event.text, sizeof(key_event.text));
|
if ( ((GLFW_MOD_CONTROL | GLFW_MOD_ALT | GLFW_MOD_SUPER) & sg->modifiers) == 0) {
|
||||||
|
xkb_state_key_get_utf8(sg->state, code_for_sym, key_text, sizeof(key_text));
|
||||||
|
}
|
||||||
text_type = "text";
|
text_type = "text";
|
||||||
}
|
}
|
||||||
if ((1 <= key_event.text[0] && key_event.text[0] <= 31) || key_event.text[0] == 127) key_event.text[0] = 0; // don't send text for ascii control codes
|
if ((1 <= key_text[0] && key_text[0] <= 31) || key_text[0] == 127) {
|
||||||
if (key_event.text[0]) { debug("%s: %s ", text_type, key_event.text); }
|
key_text[0] = 0; // don't send text for ascii control codes
|
||||||
|
}
|
||||||
|
if (key_text[0]) { debug("%s: %s ", text_type, key_text); }
|
||||||
}
|
}
|
||||||
int glfw_keycode = glfw_key_for_sym(glfw_sym);
|
int glfw_sym = glfw_key_for_sym(xkb_sym);
|
||||||
bool is_fallback = false;
|
bool is_fallback = false;
|
||||||
if (glfw_keycode == GLFW_KEY_UNKNOWN && !key_event.text[0]) {
|
if (glfw_sym == GLFW_KEY_UNKNOWN && !key_text[0]) {
|
||||||
int num_default_syms = xkb_state_key_get_syms(sg->default_state, code_for_sym, &default_syms);
|
int num_default_syms = xkb_state_key_get_syms(sg->default_state, code_for_sym, &default_syms);
|
||||||
if (num_default_syms > 0) {
|
if (num_default_syms > 0) {
|
||||||
glfw_sym = default_syms[0];
|
xkb_sym = default_syms[0];
|
||||||
glfw_keycode = glfw_key_for_sym(glfw_sym);
|
glfw_sym = glfw_key_for_sym(xkb_sym);
|
||||||
is_fallback = true;
|
is_fallback = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
debug(
|
debug(
|
||||||
"%s%s: %d (%s) xkb_key: %d (%s)\n",
|
"%s%s: %d (%s) xkb_key: %d (%s)\n",
|
||||||
format_mods(sg->modifiers),
|
format_mods(sg->modifiers),
|
||||||
is_fallback ? "glfw_fallback_key" : "glfw_key", glfw_keycode, _glfwGetKeyName(glfw_keycode),
|
is_fallback ? "glfw_fallback_key" : "glfw_key", glfw_sym, _glfwGetKeyName(glfw_sym),
|
||||||
glfw_sym, glfw_xkb_keysym_name(glfw_sym)
|
xkb_sym, glfw_xkb_keysym_name(xkb_sym)
|
||||||
);
|
);
|
||||||
key_event.action = action; key_event.glfw_modifiers = sg->modifiers;
|
|
||||||
key_event.keycode = scancode; key_event.keysym = glfw_sym;
|
glfw_ev.action = action;
|
||||||
key_event.window_id = window->id; key_event.glfw_keycode = glfw_keycode;
|
glfw_ev.scancode = xkb_sym;
|
||||||
key_event.ibus_sym = syms[0];
|
glfw_ev.key = glfw_sym;
|
||||||
if (ibus_process_key(&key_event, &xkb->ibus)) {
|
glfw_ev.mods = sg->modifiers;
|
||||||
debug("↳ to IBUS: keycode: 0x%x keysym: 0x%x (%s) %s\n", key_event.ibus_keycode, key_event.ibus_sym, glfw_xkb_keysym_name(key_event.ibus_sym), format_mods(key_event.glfw_modifiers));
|
glfw_ev.text = key_text;
|
||||||
|
|
||||||
|
_GLFWIBUSKeyEvent ibus_ev;
|
||||||
|
ibus_ev.glfw_ev = glfw_ev;
|
||||||
|
ibus_ev.ibus_keycode = ibus_keycode;
|
||||||
|
ibus_ev.window_id = window->id;
|
||||||
|
ibus_ev.ibus_keysym = syms[0];
|
||||||
|
if (ibus_process_key(&ibus_ev, &xkb->ibus)) {
|
||||||
|
debug("↳ to IBUS: scancode: 0x%x keysym: 0x%x (%s) %s\n", ibus_ev.ibus_keycode, ibus_ev.ibus_keysym, glfw_xkb_keysym_name(ibus_ev.ibus_keysym), format_mods(ibus_ev.glfw_ev.mods));
|
||||||
} else {
|
} else {
|
||||||
_glfwInputKeyboard(window, glfw_keycode, glfw_sym, action, sg->modifiers, key_event.text, 0);
|
_glfwInputKeyboard(window, &glfw_ev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
glfw/xkb_glfw.h
vendored
2
glfw/xkb_glfw.h
vendored
@ -93,4 +93,4 @@ xkb_keysym_t glfw_xkb_sym_for_key(int key);
|
|||||||
void glfw_xkb_handle_key_event(_GLFWwindow *window, _GLFWXKBData *xkb, xkb_keycode_t scancode, int action);
|
void glfw_xkb_handle_key_event(_GLFWwindow *window, _GLFWXKBData *xkb, xkb_keycode_t scancode, int action);
|
||||||
int glfw_xkb_keysym_from_name(const char *name, bool case_sensitive);
|
int glfw_xkb_keysym_from_name(const char *name, bool case_sensitive);
|
||||||
void glfw_xkb_update_ime_state(_GLFWwindow *w, _GLFWXKBData *xkb, int which, int a, int b, int c, int d);
|
void glfw_xkb_update_ime_state(_GLFWwindow *w, _GLFWXKBData *xkb, int which, int a, int b, int c, int d);
|
||||||
void glfw_xkb_key_from_ime(KeyEvent *ev, bool handled_by_ime, bool failed);
|
void glfw_xkb_key_from_ime(_GLFWIBUSKeyEvent *ev, bool handled_by_ime, bool failed);
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include "glfw-wrapper.h"
|
||||||
// Required minimum OpenGL version
|
// Required minimum OpenGL version
|
||||||
#define OPENGL_REQUIRED_VERSION_MAJOR 3
|
#define OPENGL_REQUIRED_VERSION_MAJOR 3
|
||||||
#define OPENGL_REQUIRED_VERSION_MINOR 3
|
#define OPENGL_REQUIRED_VERSION_MINOR 3
|
||||||
@ -309,7 +310,7 @@ void focus_in_event(void);
|
|||||||
void scroll_event(double, double, int);
|
void scroll_event(double, double, int);
|
||||||
void fake_scroll(int, bool);
|
void fake_scroll(int, bool);
|
||||||
void set_special_key_combo(int glfw_key, int mods, bool is_native);
|
void set_special_key_combo(int glfw_key, int mods, bool is_native);
|
||||||
void on_key_input(int key, int scancode, int action, int mods, const char*, int);
|
void on_key_input(GLFWkeyevent *ev);
|
||||||
void request_window_attention(id_type, bool);
|
void request_window_attention(id_type, bool);
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
void play_canberra_sound(const char *which_sound, const char *event_id);
|
void play_canberra_sound(const char *which_sound, const char *event_id);
|
||||||
|
83
kitty/glfw-wrapper.h
generated
83
kitty/glfw-wrapper.h
generated
@ -1,3 +1,9 @@
|
|||||||
|
//
|
||||||
|
// THIS FILE IS GENERATED BY glfw.py
|
||||||
|
//
|
||||||
|
// SAVE YOURSELF SOME TIME, DO NOT MANUALLY EDIT
|
||||||
|
//
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@ -18,7 +24,7 @@
|
|||||||
* backward-compatible.
|
* backward-compatible.
|
||||||
* @ingroup init
|
* @ingroup init
|
||||||
*/
|
*/
|
||||||
#define GLFW_VERSION_MINOR 3
|
#define GLFW_VERSION_MINOR 4
|
||||||
/*! @brief The revision number of the GLFW library.
|
/*! @brief The revision number of the GLFW library.
|
||||||
*
|
*
|
||||||
* This is incremented when a bug fix release is made that does not contain any
|
* This is incremented when a bug fix release is made that does not contain any
|
||||||
@ -725,62 +731,62 @@
|
|||||||
#define GLFW_CLIENT_API 0x00022001
|
#define GLFW_CLIENT_API 0x00022001
|
||||||
/*! @brief Context client API major version hint and attribute.
|
/*! @brief Context client API major version hint and attribute.
|
||||||
*
|
*
|
||||||
* Context client API major version [hint](@ref GLFW_CLIENT_API_hint) and
|
* Context client API major version [hint](@ref GLFW_CONTEXT_VERSION_MAJOR_hint)
|
||||||
* [attribute](@ref GLFW_CLIENT_API_attrib).
|
* and [attribute](@ref GLFW_CONTEXT_VERSION_MAJOR_attrib).
|
||||||
*/
|
*/
|
||||||
#define GLFW_CONTEXT_VERSION_MAJOR 0x00022002
|
#define GLFW_CONTEXT_VERSION_MAJOR 0x00022002
|
||||||
/*! @brief Context client API minor version hint and attribute.
|
/*! @brief Context client API minor version hint and attribute.
|
||||||
*
|
*
|
||||||
* Context client API minor version [hint](@ref GLFW_CLIENT_API_hint) and
|
* Context client API minor version [hint](@ref GLFW_CONTEXT_VERSION_MINOR_hint)
|
||||||
* [attribute](@ref GLFW_CLIENT_API_attrib).
|
* and [attribute](@ref GLFW_CONTEXT_VERSION_MINOR_attrib).
|
||||||
*/
|
*/
|
||||||
#define GLFW_CONTEXT_VERSION_MINOR 0x00022003
|
#define GLFW_CONTEXT_VERSION_MINOR 0x00022003
|
||||||
/*! @brief Context client API revision number hint and attribute.
|
/*! @brief Context client API revision number hint and attribute.
|
||||||
*
|
*
|
||||||
* Context client API revision number [hint](@ref GLFW_CLIENT_API_hint) and
|
* Context client API revision number
|
||||||
* [attribute](@ref GLFW_CLIENT_API_attrib).
|
* [attribute](@ref GLFW_CONTEXT_REVISION_attrib).
|
||||||
*/
|
*/
|
||||||
#define GLFW_CONTEXT_REVISION 0x00022004
|
#define GLFW_CONTEXT_REVISION 0x00022004
|
||||||
/*! @brief Context robustness hint and attribute.
|
/*! @brief Context robustness hint and attribute.
|
||||||
*
|
*
|
||||||
* Context client API revision number [hint](@ref GLFW_CLIENT_API_hint) and
|
* Context client API revision number [hint](@ref GLFW_CONTEXT_ROBUSTNESS_hint)
|
||||||
* [attribute](@ref GLFW_CLIENT_API_attrib).
|
* and [attribute](@ref GLFW_CONTEXT_ROBUSTNESS_attrib).
|
||||||
*/
|
*/
|
||||||
#define GLFW_CONTEXT_ROBUSTNESS 0x00022005
|
#define GLFW_CONTEXT_ROBUSTNESS 0x00022005
|
||||||
/*! @brief OpenGL forward-compatibility hint and attribute.
|
/*! @brief OpenGL forward-compatibility hint and attribute.
|
||||||
*
|
*
|
||||||
* OpenGL forward-compatibility [hint](@ref GLFW_CLIENT_API_hint) and
|
* OpenGL forward-compatibility [hint](@ref GLFW_OPENGL_FORWARD_COMPAT_hint)
|
||||||
* [attribute](@ref GLFW_CLIENT_API_attrib).
|
* and [attribute](@ref GLFW_OPENGL_FORWARD_COMPAT_attrib).
|
||||||
*/
|
*/
|
||||||
#define GLFW_OPENGL_FORWARD_COMPAT 0x00022006
|
#define GLFW_OPENGL_FORWARD_COMPAT 0x00022006
|
||||||
/*! @brief OpenGL debug context hint and attribute.
|
/*! @brief OpenGL debug context hint and attribute.
|
||||||
*
|
*
|
||||||
* OpenGL debug context [hint](@ref GLFW_CLIENT_API_hint) and
|
* OpenGL debug context [hint](@ref GLFW_OPENGL_DEBUG_CONTEXT_hint) and
|
||||||
* [attribute](@ref GLFW_CLIENT_API_attrib).
|
* [attribute](@ref GLFW_OPENGL_DEBUG_CONTEXT_attrib).
|
||||||
*/
|
*/
|
||||||
#define GLFW_OPENGL_DEBUG_CONTEXT 0x00022007
|
#define GLFW_OPENGL_DEBUG_CONTEXT 0x00022007
|
||||||
/*! @brief OpenGL profile hint and attribute.
|
/*! @brief OpenGL profile hint and attribute.
|
||||||
*
|
*
|
||||||
* OpenGL profile [hint](@ref GLFW_CLIENT_API_hint) and
|
* OpenGL profile [hint](@ref GLFW_OPENGL_PROFILE_hint) and
|
||||||
* [attribute](@ref GLFW_CLIENT_API_attrib).
|
* [attribute](@ref GLFW_OPENGL_PROFILE_attrib).
|
||||||
*/
|
*/
|
||||||
#define GLFW_OPENGL_PROFILE 0x00022008
|
#define GLFW_OPENGL_PROFILE 0x00022008
|
||||||
/*! @brief Context flush-on-release hint and attribute.
|
/*! @brief Context flush-on-release hint and attribute.
|
||||||
*
|
*
|
||||||
* Context flush-on-release [hint](@ref GLFW_CLIENT_API_hint) and
|
* Context flush-on-release [hint](@ref GLFW_CONTEXT_RELEASE_BEHAVIOR_hint) and
|
||||||
* [attribute](@ref GLFW_CLIENT_API_attrib).
|
* [attribute](@ref GLFW_CONTEXT_RELEASE_BEHAVIOR_attrib).
|
||||||
*/
|
*/
|
||||||
#define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009
|
#define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009
|
||||||
/*! @brief Context error suppression hint and attribute.
|
/*! @brief Context error suppression hint and attribute.
|
||||||
*
|
*
|
||||||
* Context error suppression [hint](@ref GLFW_CLIENT_API_hint) and
|
* Context error suppression [hint](@ref GLFW_CONTEXT_NO_ERROR_hint) and
|
||||||
* [attribute](@ref GLFW_CLIENT_API_attrib).
|
* [attribute](@ref GLFW_CONTEXT_NO_ERROR_attrib).
|
||||||
*/
|
*/
|
||||||
#define GLFW_CONTEXT_NO_ERROR 0x0002200A
|
#define GLFW_CONTEXT_NO_ERROR 0x0002200A
|
||||||
/*! @brief Context creation API hint and attribute.
|
/*! @brief Context creation API hint and attribute.
|
||||||
*
|
*
|
||||||
* Context creation API [hint](@ref GLFW_CLIENT_API_hint) and
|
* Context creation API [hint](@ref GLFW_CONTEXT_CREATION_API_hint) and
|
||||||
* [attribute](@ref GLFW_CLIENT_API_attrib).
|
* [attribute](@ref GLFW_CONTEXT_CREATION_API_attrib).
|
||||||
*/
|
*/
|
||||||
#define GLFW_CONTEXT_CREATION_API 0x0002200B
|
#define GLFW_CONTEXT_CREATION_API 0x0002200B
|
||||||
/*! @brief Window content area scaling window
|
/*! @brief Window content area scaling window
|
||||||
@ -934,6 +940,29 @@ typedef struct GLFWwindow GLFWwindow;
|
|||||||
*/
|
*/
|
||||||
typedef struct GLFWcursor GLFWcursor;
|
typedef struct GLFWcursor GLFWcursor;
|
||||||
|
|
||||||
|
typedef struct GLFWkeyevent
|
||||||
|
{
|
||||||
|
// The [keyboard key](@ref keys) that was pressed or released.
|
||||||
|
int key;
|
||||||
|
|
||||||
|
// The system-specific scancode of the key.
|
||||||
|
int scancode;
|
||||||
|
|
||||||
|
// The event action. Either `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`.
|
||||||
|
int action;
|
||||||
|
|
||||||
|
// Bit field describing which [modifier keys](@ref mods) were held down.
|
||||||
|
int mods;
|
||||||
|
|
||||||
|
// UTF-8 encoded text generated by this key event or empty string.
|
||||||
|
const char *text;
|
||||||
|
|
||||||
|
// Used for Input Method events. Zero for normal key events.
|
||||||
|
// A value of 1 means the pre-edit text for the input event has been changed.
|
||||||
|
// A value of 2 means the text should be committed.
|
||||||
|
int ime_state;
|
||||||
|
} GLFWkeyevent;
|
||||||
|
|
||||||
/*! @brief The function signature for error callbacks.
|
/*! @brief The function signature for error callbacks.
|
||||||
*
|
*
|
||||||
* This is the function signature for error callback functions.
|
* This is the function signature for error callback functions.
|
||||||
@ -1219,15 +1248,7 @@ typedef void (* GLFWscrollfun)(GLFWwindow*,double,double,int);
|
|||||||
* the "s" key will generate text "o" and GLFW_KEY_O.
|
* the "s" key will generate text "o" and GLFW_KEY_O.
|
||||||
*
|
*
|
||||||
* @param[in] window The window that received the event.
|
* @param[in] window The window that received the event.
|
||||||
* @param[in] key The [keyboard key](@ref keys) that was pressed or released.
|
* @param[in] ev TODO: blablabla
|
||||||
* @param[in] scancode The system-specific scancode of the key.
|
|
||||||
* @param[in] action `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`.
|
|
||||||
* @param[in] mods Bit field describing which [modifier keys](@ref mods) were
|
|
||||||
* held down.
|
|
||||||
* @param[in] text UTF-8 encoded text generated by this key event or empty string.
|
|
||||||
* @param[in] Used for Input Method events. Zero for normal key events.
|
|
||||||
* A value of 1 means the pre-edit text for the input event has been changed.
|
|
||||||
* A value of 2 means the text should be committed.
|
|
||||||
*
|
*
|
||||||
* @note On X11/Wayland if a modifier other than the modifiers GLFW reports
|
* @note On X11/Wayland if a modifier other than the modifiers GLFW reports
|
||||||
* (ctrl/shift/alt/super) is used, GLFW will report the shifted key rather
|
* (ctrl/shift/alt/super) is used, GLFW will report the shifted key rather
|
||||||
@ -1241,7 +1262,7 @@ typedef void (* GLFWscrollfun)(GLFWwindow*,double,double,int);
|
|||||||
*
|
*
|
||||||
* @ingroup input
|
* @ingroup input
|
||||||
*/
|
*/
|
||||||
typedef void (* GLFWkeyboardfun)(GLFWwindow*, int, int, int, int, const char*, int);
|
typedef void (* GLFWkeyboardfun)(GLFWwindow*, GLFWkeyevent*);
|
||||||
|
|
||||||
/*! @brief The function signature for file drop callbacks.
|
/*! @brief The function signature for file drop callbacks.
|
||||||
*
|
*
|
||||||
|
10
kitty/glfw.c
10
kitty/glfw.c
@ -230,14 +230,14 @@ refresh_callback(GLFWwindow *w) {
|
|||||||
static int mods_at_last_key_or_button_event = 0;
|
static int mods_at_last_key_or_button_event = 0;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
key_callback(GLFWwindow *w, int key, int scancode, int action, int mods, const char* text, int state) {
|
key_callback(GLFWwindow *w, GLFWkeyevent *ev) {
|
||||||
if (!set_callback_window(w)) return;
|
if (!set_callback_window(w)) return;
|
||||||
mods_at_last_key_or_button_event = mods;
|
mods_at_last_key_or_button_event = ev->mods;
|
||||||
global_state.callback_os_window->cursor_blink_zero_time = monotonic();
|
global_state.callback_os_window->cursor_blink_zero_time = monotonic();
|
||||||
if (key >= 0 && key <= GLFW_KEY_LAST) {
|
if (ev->key >= 0 && ev->key <= GLFW_KEY_LAST) {
|
||||||
global_state.callback_os_window->is_key_pressed[key] = action == GLFW_RELEASE ? false : true;
|
global_state.callback_os_window->is_key_pressed[ev->key] = ev->action == GLFW_RELEASE ? false : true;
|
||||||
}
|
}
|
||||||
if (is_window_ready_for_callbacks()) on_key_input(key, scancode, action, mods, text, state);
|
if (is_window_ready_for_callbacks()) on_key_input(ev);
|
||||||
global_state.callback_os_window = NULL;
|
global_state.callback_os_window = NULL;
|
||||||
request_tick_callback();
|
request_tick_callback();
|
||||||
}
|
}
|
||||||
|
@ -31,9 +31,9 @@ static void* empty_thread_main(void* data UNUSED)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void key_callback(GLFWwindow *w UNUSED, int key, int scancode UNUSED, int action, int mods UNUSED, const char* text UNUSED, int state UNUSED)
|
static void key_callback(GLFWwindow *w UNUSED, GLFWkeyevent *ev)
|
||||||
{
|
{
|
||||||
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
|
if (ev->key == GLFW_KEY_ESCAPE && ev->action == GLFW_PRESS) {
|
||||||
glfwSetWindowShouldClose(w, true);
|
glfwSetWindowShouldClose(w, true);
|
||||||
wakeup_main_loop();
|
wakeup_main_loop();
|
||||||
}
|
}
|
||||||
|
14
kitty/keys.c
14
kitty/keys.c
@ -121,16 +121,24 @@ update_ime_position(OSWindow *os_window, Window* w, Screen *screen) {
|
|||||||
#define debug(...) if (OPT(debug_keyboard)) printf(__VA_ARGS__);
|
#define debug(...) if (OPT(debug_keyboard)) printf(__VA_ARGS__);
|
||||||
|
|
||||||
void
|
void
|
||||||
on_key_input(int key, int scancode, int action, int mods, const char* text, int state) {
|
on_key_input(GLFWkeyevent *ev) {
|
||||||
Window *w = active_window();
|
Window *w = active_window();
|
||||||
|
int action, scancode, key, mods;
|
||||||
|
const char *text;
|
||||||
|
action = ev->action;
|
||||||
|
scancode = ev->scancode;
|
||||||
|
key = ev->key;
|
||||||
|
mods = ev->mods;
|
||||||
|
text = ev->text;
|
||||||
|
|
||||||
debug("on_key_input: glfw key: %d native_code: 0x%x action: %s mods: 0x%x text: '%s' state: %d ",
|
debug("on_key_input: glfw key: %d native_code: 0x%x action: %s mods: 0x%x text: '%s' state: %d ",
|
||||||
key, scancode,
|
key, scancode,
|
||||||
(action == GLFW_RELEASE ? "RELEASE" : (action == GLFW_PRESS ? "PRESS" : "REPEAT")),
|
(action == GLFW_RELEASE ? "RELEASE" : (action == GLFW_PRESS ? "PRESS" : "REPEAT")),
|
||||||
mods, text, state);
|
mods, text, ev->ime_state);
|
||||||
if (!w) { debug("no active window, ignoring\n"); return; }
|
if (!w) { debug("no active window, ignoring\n"); return; }
|
||||||
if (OPT(mouse_hide_wait) < 0 && !is_modifier_key(key)) hide_mouse(global_state.callback_os_window);
|
if (OPT(mouse_hide_wait) < 0 && !is_modifier_key(key)) hide_mouse(global_state.callback_os_window);
|
||||||
Screen *screen = w->render_data.screen;
|
Screen *screen = w->render_data.screen;
|
||||||
switch(state) {
|
switch(ev->ime_state) {
|
||||||
case 1: // update pre-edit text
|
case 1: // update pre-edit text
|
||||||
update_ime_position(global_state.callback_os_window, w, screen);
|
update_ime_position(global_state.callback_os_window, w, screen);
|
||||||
screen_draw_overlay_text(screen, text);
|
screen_draw_overlay_text(screen, text);
|
||||||
|
Loading…
Reference in New Issue
Block a user