diff --git a/docs/changelog.rst b/docs/changelog.rst index c1d04cda1..6ec91e9cf 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -112,6 +112,9 @@ Detailed list of changes - Linux: Fix fontconfig alias not being used if the aliased font is dual spaced instead of monospaced (:iss:`4649`) +- macOS: Add an option :opt:`macos_menubar_title_max_length` to control the max length of the window title displayed in the global menubar (:iss:`2132`) + + 0.24.2 [2022-02-03] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/kitty/cocoa_window.m b/kitty/cocoa_window.m index 9abdbda26..a01b78d3a 100644 --- a/kitty/cocoa_window.m +++ b/kitty/cocoa_window.m @@ -671,7 +671,15 @@ cocoa_create_global_menu(void) { void cocoa_update_menu_bar_title(PyObject *pytitle) { - NSString *title = @(PyUnicode_AsUTF8(pytitle)); + NSString *title = nil; + if (OPT(macos_menubar_title_max_length) > 0 && PyUnicode_GetLength(pytitle) > OPT(macos_menubar_title_max_length)) { + static char buf[2048]; + snprintf(buf, sizeof(buf), "%*.*s…", (int)OPT(macos_menubar_title_max_length), (int)OPT(macos_menubar_title_max_length), PyUnicode_AsUTF8(pytitle)); + title = @(buf); + } else { + title = @(PyUnicode_AsUTF8(pytitle)); + } + if (!title) return; NSMenu *bar = [NSApp mainMenu]; if (title_menu != NULL) { [bar removeItem:title_menu]; diff --git a/kitty/options/definition.py b/kitty/options/definition.py index 64be54704..a55ed094e 100644 --- a/kitty/options/definition.py +++ b/kitty/options/definition.py @@ -2829,9 +2829,14 @@ Show or hide the window title in the macOS window or menu-bar. A value of the macOS window. A value of :code:`menubar` will show the title of the currently active window in the macOS menu-bar, making use of otherwise wasted space. :code:`all` will show the title everywhere and :code:`none` hides the -title in the window and the menu-bar. -''' - ) +title in the window and the menu-bar. See :opt`macos_menubar_title_max_length` +for how to control the length of the title in the menu bar. +''') + +opt('macos_menubar_title_max_length', '0', option_type='positive_int', ctype='int', long_text=''' +The maximum number of characters from the window title to show in the global menubar. +Values less than one mean there is no maximum. +''') opt('macos_custom_beam_cursor', 'no', option_type='to_bool', diff --git a/kitty/options/parse.py b/kitty/options/parse.py index 950b08c76..2fba9509a 100644 --- a/kitty/options/parse.py +++ b/kitty/options/parse.py @@ -1029,6 +1029,9 @@ class Parser: def macos_hide_from_tasks(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: ans['macos_hide_from_tasks'] = to_bool(val) + def macos_menubar_title_max_length(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: + ans['macos_menubar_title_max_length'] = int(val) + def macos_option_as_alt(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: ans['macos_option_as_alt'] = macos_option_as_alt(val) diff --git a/kitty/options/to-c-generated.h b/kitty/options/to-c-generated.h index 0a73238fa..3a4c24401 100644 --- a/kitty/options/to-c-generated.h +++ b/kitty/options/to-c-generated.h @@ -980,6 +980,19 @@ convert_from_opts_macos_show_window_title_in(PyObject *py_opts, Options *opts) { Py_DECREF(ret); } +static void +convert_from_python_macos_menubar_title_max_length(PyObject *val, Options *opts) { + opts->macos_menubar_title_max_length = PyLong_AsLong(val); +} + +static void +convert_from_opts_macos_menubar_title_max_length(PyObject *py_opts, Options *opts) { + PyObject *ret = PyObject_GetAttrString(py_opts, "macos_menubar_title_max_length"); + if (ret == NULL) return; + convert_from_python_macos_menubar_title_max_length(ret, opts); + Py_DECREF(ret); +} + static bool convert_opts_from_python_opts(PyObject *py_opts, Options *opts) { convert_from_opts_font_size(py_opts, opts); @@ -1132,5 +1145,7 @@ convert_opts_from_python_opts(PyObject *py_opts, Options *opts) { if (PyErr_Occurred()) return false; convert_from_opts_macos_show_window_title_in(py_opts, opts); if (PyErr_Occurred()) return false; + convert_from_opts_macos_menubar_title_max_length(py_opts, opts); + if (PyErr_Occurred()) return false; return true; } diff --git a/kitty/options/types.py b/kitty/options/types.py index 7c24407c0..d002d37a1 100644 --- a/kitty/options/types.py +++ b/kitty/options/types.py @@ -370,6 +370,7 @@ option_names = ( # {{{ 'listen_on', 'macos_custom_beam_cursor', 'macos_hide_from_tasks', + 'macos_menubar_title_max_length', 'macos_option_as_alt', 'macos_quit_when_last_window_closed', 'macos_show_window_title_in', @@ -516,6 +517,7 @@ class Options: listen_on: str = 'none' macos_custom_beam_cursor: bool = False macos_hide_from_tasks: bool = False + macos_menubar_title_max_length: int = -1 macos_option_as_alt: int = 0 macos_quit_when_last_window_closed: bool = False macos_show_window_title_in: choices_for_macos_show_window_title_in = 'all' @@ -571,7 +573,7 @@ class Options: update_check_interval: float = 24.0 url_color: Color = Color(0, 135, 189) url_excluded_characters: str = '' - url_prefixes: typing.Tuple[str, ...] = ('http', 'https', 'file', 'ftp', 'gemini', 'irc', 'gopher', 'mailto', 'news', 'git') + url_prefixes: typing.Tuple[str, ...] = ('file', 'ftp', 'ftps', 'gemini', 'git', 'gopher', 'http', 'https', 'irc', 'ircs', 'kitty', 'mailto', 'news', 'sftp', 'ssh') url_style: int = 3 visual_bell_color: typing.Optional[kitty.fast_data_types.Color] = None visual_bell_duration: float = 0 diff --git a/kitty/state.h b/kitty/state.h index 43dc7c96e..1ba2c531b 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -80,6 +80,7 @@ typedef struct { struct { double outer, inner; } tab_bar_margin_height; + long macos_menubar_title_max_length; } Options; typedef struct WindowLogoRenderData {