diff --git a/glfw/xkb_glfw.c b/glfw/xkb_glfw.c index 79aa1ddaa..8623d2202 100644 --- a/glfw/xkb_glfw.c +++ b/glfw/xkb_glfw.c @@ -429,8 +429,12 @@ glfw_xkb_key_from_ime(KeyEvent *ev, GLFWbool handled_by_ime, GLFWbool failed) { GLFWbool is_release = 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); if (window && !handled_by_ime && !(is_release && ev->keycode == prev_handled_press)) { + 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->action == GLFW_RELEASE ? "RELEASE" : (ev->action == GLFW_PRESS ? "PRESS" : "REPEAT")), + format_mods(ev->glfw_modifiers), key_event.text + ); _glfwInputKeyboard(window, ev->glfw_keycode, ev->keysym, ev->action, ev->glfw_modifiers, key_event.text, 0); - debug("↳ to application\n"); } else debug("↳ discarded\n"); if (!is_release && handled_by_ime) last_handled_press_keycode = ev->keycode; } @@ -494,10 +498,10 @@ glfw_xkb_handle_key_event(_GLFWwindow *window, _GLFWXKBData *xkb, xkb_keycode_t } } debug( - "%s%s: %s xkb_key_name: %s\n", + "%s%s: %d (%s) xkb_key: %d (%s)\n", format_mods(sg->modifiers), - is_fallback ? "glfw_fallback_key" : "glfw_key", _glfwGetKeyName(glfw_keycode), - glfw_xkb_keysym_name(glfw_sym) + is_fallback ? "glfw_fallback_key" : "glfw_key", glfw_keycode, _glfwGetKeyName(glfw_keycode), + glfw_sym, glfw_xkb_keysym_name(glfw_sym) ); key_event.action = action; key_event.glfw_modifiers = sg->modifiers; key_event.keycode = scancode; key_event.keysym = glfw_sym; diff --git a/kitty/glfw.c b/kitty/glfw.c index 3fa0a6448..206e55f05 100644 --- a/kitty/glfw.c +++ b/kitty/glfw.c @@ -566,6 +566,7 @@ glfw_init(PyObject UNUSED *self, PyObject *args) { if (err) { PyErr_SetString(PyExc_RuntimeError, err); return NULL; } glfwSetErrorCallback(error_callback); glfwInitHint(GLFW_DEBUG_KEYBOARD, debug_keyboard); + global_state.opts.debug_keyboard = debug_keyboard != 0; #ifdef __APPLE__ glfwInitHint(GLFW_COCOA_CHDIR_RESOURCES, 0); glfwInitHint(GLFW_COCOA_MENUBAR, 0); diff --git a/kitty/keys.c b/kitty/keys.c index b1a26534e..9b494213c 100644 --- a/kitty/keys.c +++ b/kitty/keys.c @@ -122,28 +122,37 @@ update_ime_position(OSWindow *os_window, Window* w, Screen *screen) { glfwUpdateIMEState(global_state.callback_os_window->handle, 2, left, top, cell_width, cell_height); } +#define debug(...) if (OPT(debug_keyboard)) printf(__VA_ARGS__); void on_key_input(int key, int scancode, int action, int mods, const char* text, int state) { Window *w = active_window(); - if (!w) return; + debug("on_key_input: glfw key: %d native_code: %d action: %s mods: 0x%x text: '%s' state: %d ", + key, scancode, + (action == GLFW_RELEASE ? "RELEASE" : (action == GLFW_PRESS ? "PRESS" : "REPEAT")), + mods, text, state); + if (!w) { debug("no active window, ignoring\n"); return; } Screen *screen = w->render_data.screen; switch(state) { case 1: // update pre-edit text update_ime_position(global_state.callback_os_window, w, screen); screen_draw_overlay_text(screen, text); + debug("updated pre-edit text\n"); return; case 2: // commit text if (text && *text) { schedule_write_to_child(w->id, text, strlen(text)); } + debug("committed pre-edit text\n"); return; case 0: break; default: + debug("invalid state, ignoring\n"); return; } if (global_state.in_sequence_mode) { + debug("in sequence mode, handling as shortcut\n"); if ( action != GLFW_RELEASE && key != GLFW_KEY_LEFT_SHIFT && key != GLFW_KEY_RIGHT_SHIFT && key != GLFW_KEY_LEFT_ALT && key != GLFW_KEY_RIGHT_ALT && key != GLFW_KEY_LEFT_CONTROL && key != GLFW_KEY_RIGHT_CONTROL @@ -158,11 +167,17 @@ on_key_input(int key, int scancode, int action, int mods, const char* text, int else { bool consumed = ret == Py_True; Py_DECREF(ret); - if (consumed) return; + if (consumed) { + debug("handled as shortcut\n"); + return; + } } } } - if (action == GLFW_REPEAT && !screen->modes.mDECARM) return; + if (action == GLFW_REPEAT && !screen->modes.mDECARM) { + debug("discarding repeat key event as DECARM is off\n"); + return; + } if (screen->scrolled_by && action == GLFW_PRESS && !is_modifier_key(key)) { screen_history_scroll(screen, SCROLL_FULL, false); // scroll back to bottom } @@ -170,9 +185,13 @@ on_key_input(int key, int scancode, int action, int mods, const char* text, int if (ok_to_send) { if (has_text) { schedule_write_to_child(w->id, text, strlen(text)); + debug("sent text to child\n"); } else { send_key_to_child(w, key, mods, action); + debug("sent key to child\n"); } + } else { + debug("ignoring as keyboard mode does not allow repeat events\n"); } } diff --git a/kitty/state.h b/kitty/state.h index 9ae170f48..c1d74b38f 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -34,6 +34,7 @@ typedef struct { bool sync_to_monitor; bool close_on_child_death; bool window_alert_on_bell; + bool debug_keyboard; } Options; typedef struct {