From 0a98d848dee7a0dc0dc6a7f6743f4cebbba9a29a Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 29 Jun 2024 11:07:02 +0530 Subject: [PATCH] Wayland redraw OS window twice after resize Needed on, for instance sway to get it to recognize that the framebuffer has been resized. --- kitty/child-monitor.c | 9 ++++++--- kitty/glfw.c | 4 ++-- kitty/state.c | 4 ++-- kitty/state.h | 4 ++-- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/kitty/child-monitor.c b/kitty/child-monitor.c index 6d2c343e7..e299a01f7 100644 --- a/kitty/child-monitor.c +++ b/kitty/child-monitor.c @@ -810,7 +810,7 @@ render_prepared_os_window(OSWindow *os_window, unsigned int active_window_id, co swap_window_buffers(os_window); os_window->last_active_tab = os_window->active_tab; os_window->last_num_tabs = os_window->num_tabs; os_window->last_active_window_id = active_window_id; os_window->focused_at_last_render = os_window->is_focused; - os_window->is_damaged = false; + if (os_window->redraw_count) os_window->redraw_count--; if (USE_RENDER_FRAMES) request_frame_render(os_window); #undef WD #undef TD @@ -848,7 +848,7 @@ render_os_window(OSWindow *w, monotonic_t now, bool ignore_render_frames, bool s w->render_calls++; make_os_window_context_current(w); if (w->live_resize.in_progress) blank_os_window(w); - bool needs_render = w->is_damaged || w->live_resize.in_progress; + bool needs_render = w->redraw_count > 0 || w->live_resize.in_progress; if (w->viewport_size_dirty) { w->clear_count = 0; update_surface_size(w->viewport_width, w->viewport_height, 0); @@ -1073,7 +1073,10 @@ process_pending_resizes(monotonic_t now) { update_os_window_viewport(w, true); change_live_resize_state(w, false); zero_at_ptr(&w->live_resize); - w->is_damaged = true; // because the window size should be hidden even if update_os_window_viewport does nothing + // because the window size should be hidden even if update_os_window_viewport does nothing + // On Wayland some compositors require two redraws after a + // resize to actually render correctly (Run kitty -1 --wait-for-os-window-close in sway to reproduce) + w->redraw_count = global_state.is_wayland ? 2 : 1; } } } diff --git a/kitty/glfw.c b/kitty/glfw.c index 23ed84da0..ff97d049e 100644 --- a/kitty/glfw.c +++ b/kitty/glfw.c @@ -362,7 +362,7 @@ dpi_change_callback(GLFWwindow *w, float x_scale UNUSED, float y_scale UNUSED) { static void refresh_callback(GLFWwindow *w) { if (!set_callback_window(w)) return; - global_state.callback_os_window->is_damaged = true; + if (!global_state.callback_os_window->redraw_count) global_state.callback_os_window->redraw_count++; global_state.callback_os_window = NULL; request_tick_callback(); } @@ -1330,7 +1330,7 @@ create_os_window(PyObject UNUSED *self, PyObject *args, PyObject *kw) { // macOS: Show the window after it is ready glfwShowWindow(glfw_window); #endif - w->is_damaged = true; + w->redraw_count = 1; debug("OS Window created\n"); return PyLong_FromUnsignedLongLong(w->id); } diff --git a/kitty/state.c b/kitty/state.c index 2890bb3c9..d321aa004 100644 --- a/kitty/state.c +++ b/kitty/state.c @@ -913,7 +913,7 @@ PYWRAP1(change_background_opacity) { PA("Kf", &os_window_id, &opacity); WITH_OS_WINDOW(os_window_id) os_window->background_opacity = opacity; - os_window->is_damaged = true; + if (!os_window->redraw_count) os_window->redraw_count++; Py_RETURN_TRUE; END_WITH_OS_WINDOW Py_RETURN_FALSE; @@ -1123,7 +1123,7 @@ PYWRAP0(apply_options_update) { OSWindow *os_window = global_state.os_windows + o; get_platform_dependent_config_values(os_window->handle); os_window->background_opacity = OPT(background_opacity); - os_window->is_damaged = true; + if (!os_window->redraw_count) os_window->redraw_count++; for (size_t t = 0; t < os_window->num_tabs; t++) { Tab *tab = os_window->tabs + t; for (size_t w = 0; w < tab->num_windows; w++) { diff --git a/kitty/state.h b/kitty/state.h index d8db29da3..b9b27f01d 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -254,8 +254,8 @@ typedef struct { bool viewport_size_dirty, viewport_updated_at_least_once; monotonic_t viewport_resized_at; LiveResizeInfo live_resize; - bool has_pending_resizes, is_semi_transparent, shown_once, is_damaged, ignore_resize_events; - unsigned int clear_count; + bool has_pending_resizes, is_semi_transparent, shown_once, ignore_resize_events; + unsigned int clear_count, redraw_count; WindowChromeState last_window_chrome; float background_opacity; FONTS_DATA_HANDLE fonts_data;