From e31ca68875f1fbaabab9c8e8c4035b2d04438bb5 Mon Sep 17 00:00:00 2001 From: pagedown Date: Sun, 6 Feb 2022 19:51:39 +0800 Subject: [PATCH] macOS: Add a way to set kitty as the default handler for the URL schemes --- docs/open_actions.rst | 10 ++++++++++ kitty/cocoa_window.m | 26 ++++++++++++++++++++++++++ kitty/fast_data_types.pyi | 2 ++ 3 files changed, 38 insertions(+) diff --git a/docs/open_actions.rst b/docs/open_actions.rst index f2a4f12a6..67b10b57f 100644 --- a/docs/open_actions.rst +++ b/docs/open_actions.rst @@ -120,6 +120,16 @@ These actions can also be executed from the command line by running:: or kitty +open file_or_url ... +Since macOS lacks an official interface to set default URL scheme handler, you +can set it with the following command. The first argument for +``cocoa_set_url_handler`` is the URL scheme, and the second optional argument is +the bundle id of the app, which defaults to kitty's. (Restores when the second +argument is an empty string.) + +.. code-block:: sh + + kitty +runpy 'from kitty.fast_data_types import cocoa_set_url_handler; print(cocoa_set_url_handler("ssh", "net.kovidgoyal.kitty"));' + You can customize these actions by creating a :file:`launch-actions.conf` file in the kitty config directory, just like the :file:`open-actions.conf` file above. For example: diff --git a/kitty/cocoa_window.m b/kitty/cocoa_window.m index bfe25af42..08374efd6 100644 --- a/kitty/cocoa_window.m +++ b/kitty/cocoa_window.m @@ -829,6 +829,31 @@ cocoa_set_titlebar_color(void *w, color_type titlebar_color) } // autoreleasepool } +static PyObject* +cocoa_set_url_handler(PyObject UNUSED *self, PyObject *args) { + @autoreleasepool { + + const char *url_scheme = NULL, *bundle_id = NULL; + if (!PyArg_ParseTuple(args, "s|z", &url_scheme, &bundle_id)) return NULL; + if (!url_scheme || url_scheme[0] == '\0') Py_RETURN_FALSE; + + NSString *scheme = [NSString stringWithUTF8String:url_scheme]; + NSString *identifier = @""; + if (!bundle_id) { + identifier = [[NSBundle mainBundle] bundleIdentifier]; + if (!identifier || identifier.length == 0) identifier = @"net.kovidgoyal.kitty"; + } else if (bundle_id[0] != '\0') { + identifier = [NSString stringWithUTF8String:bundle_id]; + } + // This API has been marked as deprecated. It will need to be replaced when a new approach is available. + if (LSSetDefaultHandlerForURLScheme((CFStringRef)scheme, (CFStringRef)identifier) == noErr) { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; + + } // autoreleasepool +} + static NSSound *beep_sound = nil; static void @@ -878,6 +903,7 @@ static PyMethodDef module_methods[] = { {"cocoa_set_global_shortcut", (PyCFunction)cocoa_set_global_shortcut, METH_VARARGS, ""}, {"cocoa_send_notification", (PyCFunction)cocoa_send_notification, METH_VARARGS, ""}, {"cocoa_set_notification_activated_callback", (PyCFunction)set_notification_activated_callback, METH_O, ""}, + {"cocoa_set_url_handler", (PyCFunction)cocoa_set_url_handler, METH_VARARGS, ""}, {NULL, NULL, 0, NULL} /* Sentinel */ }; diff --git a/kitty/fast_data_types.pyi b/kitty/fast_data_types.pyi index 351a67b38..dc2f3e924 100644 --- a/kitty/fast_data_types.pyi +++ b/kitty/fast_data_types.pyi @@ -737,6 +737,8 @@ def cocoa_set_global_shortcut(name: str, mods: int, key: int) -> bool: def cocoa_get_lang() -> Optional[str]: pass +def cocoa_set_url_handler(url_scheme: str, bundle_id: Optional[str]) -> bool: + pass def locale_is_valid(name: str) -> bool: pass