From 5662d04b2f971bae51ddf4873fad57f457c6b693 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 18 Aug 2025 11:17:40 +0530 Subject: [PATCH] Fix resized area background color not correct during live resize Have to write sRGB colors rather than linear colors in this case --- kitty/glfw.c | 18 +----------------- kitty/shaders.c | 33 ++++++++++++++++++++++++++++----- kitty/state.h | 2 +- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/kitty/glfw.c b/kitty/glfw.c index e82b53e1c..c4102056d 100644 --- a/kitty/glfw.c +++ b/kitty/glfw.c @@ -299,22 +299,6 @@ cursor_active_callback(GLFWwindow *w, monotonic_t now) { } } -void -blank_os_window(OSWindow *osw) { - color_type color = OPT(background); - if (osw->num_tabs > 0) { - Tab *t = osw->tabs + osw->active_tab; - if (t->num_windows == 1) { - Window *w = t->windows + t->active_window; - Screen *s = w->render_data.screen; - if (s) { - color = colorprofile_to_color(s->color_profile, s->color_profile->overridden.default_bg, s->color_profile->configured.default_bg).rgb; - } - } - } - blank_canvas(osw->is_semi_transparent ? osw->background_opacity : 1.0f, color); -} - static void window_pos_callback(GLFWwindow* window, int x UNUSED, int y UNUSED) { if (!set_callback_window(window)) return; @@ -1466,7 +1450,7 @@ create_os_window(PyObject UNUSED *self, PyObject *args, PyObject *kw) { bool is_semi_transparent = glfwGetWindowAttrib(glfw_window, GLFW_TRANSPARENT_FRAMEBUFFER); // blank the window once so that there is no initial flash of color // changing, in case the background color is not black - blank_canvas(is_semi_transparent ? OPT(background_opacity) : 1.0f, OPT(background)); + blank_canvas(is_semi_transparent ? OPT(background_opacity) : 1.0f, OPT(background), true); apply_swap_interval(-1); // On Wayland the initial swap is allowed only after the first XDG configure event if (glfwAreSwapsAllowed(glfw_window)) glfwSwapBuffers(glfw_window); diff --git a/kitty/shaders.c b/kitty/shaders.c index 7c16e9d18..cb9b991df 100644 --- a/kitty/shaders.c +++ b/kitty/shaders.c @@ -805,7 +805,7 @@ render_a_bar(const UIRenderData *ui, WindowBarData *bar, PyObject *title, bool a const unsigned sh = ui->full_framebuffer_height; // first blank the area to be drawn to background enable_scissor_using_top_left_origin(border_rect, sh); - blank_canvas(1.f, bg); + blank_canvas(ui->os_window->is_semi_transparent ? ui->os_window->background_opacity : 1.f, bg, false); disable_scissor(); // then draw the rendered text save_viewport_using_top_left_origin( @@ -1000,11 +1000,18 @@ draw_cells_with_layers(const UIRenderData *ui, ssize_t vao_idx) { } void -blank_canvas(float background_opacity, color_type color) { - // See https://github.com/glfw/glfw/issues/1538 for why we use pre-multiplied alpha -#define C(shift) srgb_color((color >> shift) & 0xFF) - glClearColor(C(16), C(8), C(0), background_opacity); +blank_canvas(float background_opacity, color_type color_in_srgb, bool for_final_output) { + if (for_final_output) { + // we need to write pre-multiplied sRGB color to framebuffer +#define C(shift) ((((color_in_srgb >> shift) & 0xFF) / 255.f) * background_opacity) + glClearColor(C(16), C(8), C(0), background_opacity); #undef C + } else { + // we need to write pre-multiplied linear color to framebuffer +#define C(shift) srgb_color((color_in_srgb >> shift) & 0xFF) * background_opacity + glClearColor(C(16), C(8), C(0), background_opacity); +#undef C + } glClear(GL_COLOR_BUFFER_BIT); } @@ -1222,6 +1229,22 @@ draw_resizing_text(OSWindow *w) { } } +void +blank_os_window(OSWindow *osw) { + color_type color = OPT(background); + if (osw->num_tabs > 0) { + Tab *t = osw->tabs + osw->active_tab; + if (t->num_windows == 1) { + Window *w = t->windows + t->active_window; + Screen *s = w->render_data.screen; + if (s) { + color = colorprofile_to_color(s->color_profile, s->color_profile->overridden.default_bg, s->color_profile->configured.default_bg).rgb; + } + } + } + blank_canvas(osw->is_semi_transparent ? osw->background_opacity : 1.0f, color, true); +} + static void start_os_window_rendering(OSWindow *os_window) { if (os_window->live_resize.in_progress) { diff --git a/kitty/state.h b/kitty/state.h index 969aa6451..1e46ac46f 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -407,7 +407,7 @@ void free_texture(uint32_t*); void free_framebuffer(uint32_t*); void send_image_to_gpu(uint32_t*, const void*, int32_t, int32_t, bool, bool, bool, RepeatStrategy); void send_sprite_to_gpu(FONTS_DATA_HANDLE fg, sprite_index, pixel*, sprite_index); -void blank_canvas(float, color_type); +void blank_canvas(float, color_type, bool); void blank_os_window(OSWindow *); void set_os_window_chrome(OSWindow *w); FONTS_DATA_HANDLE load_fonts_data(double, double, double);