diff --git a/kitty/cocoa_window.m b/kitty/cocoa_window.m index 713d228bb..bfefdbfd1 100644 --- a/kitty/cocoa_window.m +++ b/kitty/cocoa_window.m @@ -23,8 +23,6 @@ typedef void* rusage_info_t; // needed for libproc.h #endif static NSMenuItem* title_menu = NULL; -static bool change_titlebar_color = false; -static color_type titlebar_color = 0; static NSString* @@ -207,37 +205,14 @@ cwd_of_process(PyObject *self UNUSED, PyObject *pid_) { return PyUnicode_FromString(vpi.pvi_cdir.vip_path); } -static inline color_type -color_as_int(PyObject *color) { -#define I(n, s) ((PyLong_AsUnsignedLong(PyTuple_GET_ITEM(color, n)) & 0xff) << s) - return (I(0, 16) | I(1, 8) | I(2, 0)) & 0xffffff; -#undef I -} - -static PyObject* -macos_change_titlebar_color(PyObject *self UNUSED, PyObject *val) { - if (val == Py_None) change_titlebar_color = false; - else if (val == Py_True) { - change_titlebar_color = true; - titlebar_color = OPT(background); - } else { - if (!PyTuple_Check(val)) { PyErr_SetString(PyExc_TypeError, "Not a color tuple"); return NULL; } - change_titlebar_color = true; - titlebar_color = color_as_int(val); - } - Py_RETURN_NONE; -} - void cocoa_set_hide_from_tasks(void) { [NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory]; } void -cocoa_set_titlebar_color(void *w) +cocoa_set_titlebar_color(void *w, color_type titlebar_color) { - if (!change_titlebar_color) return; - NSWindow *window = (NSWindow *)w; double red = ((titlebar_color >> 16) & 0xFF) / 255.0; @@ -264,7 +239,6 @@ cocoa_set_titlebar_color(void *w) static PyMethodDef module_methods[] = { {"cocoa_get_lang", (PyCFunction)cocoa_get_lang, METH_NOARGS, ""}, {"cwd_of_process", (PyCFunction)cwd_of_process, METH_O, ""}, - {"macos_change_titlebar_color", (PyCFunction)macos_change_titlebar_color, METH_O, ""}, {NULL, NULL, 0, NULL} /* Sentinel */ }; diff --git a/kitty/config.py b/kitty/config.py index 7e6178eeb..d78a47e52 100644 --- a/kitty/config.py +++ b/kitty/config.py @@ -19,7 +19,7 @@ from .config_utils import ( from .constants import cache_dir, defconf from .fast_data_types import CURSOR_BEAM, CURSOR_BLOCK, CURSOR_UNDERLINE from .layout import all_layouts -from .rgb import color_from_int +from .rgb import color_as_int, color_from_int from .utils import log_error MINIMUM_FONT_SIZE = 4 @@ -265,10 +265,10 @@ def adjust_line_height(x): def macos_titlebar_color(x): x = x.strip('"') if x == 'system': - return + return 0 if x == 'background': - return True - return to_color(x) + return 1 + return (color_as_int(to_color(x)) << 8) | 2 def box_drawing_scale(x): diff --git a/kitty/glfw.c b/kitty/glfw.c index 1bae1dbd9..f1b4a59d5 100644 --- a/kitty/glfw.c +++ b/kitty/glfw.c @@ -10,7 +10,7 @@ extern bool cocoa_make_window_resizable(void *w); extern void cocoa_create_global_menu(void); extern void cocoa_set_hide_from_tasks(void); -extern void cocoa_set_titlebar_color(void *w); +extern void cocoa_set_titlebar_color(void *w, color_type color); #if GLFW_KEY_LAST >= MAX_KEY_COUNT #error "glfw has too many keys, you should increase MAX_KEY_COUNT" @@ -317,6 +317,16 @@ filter_option(int key UNUSED, int mods, unsigned int scancode UNUSED) { } #endif +void +set_titlebar_color(OSWindow *w, color_type color) { + if (w->handle && (!w->last_titlebar_color || (w->last_titlebar_color & 0xffffff) != (color & 0xffffff))) { + w->last_titlebar_color = (1 << 24) | (color & 0xffffff); +#ifdef __APPLE__ + cocoa_set_titlebar_color(glfwGetCocoaWindow(w->handle), color); +#endif + } +} + static PyObject* create_os_window(PyObject UNUSED *self, PyObject *args) { int width, height, x = -1, y = -1; @@ -406,7 +416,6 @@ create_os_window(PyObject UNUSED *self, PyObject *args) { if (glfwGetCocoaWindow) { if (!cocoa_make_window_resizable(glfwGetCocoaWindow(glfw_window))) { PyErr_Print(); } } else log_error("Failed to load glfwGetCocoaWindow"); } - cocoa_set_titlebar_color(glfwGetCocoaWindow(glfw_window)); #endif double now = monotonic(); w->is_focused = true; diff --git a/kitty/main.py b/kitty/main.py index 85128b55b..a810f6d5c 100644 --- a/kitty/main.py +++ b/kitty/main.py @@ -39,9 +39,6 @@ def init_graphics(): def run_app(opts, args): set_scale(opts.box_drawing_scale) set_options(opts, is_wayland, args.debug_gl, args.debug_font_fallback) - if is_macos: - from .fast_data_types import macos_change_titlebar_color - macos_change_titlebar_color(opts.macos_titlebar_color) with cached_values_for('main') as cached_values: w, h = initial_window_size(opts, cached_values) window_id = create_os_window(w, h, appname, args.name or args.cls or appname, args.cls or appname, load_all_shaders) diff --git a/kitty/state.c b/kitty/state.c index 93a5e7f00..8fedbcd53 100644 --- a/kitty/state.c +++ b/kitty/state.c @@ -478,6 +478,17 @@ PYWRAP1(mark_os_window_for_close) { Py_RETURN_FALSE; } +PYWRAP1(set_titlebar_color) { + id_type os_window_id; + unsigned int color; + PA("KI", &os_window_id, &color); + WITH_OS_WINDOW(os_window_id) + set_titlebar_color(os_window, color); + Py_RETURN_TRUE; + END_WITH_OS_WINDOW + Py_RETURN_FALSE; +} + static inline bool fix_window_idx(Tab *tab, id_type window_id, unsigned int *window_idx) { for (id_type fix = 0; fix < tab->num_windows; fix++) { @@ -602,6 +613,7 @@ static PyMethodDef module_methods[] = { MW(set_window_render_data, METH_VARARGS), MW(viewport_for_window, METH_VARARGS), MW(mark_os_window_for_close, METH_VARARGS), + MW(set_titlebar_color, METH_VARARGS), MW(update_window_visibility, METH_VARARGS), MW(set_boss, METH_O), MW(set_display_state, METH_VARARGS), diff --git a/kitty/state.h b/kitty/state.h index 2914bf6cf..a8ebc323d 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -116,6 +116,7 @@ typedef struct { bool has_pending_resizes, is_semi_transparent, shown_once, is_damaged; uint32_t offscreen_texture_id; unsigned int clear_count; + color_type last_titlebar_color; } OSWindow; @@ -180,3 +181,4 @@ void update_surface_size(int, int, uint32_t); void free_texture(uint32_t*); void send_image_to_gpu(uint32_t*, const void*, int32_t, int32_t, bool, bool); void send_sprite_to_gpu(unsigned int, unsigned int, unsigned int, pixel*); +void set_titlebar_color(OSWindow *w, color_type color); diff --git a/kitty/tabs.py b/kitty/tabs.py index 7f1a6fb10..e1e51fe1b 100644 --- a/kitty/tabs.py +++ b/kitty/tabs.py @@ -100,8 +100,11 @@ class Tab: # {{{ tm = self.tab_manager_ref() if tm is not None: visible_windows = [w for w in self.windows if w.is_visible_in_layout] - self.borders(visible_windows, self.active_window, self.current_layout, + w = self.active_window + self.borders(visible_windows, w, self.current_layout, tm.blank_rects, self.current_layout.needs_window_borders and len(visible_windows) > 1) + if w is not None: + w.change_titlebar_color() def create_layout_object(self, idx): return all_layouts[idx](self.os_window_id, self.id, self.opts, self.borders.border_width) diff --git a/kitty/window.py b/kitty/window.py index 55d65c307..5537ab311 100644 --- a/kitty/window.py +++ b/kitty/window.py @@ -18,8 +18,9 @@ from .fast_data_types import ( CELL_SPECIAL_PROGRAM, CSI, CURSOR_PROGRAM, DCS, GRAPHICS_PREMULT_PROGRAM, GRAPHICS_PROGRAM, OSC, SCROLL_FULL, SCROLL_LINE, SCROLL_PAGE, Screen, add_window, compile_program, glfw_post_empty_event, init_cell_program, - init_cursor_program, set_clipboard_string, set_window_render_data, - update_window_title, update_window_visibility, viewport_for_window + init_cursor_program, set_clipboard_string, set_titlebar_color, + set_window_render_data, update_window_title, update_window_visibility, + viewport_for_window ) from .keys import keyboard_mode_name from .rgb import to_color @@ -227,6 +228,15 @@ class Window: def icon_changed(self, new_icon): pass # TODO: Implement this + def change_titlebar_color(self): + val = self.opts.macos_titlebar_color + if val: + if (val & 0xff) == 1: + val = self.screen.color_profile.default_bg + else: + val = val >> 8 + set_titlebar_color(self.os_window_id, val) + def change_colors(self, changes): dirtied = default_bg_changed = False