// for GTK+ 3, may induce other draw events.
cairo_set_source_surface(cr, gui.surface, 0, 0);
-
- {
- cairo_rectangle_list_t *list = NULL;
-
- list = cairo_copy_clip_rectangle_list(cr);
- if (list->status != CAIRO_STATUS_CLIP_NOT_REPRESENTABLE)
- {
- int i;
-
- 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);
- }
- }
- cairo_rectangle_list_destroy(list);
- }
+ cairo_paint(cr);
return FALSE;
}
GDK_ACTION_COPY | GDK_ACTION_MOVE);
}
-#ifdef GDK_WINDOWING_WAYLAND
-static struct {
- int left;
- int top;
- int right;
- int bottom;
- bool active;
-} wl_dirty_rect = {0, 0, 0, 0, false};
-
- static void
-wl_queue_dirty_area(int x, int y, int width, int height)
-{
- if (!wl_dirty_rect.active)
- {
- wl_dirty_rect.left = x;
- wl_dirty_rect.top = y;
- wl_dirty_rect.right = x + width;
- wl_dirty_rect.bottom = y + height;
- wl_dirty_rect.active = true;
- }
- else
- {
- // Expand to append further changes
- if (x < wl_dirty_rect.left) wl_dirty_rect.left = x;
- if (y < wl_dirty_rect.top) wl_dirty_rect.top = y;
- if (x + width > wl_dirty_rect.right) wl_dirty_rect.right = x + width;
- if (y + height > wl_dirty_rect.bottom) wl_dirty_rect.bottom = y + height;
- }
-}
-
- static void
-wl_flush(void)
-{
- if (!wl_dirty_rect.active)
- return;
- int draw_x = wl_dirty_rect.left;
- int draw_y = wl_dirty_rect.top;
- int draw_w = wl_dirty_rect.right - wl_dirty_rect.left;
- int draw_h = wl_dirty_rect.bottom - wl_dirty_rect.top;
-
- if (draw_w > 0 && draw_h > 0)
- {
- gtk_widget_queue_draw_area(gui.drawarea, draw_x, draw_y, draw_w, draw_h);
- }
- wl_dirty_rect.active = false;
-}
-#endif
-
/*
* Initialize the GUI. Create all the windows, set up all the callbacks etc.
* Returns OK for success, FAIL when the GUI can't be started.
return len_sum;
}
+#if GTK_CHECK_VERSION(3,0,0)
+static cairo_region_t *dirty_region = NULL;
+
static void
-queue_draw_area(
- int x,
- int y,
- int width,
- int height)
+queue_draw_area(int x, int y, int width, int height)
{
-#ifdef GDK_WINDOWING_WAYLAND
- if (gui.is_wayland)
- wl_queue_dirty_area(x, y, width, height);
+ cairo_rectangle_int_t rect;
+
+ if (width <= 0 || height <= 0 || gui.drawarea == NULL)
+ return;
+
+ rect.x = x;
+ rect.y = y;
+ rect.width = width;
+ rect.height = height;
+
+ if (dirty_region == NULL)
+ dirty_region = cairo_region_create_rectangle(&rect);
else
-#endif
- gtk_widget_queue_draw_area(gui.drawarea, x, y, width, height);
+ cairo_region_union_rectangle(dirty_region, &rect);
}
+#endif
int
gui_gtk_draw_string_ext(
#if GTK_CHECK_VERSION(3,0,0)
cairo_destroy(cr);
- queue_draw_area(area.x, area.y,
- area.width, area.height);
+ queue_draw_area(FILL_X(col), FILL_Y(row),
+ column_offset * gui.char_width + 1, gui.char_height);
#else
gdk_gc_set_clip_rectangle(gui.text_gc, NULL);
#endif
cairo_destroy(cr);
- queue_draw_area(rect.x, rect.y,
- rect.width, rect.height);
+ queue_draw_area(rect.x, rect.y, rect.width, rect.height);
#else
GdkGCValues values;
GdkGC *invert_gc;
{
int cnt = 0; // prevent endless loop
while (g_main_context_pending(NULL) && !vim_is_input_buf_full()
- && ++cnt < 100)
+ && ++cnt < 100)
{
-#ifdef GDK_WINDOWING_WAYLAND
- if (gui.is_wayland)
- {
- int prio = 0;
- g_main_context_prepare(NULL, &prio);
- // peek internal scheduling of redraw
- if (prio == GDK_PRIORITY_REDRAW)
- gui_may_flush(); // prepares redraw: g_main_context_iteration
- }
+#if GTK_CHECK_VERSION(3,0,0)
+ int prio = 0;
+ g_main_context_prepare(NULL, &prio);
+ // peek internal scheduling of redraw
+ if (prio == GDK_PRIORITY_REDRAW)
+ gui_may_flush(); // prepares redraw: g_main_context_iteration
#endif
g_main_context_iteration(NULL, TRUE);
}
void
gui_mch_flush(void)
{
- if (gui.mainwin != NULL && gtk_widget_get_realized(gui.mainwin))
+ if (gui.mainwin == NULL || !gtk_widget_get_realized(gui.mainwin))
+ return;
+#if GTK_CHECK_VERSION(3,0,0)
+ if (dirty_region != NULL && gui.drawarea != NULL)
{
-#ifdef GDK_WINDOWING_WAYLAND
- if (gui.is_wayland)
- return wl_flush();
-#endif
-#if GTK_CHECK_VERSION(2,4,0)
- gdk_display_flush(gtk_widget_get_display(gui.mainwin));
+ gtk_widget_queue_draw_region(gui.drawarea, dirty_region);
+ cairo_region_destroy(dirty_region);
+ dirty_region = NULL;
+ }
#else
- gdk_display_sync(gtk_widget_get_display(gui.mainwin));
+ gdk_display_flush(gtk_widget_get_display(gui.mainwin));
+ return;
#endif
- }
}
/*
cairo_fill(cr);
cairo_destroy(cr);
- queue_draw_area(
- rect.x, rect.y, rect.width, rect.height);
+ queue_draw_area(rect.x, rect.y, rect.width, rect.height);
}
#else // !GTK_CHECK_VERSION(3,0,0)
gdk_gc_set_foreground(gui.text_gc, &color);
cairo_fill(cr);
cairo_destroy(cr);
- queue_draw_area(
- rect.x, rect.y, rect.width, rect.height);
+ queue_draw_area(rect.x, rect.y, rect.width, rect.height);
}
#else
# define gui_gtk_window_clear(win) gdk_window_clear(win)
# if GTK_CHECK_VERSION(3,0,0)
cairo_popup_image_paint(wp, gui.surface, x, y,
src_x, src_y, draw_w, draw_h);
- if (gui.drawarea != NULL)
- queue_draw_area(x, y, draw_w, draw_h);
+ queue_draw_area(x, y, draw_w, draw_h);
# else
cairo_popup_image_paint(wp, gui.drawarea->window, x, y,
src_x, src_y, draw_w, draw_h);