File vim-8.2.3607-revert-gtk3-code-removal.patch of Package vim.31592
From d3d3309464edf470cece3e4b698e89e62d036274 Mon Sep 17 00:00:00 2001
From: Tamara Schmitz <tschmitz@suse.de>
Date: Wed, 17 May 2023 16:04:11 +0200
Subject: [PATCH] Revert "patch 8.2.3607: GTK3 screen updating is slow"
This reverts commit 9459b8d461d6f8345bfa3fb9b3b4297a7950b0bc.
---
src/gui.h | 1 +
src/gui_gtk_x11.c | 89 ++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 86 insertions(+), 4 deletions(-)
diff --git a/src/gui.h b/src/gui.h
index aecba27d8..b3ce046ac 100644
--- a/src/gui.h
+++ b/src/gui.h
@@ -376,6 +376,7 @@ typedef struct Gui
# endif
# ifdef USE_GTK3
cairo_surface_t *surface; // drawarea surface
+ gboolean by_signal; // cause of draw operation
# else
GdkGC *text_gc; // cached GC for normal text
# endif
diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c
index 7ef63b842..fab74621e 100644
--- a/src/gui_gtk_x11.c
+++ b/src/gui_gtk_x11.c
@@ -755,6 +755,46 @@ visibility_event(GtkWidget *widget UNUSED,
* Redraw the corresponding portions of the screen.
*/
#if GTK_CHECK_VERSION(3,0,0)
+static gboolean is_key_pressed = FALSE;
+static gboolean blink_mode = TRUE;
+
+static gboolean gui_gtk_is_blink_on(void);
+
+ static void
+gui_gtk3_redraw(int x, int y, int width, int height)
+{
+ // Range checks are left to gui_redraw_block()
+ gui_redraw_block(Y_2_ROW(y), X_2_COL(x),
+ Y_2_ROW(y + height - 1), X_2_COL(x + width - 1),
+ GUI_MON_NOCLEAR);
+}
+
+ static void
+gui_gtk3_update_cursor(cairo_t *cr)
+{
+ if (gui.row == gui.cursor_row)
+ {
+ gui.by_signal = TRUE;
+ if (State & MODE_CMDLINE)
+ gui_update_cursor(TRUE, FALSE);
+ else
+ gui_update_cursor(TRUE, TRUE);
+ gui.by_signal = FALSE;
+ cairo_paint(cr);
+ }
+}
+
+ static gboolean
+gui_gtk3_should_draw_cursor(void)
+{
+ unsigned int cond = 0;
+ cond |= gui_gtk_is_blink_on();
+ if (gui.cursor_col >= gui.col)
+ cond |= is_key_pressed;
+ cond |= gui.in_focus == FALSE;
+ return cond;
+}
+
static gboolean
draw_event(GtkWidget *widget UNUSED,
cairo_t *cr,
@@ -769,6 +809,8 @@ draw_event(GtkWidget *widget UNUSED,
cairo_set_source_surface(cr, gui.surface, 0, 0);
+ // Draw the window without the cursor.
+ gui.by_signal = TRUE;
{
cairo_rectangle_list_t *list = NULL;
@@ -777,16 +819,47 @@ draw_event(GtkWidget *widget UNUSED,
{
int i;
+ // First clear all the blocks and then redraw them. Just in case
+ // some blocks overlap.
+ for (i = 0; i < list->num_rectangles; i++)
+ {
+ const cairo_rectangle_t rect = list->rectangles[i];
+
+ gui_mch_clear_block(Y_2_ROW((int)rect.y), 0,
+ Y_2_ROW((int)(rect.y + rect.height)) - 1, Columns - 1);
+ }
+
for (i = 0; i < list->num_rectangles; i++)
{
- const cairo_rectangle_t *rect = &list->rectangles[i];
- cairo_rectangle(cr, rect->x, rect->y,
- rect->width, rect->height);
- cairo_fill(cr);
+ const cairo_rectangle_t rect = list->rectangles[i];
+
+ if (blink_mode)
+ gui_gtk3_redraw(rect.x, rect.y, rect.width, rect.height);
+ else
+ {
+ if (get_real_state() & MODE_VISUAL)
+ gui_gtk3_redraw(rect.x, rect.y,
+ rect.width, rect.height);
+ else
+ gui_redraw(rect.x, rect.y, rect.width, rect.height);
+ }
}
}
cairo_rectangle_list_destroy(list);
+
+ if (get_real_state() & MODE_VISUAL)
+ {
+ if (gui.cursor_row == gui.row && gui.cursor_col >= gui.col)
+ gui_update_cursor(TRUE, TRUE);
+ }
+
+ cairo_paint(cr);
}
+ gui.by_signal = FALSE;
+
+ // Add the cursor to the window if necessary.
+ if (gui_gtk3_should_draw_cursor() && blink_mode)
+ gui_gtk3_update_cursor(cr);
return FALSE;
}
@@ -911,6 +984,14 @@ static long_u blink_ontime = 400;
static long_u blink_offtime = 250;
static guint blink_timer = 0;
+#if GTK_CHECK_VERSION(3,0,0)
+ static gboolean
+gui_gtk_is_blink_on(void)
+{
+ return blink_state == BLINK_ON;
+}
+#endif
+
int
gui_mch_is_blinking(void)
{
--
2.26.2