From 59afdfc4e9136d3868f087052532393d5a590563 Mon Sep 17 00:00:00 2001 From: pagedown Date: Sun, 20 Mar 2022 14:51:47 +0800 Subject: [PATCH] macOS: Allow the New kitty Here services to open multiple folders --- docs/changelog.rst | 2 ++ kitty/boss.py | 18 ++++++++++++------ kitty/child-monitor.c | 13 +++++++++++-- kitty/cocoa_window.m | 17 ++++++++++------- 4 files changed, 35 insertions(+), 15 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 11c131cff..92b30f52c 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -53,6 +53,8 @@ Detailed list of changes - Fix continued lines not having their continued status reset on line feed (:iss:`4837`) +- macOS: Allow the New kitty Tab/Window Here services to open multiple selected folders. (:pull:`4848`) + 0.24.4 [2022-03-03] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/kitty/boss.py b/kitty/boss.py index 2c6b78064..69e652a04 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -463,9 +463,12 @@ class Boss: w = self.active_window_for_cwd self._new_os_window(args, CwdRequest(w)) - def new_os_window_with_wd(self, wd: str) -> None: - special_window = SpecialWindow(None, cwd=wd) - self._new_os_window(special_window) + def new_os_window_with_wd(self, wd: Union[str, List[str]]) -> None: + if isinstance(wd, str): + wd = [wd] + for path in wd: + special_window = SpecialWindow(None, cwd=path) + self._new_os_window(special_window) def add_child(self, window: Window) -> None: assert window.child.pid is not None and window.child.child_fd is not None @@ -1848,11 +1851,14 @@ class Boss: def new_tab_with_cwd(self, *args: str) -> None: self._create_tab(list(args), cwd_from=CwdRequest(self.active_window_for_cwd)) - def new_tab_with_wd(self, wd: str) -> None: + def new_tab_with_wd(self, wd: Union[str, List[str]]) -> None: if not self.os_window_map: self.add_os_window() - special_window = SpecialWindow(None, cwd=wd) - self._new_tab(special_window) + if isinstance(wd, str): + wd = [wd] + for path in wd: + special_window = SpecialWindow(None, cwd=path) + self._new_tab(special_window) def _new_window(self, args: List[str], cwd_from: Optional[CwdRequest] = None) -> Optional[Window]: tab = self.active_tab diff --git a/kitty/child-monitor.c b/kitty/child-monitor.c index 04959c57f..a4dc767bb 100644 --- a/kitty/child-monitor.c +++ b/kitty/child-monitor.c @@ -1041,8 +1041,17 @@ process_cocoa_pending_actions(void) { if (cocoa_pending_actions[TOGGLE_MACOS_SECURE_KEYBOARD_ENTRY]) { call_boss(toggle_macos_secure_keyboard_entry, NULL); } if (cocoa_pending_actions[TOGGLE_FULLSCREEN]) { call_boss(toggle_fullscreen, NULL); } if (cocoa_pending_actions_data.wd) { - if (cocoa_pending_actions[NEW_OS_WINDOW_WITH_WD]) { call_boss(new_os_window_with_wd, "s", cocoa_pending_actions_data.wd); } - if (cocoa_pending_actions[NEW_TAB_WITH_WD]) { call_boss(new_tab_with_wd, "s", cocoa_pending_actions_data.wd); } +#define C(a, f) \ + if (cocoa_pending_actions[a]) { \ + PyObject *wds = PyUnicode_FromString(cocoa_pending_actions_data.wd); \ + PyObject *sep = PyUnicode_FromString(":"); \ + PyObject *paths = PyUnicode_Split(wds, sep, -1); \ + call_boss(f, "O", paths); \ + Py_DECREF(paths); Py_DECREF(sep); Py_DECREF(wds); \ + } + C(NEW_OS_WINDOW_WITH_WD, new_os_window_with_wd); + C(NEW_TAB_WITH_WD, new_tab_with_wd); +#undef C free(cocoa_pending_actions_data.wd); cocoa_pending_actions_data.wd = NULL; } diff --git a/kitty/cocoa_window.m b/kitty/cocoa_window.m index 37ea98a80..7eb0924da 100644 --- a/kitty/cocoa_window.m +++ b/kitty/cocoa_window.m @@ -499,27 +499,30 @@ cocoa_send_notification(PyObject *self UNUSED, PyObject *args) { - (BOOL)openTab:(NSPasteboard*)pasteboard userData:(NSString *) UNUSED userData error:(NSError **) UNUSED error { - return [self openFilesFromPasteboard:pasteboard type:NEW_TAB_WITH_WD]; + return [self openDirsFromPasteboard:pasteboard type:NEW_TAB_WITH_WD]; } - (BOOL)openOSWindow:(NSPasteboard*)pasteboard userData:(NSString *) UNUSED userData error:(NSError **) UNUSED error { - return [self openFilesFromPasteboard:pasteboard type:NEW_OS_WINDOW_WITH_WD]; + return [self openDirsFromPasteboard:pasteboard type:NEW_OS_WINDOW_WITH_WD]; } -- (BOOL)openFilesFromPasteboard:(NSPasteboard *)pasteboard type:(int)type { +- (BOOL)openDirsFromPasteboard:(NSPasteboard *)pasteboard type:(int)type { NSDictionary *options = @{ NSPasteboardURLReadingFileURLsOnlyKey: @YES }; NSArray *filePathArray = [pasteboard readObjectsForClasses:[NSArray arrayWithObject:[NSURL class]] options:options]; + NSMutableArray *dirPathArray = [NSMutableArray arrayWithCapacity:[filePathArray count]]; for (NSURL *url in filePathArray) { NSString *path = [url path]; BOOL isDirectory = NO; if ([[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDirectory]) { - if (!isDirectory) { - path = [path stringByDeletingLastPathComponent]; - } - set_cocoa_pending_action(type, [path UTF8String]); + if (!isDirectory) path = [path stringByDeletingLastPathComponent]; + if (![dirPathArray containsObject:path]) [dirPathArray addObject:path]; } } + if ([dirPathArray count] > 0) { + // Colons are not valid in paths under macOS. + set_cocoa_pending_action(type, [[dirPathArray componentsJoinedByString:@":"] UTF8String]); + } return YES; }