From 6d6d9cc26b850f91148a0299f03bbe905a77311e Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 26 Apr 2022 11:14:01 +0530 Subject: [PATCH] macOS: Add the macos_colorspace option to control what color space colors are rendered in Fixed #4686 --- docs/changelog.rst | 2 ++ kitty/glfw-wrapper.h | 10 ++++++++++ kitty/glfw.c | 1 + kitty/options/definition.py | 10 ++++++++++ kitty/options/parse.py | 8 ++++++++ kitty/options/to-c-generated.h | 15 +++++++++++++++ kitty/options/to-c.h | 7 +++++++ kitty/options/types.py | 4 ++++ kitty/state.h | 1 + 9 files changed, 58 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index 55e6b9267..d0237ff99 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -55,6 +55,8 @@ Detailed list of changes - macOS: Make the global menu shortcut to open kitty website configurable (:pull:`5004`) +- macOS: Add the :opt:`macos_colorspace` option to control what color space colors are rendered in (:iss:`4686`) + 0.25.0 [2022-04-11] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/kitty/glfw-wrapper.h b/kitty/glfw-wrapper.h index 7bc8a1ce1..2230e8488 100644 --- a/kitty/glfw-wrapper.h +++ b/kitty/glfw-wrapper.h @@ -762,6 +762,16 @@ typedef enum GLFWMouseButton { * [window hint](@ref GLFW_COCOA_GRAPHICS_SWITCHING_hint). */ #define GLFW_COCOA_GRAPHICS_SWITCHING 0x00023003 +/*! @brief macOS specific + * [window hint](@ref GLFW_COCOA_COLOR_SPACE_hint). + */ +#define GLFW_COCOA_COLOR_SPACE 0x00023004 +typedef enum { + DEFAULT_COLORSPACE = 0, + SRGB_COLORSPACE = 1, + DISPLAY_P3_COLORSPACE = 2, +} GlfwCocoaColorSpaces; + /*! @brief X11 specific * [window hint](@ref GLFW_X11_CLASS_NAME_hint). */ diff --git a/kitty/glfw.c b/kitty/glfw.c index 1d6e3377b..32a5467d4 100644 --- a/kitty/glfw.c +++ b/kitty/glfw.c @@ -775,6 +775,7 @@ create_os_window(PyObject UNUSED *self, PyObject *args, PyObject *kw) { glfwWindowHintString(GLFW_X11_INSTANCE_NAME, wm_class_name); glfwWindowHintString(GLFW_X11_CLASS_NAME, wm_class_class); glfwWindowHintString(GLFW_WAYLAND_APP_ID, wm_class_class); + glfwWindowHint(GLFW_COCOA_COLOR_SPACE, OPT(macos_colorspace)); #endif if (global_state.num_os_windows >= MAX_CHILDREN) { diff --git a/kitty/options/definition.py b/kitty/options/definition.py index 6fb1dd2ae..c597fc0e3 100644 --- a/kitty/options/definition.py +++ b/kitty/options/definition.py @@ -3016,6 +3016,16 @@ dual GPU machines. Changing this option by reloading the config is not supported ''' ) +opt('macos_colorspace', 'srgb', choices=('srgb', 'default', 'displayp3'), ctype='macos_colorspace', + long_text=''' +The colorspace in which to interpret terminal colors. The default of :code:`srgb` will +cause colors to match those seen in web browsers. The value of :code:`default` will +use whatever the native colorspace of the display is. The value of :code:`displayp3` +will use Apple's special snowflake display P3 color space, which will result in over +saturated (brighter) colors with some color shift. +''') + + opt('linux_display_server', 'auto', choices=('auto', 'wayland', 'x11'), long_text=''' diff --git a/kitty/options/parse.py b/kitty/options/parse.py index cfa99f676..9eb4e557b 100644 --- a/kitty/options/parse.py +++ b/kitty/options/parse.py @@ -1035,6 +1035,14 @@ class Parser: def listen_on(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: ans['listen_on'] = str(val) + def macos_colorspace(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: + val = val.lower() + if val not in self.choices_for_macos_colorspace: + raise ValueError(f"The value {val} is not a valid choice for macos_colorspace") + ans["macos_colorspace"] = val + + choices_for_macos_colorspace = frozenset(('srgb', 'default', 'displayp3')) + def macos_custom_beam_cursor(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: ans['macos_custom_beam_cursor'] = to_bool(val) diff --git a/kitty/options/to-c-generated.h b/kitty/options/to-c-generated.h index 3706010c5..566e02aa8 100644 --- a/kitty/options/to-c-generated.h +++ b/kitty/options/to-c-generated.h @@ -1006,6 +1006,19 @@ convert_from_opts_macos_menubar_title_max_length(PyObject *py_opts, Options *opt Py_DECREF(ret); } +static void +convert_from_python_macos_colorspace(PyObject *val, Options *opts) { + opts->macos_colorspace = macos_colorspace(val); +} + +static void +convert_from_opts_macos_colorspace(PyObject *py_opts, Options *opts) { + PyObject *ret = PyObject_GetAttrString(py_opts, "macos_colorspace"); + if (ret == NULL) return; + convert_from_python_macos_colorspace(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); @@ -1162,5 +1175,7 @@ convert_opts_from_python_opts(PyObject *py_opts, Options *opts) { if (PyErr_Occurred()) return false; convert_from_opts_macos_menubar_title_max_length(py_opts, opts); if (PyErr_Occurred()) return false; + convert_from_opts_macos_colorspace(py_opts, opts); + if (PyErr_Occurred()) return false; return true; } diff --git a/kitty/options/to-c.h b/kitty/options/to-c.h index d568a1b32..78b09f202 100644 --- a/kitty/options/to-c.h +++ b/kitty/options/to-c.h @@ -127,6 +127,13 @@ pointer_shape(PyObject *shape_name) { return BEAM; } +static int +macos_colorspace(PyObject *csname) { + if (PyUnicode_CompareWithASCIIString(csname, "srgb")) return 1; + if (PyUnicode_CompareWithASCIIString(csname, "displayp3")) return 2; + return 0; +} + static inline void free_url_prefixes(void) { OPT(url_prefixes).num = 0; diff --git a/kitty/options/types.py b/kitty/options/types.py index bd3c8a3d7..348600484 100644 --- a/kitty/options/types.py +++ b/kitty/options/types.py @@ -17,6 +17,7 @@ if typing.TYPE_CHECKING: choices_for_background_image_layout = typing.Literal['mirror-tiled', 'scaled', 'tiled', 'clamped'] choices_for_default_pointer_shape = typing.Literal['arrow', 'beam', 'hand'] choices_for_linux_display_server = typing.Literal['auto', 'wayland', 'x11'] + choices_for_macos_colorspace = typing.Literal['srgb', 'default', 'displayp3'] choices_for_macos_show_window_title_in = typing.Literal['all', 'menubar', 'none', 'window'] choices_for_placement_strategy = typing.Literal['center', 'top-left'] choices_for_pointer_shape_when_dragging = typing.Literal['arrow', 'beam', 'hand'] @@ -32,6 +33,7 @@ else: choices_for_background_image_layout = str choices_for_default_pointer_shape = str choices_for_linux_display_server = str + choices_for_macos_colorspace = str choices_for_macos_show_window_title_in = str choices_for_placement_strategy = str choices_for_pointer_shape_when_dragging = str @@ -373,6 +375,7 @@ option_names = ( # {{{ 'kitty_mod', 'linux_display_server', 'listen_on', + 'macos_colorspace', 'macos_custom_beam_cursor', 'macos_hide_from_tasks', 'macos_menubar_title_max_length', @@ -525,6 +528,7 @@ class Options: kitty_mod: int = 5 linux_display_server: choices_for_linux_display_server = 'auto' listen_on: str = 'none' + macos_colorspace: choices_for_macos_colorspace = 'srgb' macos_custom_beam_cursor: bool = False macos_hide_from_tasks: bool = False macos_menubar_title_max_length: int = 0 diff --git a/kitty/state.h b/kitty/state.h index 53bf0352b..23d6b2f04 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -82,6 +82,7 @@ typedef struct { double outer, inner; } tab_bar_margin_height; long macos_menubar_title_max_length; + int macos_colorspace; } Options; typedef struct WindowLogoRenderData {