diff --git a/docs/changelog.rst b/docs/changelog.rst index 9155ad0cf..6376e410e 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -24,6 +24,8 @@ To update |kitty|, :doc:`follow the instructions `. - Fix kitty @ send-text not working with text larger than 1024 bytes when using :option:`kitty --listen-on` (:iss:`2607`) +- Wayland: Fix OS window title not updating for hidden windows (:iss:`2629`) + 0.17.3 [2020-04-23] -------------------- diff --git a/kitty/child-monitor.c b/kitty/child-monitor.c index d08f01fde..6c89d3bb2 100644 --- a/kitty/child-monitor.c +++ b/kitty/child-monitor.c @@ -523,17 +523,6 @@ change_menubar_title(PyObject *title UNUSED) { #endif } -static inline bool -update_window_title(Window *w, OSWindow *os_window) { - if (w->title && w->title != os_window->window_title) { - os_window->window_title = w->title; - Py_INCREF(os_window->window_title); - set_os_window_title(os_window, PyUnicode_AsUTF8(w->title)); - return true; - } - return false; -} - static inline bool prepare_to_render_os_window(OSWindow *os_window, monotonic_t now, unsigned int *active_window_id, color_type *active_window_bg, unsigned int *num_visible_windows, bool *all_windows_have_same_bg) { #define TD os_window->tab_bar_render_data @@ -577,7 +566,7 @@ prepare_to_render_os_window(OSWindow *os_window, monotonic_t now, unsigned int * *active_window_id = w->id; collect_cursor_info(&WD.screen->cursor_render_info, w, now, os_window); if (w->cursor_visible_at_last_render != WD.screen->cursor_render_info.is_visible || w->last_cursor_x != WD.screen->cursor_render_info.x || w->last_cursor_y != WD.screen->cursor_render_info.y || w->last_cursor_shape != WD.screen->cursor_render_info.shape) needs_render = true; - update_window_title(w, os_window); + set_os_window_title_from_window(w, os_window); *active_window_bg = window_bg; } else WD.screen->cursor_render_info.is_visible = false; if (send_cell_data_to_gpu(WD.vao_idx, WD.gvao_idx, WD.xstart, WD.ystart, WD.dx, WD.dy, WD.screen, os_window)) needs_render = true; @@ -625,15 +614,6 @@ render_os_window(OSWindow *os_window, monotonic_t now, unsigned int active_windo #undef TD } -static inline void -update_os_window_title(OSWindow *os_window) { - Tab *tab = os_window->tabs + os_window->active_tab; - if (tab->num_windows) { - Window *w = tab->windows + tab->active_window; - update_window_title(w, os_window); - } -} - static void draw_resizing_text(OSWindow *w) { char text[32] = {0}; diff --git a/kitty/fast_data_types.pyi b/kitty/fast_data_types.pyi index b8762c467..5baa94da3 100644 --- a/kitty/fast_data_types.pyi +++ b/kitty/fast_data_types.pyi @@ -550,6 +550,10 @@ def update_window_visibility( pass +def sync_os_window_title(os_window_id: int) -> None: + pass + + def set_options( opts: Options, is_wayland: bool = False, diff --git a/kitty/state.c b/kitty/state.c index b6ba48923..98a58c4a9 100644 --- a/kitty/state.c +++ b/kitty/state.c @@ -214,6 +214,27 @@ update_window_title(id_type os_window_id, id_type tab_id, id_type window_id, PyO END_WITH_TAB; } +void +set_os_window_title_from_window(Window *w, OSWindow *os_window) { + if (w->title && w->title != os_window->window_title) { + Py_XDECREF(os_window->window_title); + os_window->window_title = w->title; + Py_INCREF(os_window->window_title); + set_os_window_title(os_window, PyUnicode_AsUTF8(w->title)); + } +} + +void +update_os_window_title(OSWindow *os_window) { + if (os_window->num_tabs) { + Tab *tab = os_window->tabs + os_window->active_tab; + if (tab->num_windows) { + Window *w = tab->windows + tab->active_window; + set_os_window_title_from_window(w, os_window); + } + } +} + static inline void destroy_window(Window *w) { Py_CLEAR(w->render_data.screen); Py_CLEAR(w->title); @@ -908,6 +929,17 @@ PYWRAP1(update_window_visibility) { Py_RETURN_NONE; } + +PYWRAP1(sync_os_window_title) { + id_type os_window_id; + PA("K", &os_window_id); + WITH_OS_WINDOW(os_window_id) + update_os_window_title(os_window); + END_WITH_OS_WINDOW + Py_RETURN_NONE; +} + + static inline double dpi_for_os_window_id(id_type os_window_id) { double dpi = 0; @@ -1121,6 +1153,7 @@ static PyMethodDef module_methods[] = { MW(change_background_opacity, METH_VARARGS), MW(background_opacity_of, METH_O), MW(update_window_visibility, METH_VARARGS), + MW(sync_os_window_title, METH_VARARGS), MW(global_font_size, METH_VARARGS), MW(set_background_image, METH_VARARGS), MW(os_window_font_size, METH_VARARGS), diff --git a/kitty/state.h b/kitty/state.h index af4dfe81b..5a6fac4bf 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -277,3 +277,5 @@ void update_main_loop_timer(id_type timer_id, monotonic_t interval, bool enabled void run_main_loop(tick_callback_fun, void*); void stop_main_loop(void); void os_window_update_size_increments(OSWindow *window); +void set_os_window_title_from_window(Window *w, OSWindow *os_window); +void update_os_window_title(OSWindow *os_window); diff --git a/kitty/tabs.py b/kitty/tabs.py index 7d8207d4f..cd0b320cd 100644 --- a/kitty/tabs.py +++ b/kitty/tabs.py @@ -18,7 +18,7 @@ from .constants import appname, is_macos, is_wayland from .fast_data_types import ( add_tab, attach_window, detach_window, get_boss, mark_tab_bar_dirty, next_window_id, remove_tab, remove_window, ring_bell, set_active_tab, - swap_tabs, x11_window_id + swap_tabs, sync_os_window_title, x11_window_id ) from .layout import ( Layout, Rect, create_layout_object_for, evict_cached_layouts @@ -206,7 +206,7 @@ class Tab: # {{{ if window is self.active_window: tm = self.tab_manager_ref() if tm is not None: - tm.mark_tab_bar_dirty() + tm.title_changed(self) def on_bell(self, window: Window) -> None: tm = self.tab_manager_ref() @@ -639,6 +639,11 @@ class TabManager: # {{{ def update_tab_bar_data(self) -> None: self.tab_bar.update(self.tab_bar_data) + def title_changed(self, tab: Tab) -> None: + self.mark_tab_bar_dirty() + if tab is self.active_tab: + sync_os_window_title(self.os_window_id) + def resize(self, only_tabs: bool = False) -> None: if not only_tabs: if not self.tab_bar_hidden: