From 84f6aabf5ba49ea50bc4b91721c0fd381db7c422 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 22 Apr 2021 09:28:11 +0530 Subject: [PATCH] Clean up debug keyboard on macOS --- glfw/cocoa_window.m | 53 ++++++++++++++++++++++++--------------------- kitty/keys.c | 28 +++++++++++++++++++++--- kitty/keys.h | 2 +- 3 files changed, 54 insertions(+), 29 deletions(-) diff --git a/glfw/cocoa_window.m b/glfw/cocoa_window.m index fc6fb8d8a..f506d12f3 100644 --- a/glfw/cocoa_window.m +++ b/glfw/cocoa_window.m @@ -454,7 +454,8 @@ static void releaseMonitor(_GLFWwindow* window) // Translates macOS key modifiers into GLFW ones // -static int translateFlags(NSUInteger flags) +static int +translateFlags(NSUInteger flags) { int mods = 0; @@ -472,7 +473,7 @@ static int translateFlags(NSUInteger flags) return mods; } -#define debug_key(...) if (_glfw.hints.init.debugKeyboard) NSLog(__VA_ARGS__) +#define debug_key(...) if (_glfw.hints.init.debugKeyboard) { fprintf(stderr, __VA_ARGS__); fflush(stderr); } static inline const char* format_mods(int mods) { @@ -613,7 +614,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; - (void)toggle { // Set _desired to the opposite of the current state. _desired = !_desired; - debug_key(@"toggle called. Setting desired to %@", @(_desired)); + debug_key("toggle called. Setting desired to %d", _desired); // Try to set the system's state of secure input to the desired state. [self update]; @@ -632,7 +633,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; - (void)applicationDidResignActive:(NSNotification *)notification { (void)notification; if (_count > 0) { - debug_key(@"Application resigning active."); + debug_key("Application resigning active."); [self update]; } } @@ -640,7 +641,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; - (void)applicationDidBecomeActive:(NSNotification *)notification { (void)notification; if (self.isDesired) { - debug_key(@"Application became active."); + debug_key("Application became active."); [self update]; } } @@ -652,39 +653,39 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; } - (void)update { - debug_key(@"Update secure keyboard entry. desired=%@ active=%@", - @(self.isDesired), @([NSApp isActive])); + debug_key("Update secure keyboard entry. desired=%d active=%d", + (int)self.isDesired, (int)[NSApp isActive]); const BOOL secure = self.isDesired && [self allowed]; if (secure && _count > 0) { - debug_key(@"Want to turn on secure input but it's already on"); + debug_key("Want to turn on secure input but it's already on"); return; } if (!secure && _count == 0) { - debug_key(@"Want to turn off secure input but it's already off"); + debug_key("Want to turn off secure input but it's already off"); return; } - debug_key(@"Before: IsSecureEventInputEnabled returns %d", (int)self.isEnabled); + debug_key("Before: IsSecureEventInputEnabled returns %d", (int)self.isEnabled); if (secure) { OSErr err = EnableSecureEventInput(); - debug_key(@"EnableSecureEventInput err=%d", (int)err); + debug_key("EnableSecureEventInput err=%d", (int)err); if (err) { - debug_key(@"EnableSecureEventInput failed with error %d", (int)err); + debug_key("EnableSecureEventInput failed with error %d", (int)err); } else { _count += 1; } } else { OSErr err = DisableSecureEventInput(); - debug_key(@"DisableSecureEventInput err=%d", (int)err); + debug_key("DisableSecureEventInput err=%d", (int)err); if (err) { - debug_key(@"DisableSecureEventInput failed with error %d", (int)err); + debug_key("DisableSecureEventInput failed with error %d", (int)err); } else { _count -= 1; } } - debug_key(@"After: IsSecureEventInputEnabled returns %d", (int)self.isEnabled); + debug_key("After: IsSecureEventInputEnabled returns %d", (int)self.isEnabled); } @end @@ -1200,7 +1201,7 @@ is_ascii_control_char(char x) { } } else { if (input_source_changed) { - debug_key(@"Input source changed, clearing pre-edit text and resetting deadkey state\n"); + debug_key("Input source changed, clearing pre-edit text and resetting deadkey state\n"); glfw_keyevent.text = NULL; glfw_keyevent.ime_state = GLFW_IME_PREEDIT_CHANGED; window->ns.deadKeyState = 0; @@ -1222,13 +1223,13 @@ is_ascii_control_char(char x) { &char_count, text ) != noErr) { - debug_key(@"UCKeyTranslate failed for keycode: 0x%x (%@) %@\n", - keycode, @(safe_name_for_keycode(keycode)), @(format_mods(mods))); + debug_key("UCKeyTranslate failed for keycode: 0x%x (%s) %s\n", + keycode, safe_name_for_keycode(keycode), format_mods(mods)); window->ns.deadKeyState = 0; return; } - debug_key(@"keycode: 0x%x (%@) %@char_count: %lu deadKeyState: %u repeat: %d", - keycode, @(safe_name_for_keycode(keycode)), @(format_mods(mods)), char_count, window->ns.deadKeyState, event.ARepeat); + debug_key("\x1b[31mPress:\x1b[m native_key: 0x%x (%s) glfw_key: 0x%x %schar_count: %lu deadKeyState: %u repeat: %d ", + keycode, safe_name_for_keycode(keycode), key, format_mods(mods), char_count, window->ns.deadKeyState, event.ARepeat); if (process_text) { // this will call insertText which will fill up _glfw.ns.text [self interpretKeyEvents:[NSArray arrayWithObject:event]]; @@ -1237,22 +1238,22 @@ is_ascii_control_char(char x) { } if (window->ns.deadKeyState && (char_count == 0 || keycode == 0x75)) { // 0x75 is the delete key which needs to be ignored during a compose sequence - debug_key(@"Sending pre-edit text for dead key (text: %@ markedText: %@).\n", @(format_text(_glfw.ns.text)), markedText); glfw_keyevent.text = [[markedText string] UTF8String]; + debug_key("Sending pre-edit text for dead key (text: %s markedText: %s).\n", format_text(_glfw.ns.text), glfw_keyevent.text); glfw_keyevent.ime_state = GLFW_IME_PREEDIT_CHANGED; _glfwInputKeyboard(window, &glfw_keyevent); // update pre-edit text return; } if (in_compose_sequence) { - debug_key(@"Clearing pre-edit text at end of compose sequence\n"); + debug_key("Clearing pre-edit text at end of compose sequence\n"); glfw_keyevent.text = NULL; glfw_keyevent.ime_state = GLFW_IME_PREEDIT_CHANGED; _glfwInputKeyboard(window, &glfw_keyevent); // clear pre-edit text } } if (is_ascii_control_char(_glfw.ns.text[0])) _glfw.ns.text[0] = 0; // don't send text for ascii control codes - debug_key(@"text: %@ glfw_key: %@ marked_text: %@\n", - @(format_text(_glfw.ns.text)), @(_glfwGetKeyName(key)), markedText); + debug_key("text: %s glfw_key: %s marked_text: %s\n", + format_text(_glfw.ns.text), _glfwGetKeyName(key), [[markedText string] UTF8String]); if (!window->ns.deadKeyState) { if ([self hasMarkedText]) { glfw_keyevent.text = [[markedText string] UTF8String]; @@ -1310,6 +1311,8 @@ is_ascii_control_char(char x) { GLFWkeyevent glfw_keyevent = {.key = key, .native_key = keycode, .action = GLFW_RELEASE, .mods = mods}; add_alternate_keys(&glfw_keyevent, event); + debug_key("\x1b[32mRelease:\x1b[m native_key: 0x%x (%s) glfw_key: 0x%x %s\n", + keycode, safe_name_for_keycode(keycode), key, format_mods(mods)); _glfwInputKeyboard(window, &glfw_keyevent); } @@ -1439,7 +1442,7 @@ void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) { top /= window->ns.yscale; cellWidth /= window->ns.xscale; cellHeight /= window->ns.yscale; - debug_key(@"updateIMEState: %f, %f, %f, %f\n", left, top, cellWidth, cellHeight); + debug_key("updateIMEState: %f, %f, %f, %f\n", left, top, cellWidth, cellHeight); const NSRect frame = [window->ns.view frame]; const NSRect rectInView = NSMakeRect(left, frame.size.height - top - cellHeight, diff --git a/kitty/keys.c b/kitty/keys.c index 38c4d673b..fbb68924b 100644 --- a/kitty/keys.c +++ b/kitty/keys.c @@ -90,6 +90,28 @@ update_ime_position(OSWindow *os_window, Window* w, Screen *screen) { glfwUpdateIMEState(global_state.callback_os_window->handle, &ev); } +static inline const char* +format_mods(unsigned mods) { + static char buf[128]; + char *p = buf, *s; +#define pr(x) p += snprintf(p, sizeof(buf) - (p - buf) - 1, x) + pr("mods: "); + s = p; + if (mods & GLFW_MOD_CONTROL) pr("ctrl+"); + if (mods & GLFW_MOD_ALT) pr("alt+"); + if (mods & GLFW_MOD_SHIFT) pr("shift+"); + if (mods & GLFW_MOD_SUPER) pr("super+"); + if (mods & GLFW_MOD_HYPER) pr("hyper+"); + if (mods & GLFW_MOD_META) pr("meta+"); + if (mods & GLFW_MOD_CAPS_LOCK) pr("capslock+"); + if (mods & GLFW_MOD_NUM_LOCK) pr("numlock+"); + if (p == s) pr("none"); + else p--; + pr(" "); +#undef pr + return buf; +} + void on_key_input(GLFWkeyevent *ev) { Window *w = active_window(); @@ -97,10 +119,10 @@ on_key_input(GLFWkeyevent *ev) { const uint32_t key = ev->key, native_key = ev->native_key; const char *text = ev->text ? ev->text : ""; - debug("\x1b[33mon_key_input\x1b[m: glfw key: %d native_code: 0x%x action: %s mods: 0x%x text: '%s' state: %d ", + debug("\x1b[33mon_key_input\x1b[m: glfw key: 0x%x native_code: 0x%x action: %s %stext: '%s' state: %d ", key, native_key, (action == GLFW_RELEASE ? "RELEASE" : (action == GLFW_PRESS ? "PRESS" : "REPEAT")), - mods, text, ev->ime_state); + format_mods(mods), text, ev->ime_state); 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); Screen *screen = w->render_data.screen; @@ -167,7 +189,7 @@ on_key_input(GLFWkeyevent *ev) { if (!w) return; } else if (w->last_special_key_pressed == key) { w->last_special_key_pressed = 0; - debug("ignoring release event for previous press that was handled as shortcut"); + debug("ignoring release event for previous press that was handled as shortcut\n"); return; } #undef create_key_event diff --git a/kitty/keys.h b/kitty/keys.h index 1f80d0e4a..2f70ca6d6 100644 --- a/kitty/keys.h +++ b/kitty/keys.h @@ -13,7 +13,7 @@ #define KEY_BUFFER_SIZE 128 #define SEND_TEXT_TO_CHILD INT_MIN -#define debug(...) if (OPT(debug_keyboard)) printf(__VA_ARGS__); +#define debug(...) if (OPT(debug_keyboard)) { fprintf(stderr, __VA_ARGS__); fflush(stderr); } int encode_glfw_key_event(const GLFWkeyevent *e, const bool cursor_key_mode, const unsigned flags, char *output);