diff --git a/glfw/cocoa_init.m b/glfw/cocoa_init.m index 4ea90333f..e7d86ee99 100644 --- a/glfw/cocoa_init.m +++ b/glfw/cocoa_init.m @@ -927,12 +927,12 @@ int _glfwPlatformInit(bool *supports_window_occlusion) NSEvent* (^keydown_block)(NSEvent*) = ^ NSEvent* (NSEvent* event) { - debug_key("---------------- key down -------------------\n"); - debug_key("%s\n", [[event description] UTF8String]); + debug_input("---------------- key down -------------------\n"); + debug_input("%s\n", [[event description] UTF8String]); if (!_glfw.ignoreOSKeyboardProcessing && !_glfw.keyboard_grabbed) { // first check if there is a global menu bar shortcut if ([[NSApp mainMenu] performKeyEquivalent:event]) { - debug_key("keyDown triggered global menu bar action ignoring\n"); + debug_input("keyDown triggered global menu bar action ignoring\n"); last_keydown_shortcut_event.virtual_key_code = [event keyCode]; last_keydown_shortcut_event.input_source_switch_modifiers = 0; last_keydown_shortcut_event.timestamp = [event timestamp]; @@ -941,7 +941,7 @@ int _glfwPlatformInit(bool *supports_window_occlusion) // now check if there is a useful apple shortcut int global_shortcut = is_active_apple_global_shortcut(event); if (is_useful_apple_global_shortcut(global_shortcut)) { - debug_key("keyDown triggered global macOS shortcut ignoring\n"); + debug_input("keyDown triggered global macOS shortcut ignoring\n"); last_keydown_shortcut_event.virtual_key_code = [event keyCode]; // record the modifier keys if switching to the next input source last_keydown_shortcut_event.input_source_switch_modifiers = (global_shortcut == kSHKSelectNextSourceInInputMenu) ? USEFUL_MODS([event modifierFlags]) : 0; @@ -950,7 +950,7 @@ int _glfwPlatformInit(bool *supports_window_occlusion) } // check for JIS keyboard layout function keys if (is_apple_jis_layout_function_key(event)) { - debug_key("keyDown triggered JIS layout function key ignoring\n"); + debug_input("keyDown triggered JIS layout function key ignoring\n"); last_keydown_shortcut_event.virtual_key_code = [event keyCode]; last_keydown_shortcut_event.input_source_switch_modifiers = 0; last_keydown_shortcut_event.timestamp = [event timestamp]; @@ -960,33 +960,33 @@ int _glfwPlatformInit(bool *supports_window_occlusion) last_keydown_shortcut_event.virtual_key_code = 0xffff; NSWindow *kw = [NSApp keyWindow]; if (kw && kw.contentView) [kw.contentView keyDown:event]; - else debug_key("keyDown ignored as no keyWindow present\n"); + else debug_input("keyDown ignored as no keyWindow present\n"); return nil; }; NSEvent* (^keyup_block)(NSEvent*) = ^ NSEvent* (NSEvent* event) { - debug_key("----------------- key up --------------------\n"); - debug_key("%s\n", [[event description] UTF8String]); + debug_input("----------------- key up --------------------\n"); + debug_input("%s\n", [[event description] UTF8String]); if (last_keydown_shortcut_event.virtual_key_code != 0xffff && last_keydown_shortcut_event.virtual_key_code == [event keyCode]) { // ignore as the corresponding key down event triggered a menu bar or macOS shortcut last_keydown_shortcut_event.virtual_key_code = 0xffff; - debug_key("keyUp ignored as corresponds to previous keyDown that triggered a shortcut\n"); + debug_input("keyUp ignored as corresponds to previous keyDown that triggered a shortcut\n"); return nil; } NSWindow *kw = [NSApp keyWindow]; if (kw && kw.contentView) [kw.contentView keyUp:event]; - else debug_key("keyUp ignored as no keyWindow present\n"); + else debug_input("keyUp ignored as no keyWindow present\n"); return nil; }; NSEvent* (^flags_changed_block)(NSEvent*) = ^ NSEvent* (NSEvent* event) { - debug_key("-------------- flags changed -----------------\n"); - debug_key("%s\n", [[event description] UTF8String]); + debug_input("-------------- flags changed -----------------\n"); + debug_input("%s\n", [[event description] UTF8String]); last_keydown_shortcut_event.virtual_key_code = 0xffff; if (!_glfw.ignoreOSKeyboardProcessing && !_glfw.keyboard_grabbed && is_apple_fn_global_shortcut(event)) { - debug_key("flagsChanged triggered global fn shortcut ignoring\n"); + debug_input("flagsChanged triggered global fn shortcut ignoring\n"); return event; } // switching to the next input source is only confirmed when all modifier keys are released @@ -997,7 +997,7 @@ int _glfwPlatformInit(bool *supports_window_occlusion) } NSWindow *kw = [NSApp keyWindow]; if (kw && kw.contentView) [kw.contentView flagsChanged:event]; - else debug_key("flagsChanged ignored as no keyWindow present\n"); + else debug_input("flagsChanged ignored as no keyWindow present\n"); return nil; }; diff --git a/glfw/cocoa_platform.h b/glfw/cocoa_platform.h index 8974b8cf6..5a39e9bcd 100644 --- a/glfw/cocoa_platform.h +++ b/glfw/cocoa_platform.h @@ -62,8 +62,6 @@ typedef void* id; #define NSOpenGLContextParameterSurfaceOpacity NSOpenGLCPSurfaceOpacity #endif -#define debug_key(...) if (_glfw.hints.init.debugKeyboard) { fprintf(stderr, __VA_ARGS__); fflush(stderr); } - typedef int (* GLFWcocoatextinputfilterfun)(int,int,unsigned int, unsigned long); typedef bool (* GLFWapplicationshouldhandlereopenfun)(int); typedef bool (* GLFWhandleurlopen)(const char*); diff --git a/glfw/cocoa_window.m b/glfw/cocoa_window.m index fce4b72fd..effbf641c 100644 --- a/glfw/cocoa_window.m +++ b/glfw/cocoa_window.m @@ -108,7 +108,7 @@ forward_dictation_selector_to_app(SEL selector, id sender) { } if (selector != start_dictation_selector && selector != stop_dictation_selector) return false; if ([NSApp respondsToSelector:selector]) { - debug_key("Forwarding %s to NSApp\n", [NSStringFromSelector(selector) UTF8String]); + debug_input("Forwarding %s to NSApp\n", [NSStringFromSelector(selector) UTF8String]); [NSApp performSelector:selector withObject:sender]; return true; } @@ -859,7 +859,7 @@ static void _glfwUpdateNotchCover(_GLFWwindow*); // interpretKeyEvents: May call insertText: or doCommandBySelector:. // With the default macOS keybindings, pressing certain key combinations // (e.g. Ctrl+/, Ctrl+Cmd+Down/Left/Right) will produce a beep sound. - debug_key("\n\tTextInputCtx: doCommandBySelector: (%s)\n", [NSStringFromSelector(selector) UTF8String]); + debug_input("\n\tTextInputCtx: doCommandBySelector: (%s)\n", [NSStringFromSelector(selector) UTF8String]); if (forward_dictation_selector_to_app(selector, nil)) return; } @end // }}} @@ -1264,7 +1264,7 @@ is_ascii_control_char(char x) { const bool previous_has_marked_text = [self hasMarkedText]; if (input_context && (!input_source_at_last_key_event || ![input_source_at_last_key_event isEqualToString:input_context.selectedKeyboardInputSource])) { if (input_source_at_last_key_event) { - debug_key("Input source changed, clearing pre-edit text and resetting deadkey state\n"); + debug_input("Input source changed, clearing pre-edit text and resetting deadkey state\n"); GLFWkeyevent dummy = {.action = GLFW_RELEASE, .ime_state = GLFW_IME_PREEDIT_CHANGED}; window->ns.deadKeyState = 0; _glfwInputKeyboard(window, &dummy); // clear pre-edit text @@ -1307,12 +1307,12 @@ is_ascii_control_char(char x) { &char_count, text ) != noErr) { - debug_key("UCKeyTranslate failed for keycode: 0x%x (%s) %s\n", + debug_input("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("\x1b[31mPress:\x1b[m native_key: 0x%x (%s) glfw_key: 0x%x %schar_count: %lu deadKeyState: %u repeat: %d ", + debug_input("\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); marked_text_cleared_by_insert = false; if (process_text) { @@ -1325,17 +1325,17 @@ 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: %s markedText: %s).\n", format_text(_glfw.ns.text), glfw_keyevent.text); + debug_input("Sending pre-edit text for dead key (text: %s markedText: %s).\n", format_text(_glfw.ns.text), glfw_keyevent.text); UPDATE_PRE_EDIT_TEXT; return; } if (in_compose_sequence) { - debug_key("Clearing pre-edit text at end of compose sequence\n"); + debug_input("Clearing pre-edit text at end of compose sequence\n"); 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: %s glfw_key: %s marked_text: (%s)\n", + debug_input("text: %s glfw_key: %s marked_text: (%s)\n", format_text(_glfw.ns.text), _glfwGetKeyName(key), [[markedText string] UTF8String]); bool bracketed_ime = false; if (!window->ns.deadKeyState) { @@ -1348,7 +1348,7 @@ is_ascii_control_char(char x) { } if (([self hasMarkedText] || previous_has_marked_text) && !_glfw.ns.text[0]) { // do not pass keys like BACKSPACE while there's pre-edit text, let IME handle it - debug_key("Ignoring key press as IME is active and it generated no text\n"); + debug_input("Ignoring key press as IME is active and it generated no text\n"); return; } } @@ -1406,7 +1406,7 @@ is_modifier_pressed(NSUInteger flags, NSUInteger target_mask, NSUInteger other_m } #undef action_for GLFWkeyevent glfw_keyevent = {.key = key, .native_key = keycode, .native_key_id = keycode, .action = action, .mods = mods}; - debug_key("\x1b[33mflagsChanged:\x1b[m modifier: %s native_key: 0x%x (%s) glfw_key: 0x%x %s\n", + debug_input("\x1b[33mflagsChanged:\x1b[m modifier: %s native_key: 0x%x (%s) glfw_key: 0x%x %s\n", mod_name, keycode, safe_name_for_keycode(keycode), key, format_mods(mods)); marked_text_cleared_by_insert = false; if (process_text && input_context) { @@ -1415,7 +1415,7 @@ is_modifier_pressed(NSUInteger flags, NSUInteger target_mask, NSUInteger other_m [input_context handleEvent:event]; in_key_handler = 0; if (marked_text_cleared_by_insert) { - debug_key("Clearing pre-edit text because insertText called from flagsChanged\n"); + debug_input("Clearing pre-edit text because insertText called from flagsChanged\n"); CLEAR_PRE_EDIT_TEXT; if (_glfw.ns.text[0]) glfw_keyevent.text = _glfw.ns.text; else _glfw.ns.text[0] = old_first_char; @@ -1433,7 +1433,7 @@ is_modifier_pressed(NSUInteger flags, NSUInteger target_mask, NSUInteger other_m GLFWkeyevent glfw_keyevent = {.key = key, .native_key = keycode, .native_key_id = 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", + debug_input("\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); } @@ -1827,12 +1827,12 @@ _glfwPlatformEndDrop(GLFWwindow *w UNUSED, GLFWDragOperationType op UNUSED) { replacementRange:(NSRange)replacementRange { const char *s = polymorphic_string_as_utf8(string); - debug_key("\n\tsetMarkedText: %s selectedRange: (%lu, %lu) replacementRange: (%lu, %lu)\n", s, selectedRange.location, selectedRange.length, replacementRange.location, replacementRange.length); + debug_input("\n\tsetMarkedText: %s selectedRange: (%lu, %lu) replacementRange: (%lu, %lu)\n", s, selectedRange.location, selectedRange.length, replacementRange.location, replacementRange.length); if (string == nil || !s[0]) { bool had_marked_text = [self hasMarkedText]; [self unmarkText]; if (had_marked_text && (!in_key_handler || in_key_handler == 2)) { - debug_key("Clearing pre-edit because setMarkedText called from %s\n", in_key_handler ? "flagsChanged" : "event loop"); + debug_input("Clearing pre-edit because setMarkedText called from %s\n", in_key_handler ? "flagsChanged" : "event loop"); GLFWkeyevent glfw_keyevent = {.ime_state = GLFW_IME_PREEDIT_CHANGED}; _glfwInputKeyboard(window, &glfw_keyevent); _glfw.ns.text[0] = 0; @@ -1849,7 +1849,7 @@ _glfwPlatformEndDrop(GLFWwindow *w UNUSED, GLFWDragOperationType op UNUSED) { markedText = [[NSMutableAttributedString alloc] initWithString:string]; } if (!in_key_handler || in_key_handler == 2) { - debug_key("Updating IME text in kitty from setMarkedText called from %s: %s\n", in_key_handler ? "flagsChanged" : "event loop", _glfw.ns.text); + debug_input("Updating IME text in kitty from setMarkedText called from %s: %s\n", in_key_handler ? "flagsChanged" : "event loop", _glfw.ns.text); GLFWkeyevent glfw_keyevent = {.text=[[markedText string] UTF8String], .ime_state = GLFW_IME_PREEDIT_CHANGED}; _glfwInputKeyboard(window, &glfw_keyevent); _glfw.ns.text[0] = 0; @@ -1909,7 +1909,7 @@ void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) { const CGFloat top = (CGFloat)ev.cursor.top / window->ns.yscale; const CGFloat cellWidth = (CGFloat)ev.cursor.width / window->ns.xscale; const CGFloat cellHeight = (CGFloat)ev.cursor.height / window->ns.yscale; - debug_key("updateIMEPosition: left=%f, top=%f, width=%f, height=%f\n", left, top, cellWidth, cellHeight); + debug_input("updateIMEPosition: left=%f, top=%f, width=%f, height=%f\n", left, top, cellWidth, cellHeight); const NSRect frame = [window->ns.view frame]; const NSRect rectInView = NSMakeRect(left, frame.size.height - top - cellHeight, @@ -1923,12 +1923,12 @@ void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) { - (void)insertText:(id)string replacementRange:(NSRange)replacementRange { const char *utf8 = polymorphic_string_as_utf8(string); - debug_key("\n\tinsertText: %s replacementRange: (%lu, %lu)\n", utf8, replacementRange.location, replacementRange.length); + debug_input("\n\tinsertText: %s replacementRange: (%lu, %lu)\n", utf8, replacementRange.location, replacementRange.length); if ([self hasMarkedText] && !is_ascii_control_char(utf8[0])) { [self unmarkText]; marked_text_cleared_by_insert = true; if (!in_key_handler) { - debug_key("Clearing pre-edit because insertText called from event loop\n"); + debug_input("Clearing pre-edit because insertText called from event loop\n"); GLFWkeyevent glfw_keyevent = {.ime_state = GLFW_IME_PREEDIT_CHANGED}; _glfwInputKeyboard(window, &glfw_keyevent); _glfw.ns.text[0] = 0; @@ -1943,7 +1943,7 @@ void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) { _glfw.ns.text[sizeof(_glfw.ns.text) - 1] = 0; if ((!in_key_handler || in_key_handler == 2) && _glfw.ns.text[0]) { if (!is_ascii_control_char(_glfw.ns.text[0])) { - debug_key("Sending text to kitty from insertText called from %s: %s\n", in_key_handler ? "flagsChanged" : "event loop", _glfw.ns.text); + debug_input("Sending text to kitty from insertText called from %s: %s\n", in_key_handler ? "flagsChanged" : "event loop", _glfw.ns.text); GLFWkeyevent glfw_keyevent = {.text=_glfw.ns.text, .ime_state=GLFW_IME_COMMIT_TEXT}; _glfwInputKeyboard(window, &glfw_keyevent); } @@ -1954,7 +1954,7 @@ void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) { - (void)doCommandBySelector:(SEL)selector { - debug_key("\n\tdoCommandBySelector: (%s)\n", [NSStringFromSelector(selector) UTF8String]); + debug_input("\n\tdoCommandBySelector: (%s)\n", [NSStringFromSelector(selector) UTF8String]); if (forward_dictation_selector_to_app(selector, self)) return; } @@ -2052,7 +2052,7 @@ void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) { // When dictation or other accessibility features set text, insert it as keyboard input if (value && [value length] > 0 && window) { const char *utf8 = [value UTF8String]; - debug_key("Inserting text via setAccessibilityValue: %s\n", utf8); + debug_input("Inserting text via setAccessibilityValue: %s\n", utf8); GLFWkeyevent glfw_keyevent = {.text=utf8, .ime_state=GLFW_IME_COMMIT_TEXT}; _glfwInputKeyboard(window, &glfw_keyevent); } @@ -2109,7 +2109,7 @@ void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) { if (text && [text length] > 0) { // The service wants us to replace the selection, but we can't replace anything but insert text. const char *utf8 = polymorphic_string_as_utf8(text); - debug_key("Sending text received in readSelectionFromPasteboard as key event\n"); + debug_input("Sending text received in readSelectionFromPasteboard as key event\n"); GLFWkeyevent glfw_keyevent = {.text=utf8, .ime_state=GLFW_IME_COMMIT_TEXT}; _glfwInputKeyboard(window, &glfw_keyevent); // Restore pre-edit text after inserting the received text @@ -4170,6 +4170,7 @@ static NSMutableArray *file_promise_providers willBeginAtPoint:(NSPoint)screenPoint { (void)session; + debug_input("Dragging session started at: (%f, %f)\n", screenPoint.x, screenPoint.y); start_point = screenPoint; } @@ -4177,15 +4178,40 @@ static NSMutableArray *file_promise_providers movedToPoint:(NSPoint)screenPoint { (void)session; + debug_input("Dragging session moved to: (%f, %f)\n", screenPoint.x, screenPoint.y); current_point = screenPoint; } +NSString* +NSStringFromDragOperation(NSDragOperation operation) { + // Check explicit presets first + if (operation == NSDragOperationNone) return @"None"; + if (operation == NSDragOperationEvery) return @"Every"; + + NSMutableArray *descriptions = [NSMutableArray array]; + + // Evaluate individual bitwise flags + if (operation & NSDragOperationCopy) [descriptions addObject:@"Copy"]; + if (operation & NSDragOperationLink) [descriptions addObject:@"Link"]; + if (operation & NSDragOperationGeneric) [descriptions addObject:@"Generic"]; + if (operation & NSDragOperationPrivate) [descriptions addObject:@"Private"]; + if (operation & NSDragOperationMove) [descriptions addObject:@"Move"]; + if (operation & NSDragOperationDelete) [descriptions addObject:@"Delete"]; + + // Fallback for undefined or custom masks + if (descriptions.count == 0) { + return [NSString stringWithFormat:@"Unknown (%lu)", (unsigned long)operation]; + } + + return [descriptions componentsJoinedByString:@", "]; +} - (void)draggingSession:(NSDraggingSession *)session endedAtPoint:(NSPoint)screenPoint operation:(NSDragOperation)operation { (void)session; + debug_input("Dragging session ended at: (%f, %f) with operation: %s\n", screenPoint.x, screenPoint.y, [NSStringFromDragOperation(operation) UTF8String]); _glfwPlatformFreeDragSourceData(); _GLFWwindow *window = _glfwWindowForId(_glfw.drag.window_id); if (window) {