From 06c22636573fae88621a18263ec8e4b59cee4322 Mon Sep 17 00:00:00 2001 From: Luflosi Date: Fri, 23 Aug 2019 21:27:00 +0200 Subject: [PATCH] macOS: implement drag and drop of text into kitty Closes #1368. --- glfw/cocoa_window.m | 21 ++++++++++++++++----- kitty/boss.py | 4 ++-- kitty/glfw.c | 12 ++++++------ 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/glfw/cocoa_window.m b/glfw/cocoa_window.m index 9ee64081a..847000345 100644 --- a/glfw/cocoa_window.m +++ b/glfw/cocoa_window.m @@ -630,7 +630,7 @@ static GLFWapplicationshouldhandlereopenfun handle_reopen_callback = NULL; markedRect = NSMakeRect(0.0, 0.0, 0.0, 0.0); [self updateTrackingAreas]; - [self registerForDraggedTypes:@[NSPasteboardTypeFileURL]]; + [self registerForDraggedTypes:@[NSPasteboardTypeFileURL, NSPasteboardTypeString]]; } return self; @@ -1073,16 +1073,27 @@ is_ascii_control_char(char x) { NSPasteboard* pasteboard = [sender draggingPasteboard]; NSDictionary* options = @{NSPasteboardURLReadingFileURLsOnlyKey:@YES}; - NSArray* urls = [pasteboard readObjectsForClasses:@[[NSURL class]] + NSArray* objs = [pasteboard readObjectsForClasses:@[[NSURL class], [NSString class]] options:options]; - if (!urls) return NO; - const NSUInteger count = [urls count]; + if (!objs) return NO; + const NSUInteger count = [objs count]; if (count) { char** paths = calloc(count, sizeof(char*)); for (NSUInteger i = 0; i < count; i++) - paths[i] = _glfw_strdup([urls[i] fileSystemRepresentation]); + { + id obj = objs[i]; + if ([obj isKindOfClass:[NSURL class]]) { + paths[i] = _glfw_strdup([obj fileSystemRepresentation]); + } else if ([obj isKindOfClass:[NSString class]]) { + paths[i] = _glfw_strdup([obj UTF8String]); + } else { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Cocoa: Object is neither a URL nor a string"); + paths[i] = _glfw_strdup(""); + } + } _glfwInputDrop(window, (int) count, (const char**) paths); diff --git a/kitty/boss.py b/kitty/boss.py index e10422eca..76b4a6825 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -619,12 +619,12 @@ class Boss: if tm is not None: tm.update_tab_bar_data() - def on_drop(self, os_window_id, paths): + def on_drop(self, os_window_id, strings): tm = self.os_window_map.get(os_window_id) if tm is not None: w = tm.active_window if w is not None: - w.paste('\n'.join(paths)) + w.paste('\n'.join(strings)) def on_os_window_closed(self, os_window_id, viewport_width, viewport_height): self.cached_values['window-size'] = viewport_width, viewport_height diff --git a/kitty/glfw.c b/kitty/glfw.c index ab3556ccb..8a9da6774 100644 --- a/kitty/glfw.c +++ b/kitty/glfw.c @@ -319,13 +319,13 @@ window_focus_callback(GLFWwindow *w, int focused) { } static void -drop_callback(GLFWwindow *w, int count, const char **paths) { +drop_callback(GLFWwindow *w, int count, const char **strings) { if (!set_callback_window(w)) return; - PyObject *p = PyTuple_New(count); - if (p) { - for (int i = 0; i < count; i++) PyTuple_SET_ITEM(p, i, PyUnicode_FromString(paths[i])); - WINDOW_CALLBACK(on_drop, "O", p); - Py_CLEAR(p); + PyObject *s = PyTuple_New(count); + if (s) { + for (int i = 0; i < count; i++) PyTuple_SET_ITEM(s, i, PyUnicode_FromString(strings[i])); + WINDOW_CALLBACK(on_drop, "O", s); + Py_CLEAR(s); request_tick_callback(); } global_state.callback_os_window = NULL;