From e719499a9c6bc025c454848967477dc2bcdc4502 Mon Sep 17 00:00:00 2001 From: Jeff Walsh Date: Mon, 13 Jan 2020 16:17:50 +1100 Subject: [PATCH] End Resize flickering by copying surface rather than just clearing --- src/gtkutil.c | 6 +++--- src/pgtkterm.c | 42 ++++++++++++++++++++++++++++++++++++++++++ src/pgtkterm.h | 2 ++ 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/gtkutil.c b/src/gtkutil.c index 531b24fddacb..11d8dce8d0a6 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -1061,9 +1061,6 @@ xg_frame_resized (struct frame *f, int pixelwidth, int pixelheight) change_frame_size (f, width, height, 0, 1, 0, 1); SET_FRAME_GARBAGED (f); cancel_mouse_face (f); -#ifdef HAVE_PGTK - pgtk_cr_destroy_surface (f); -#endif } } @@ -1422,7 +1419,10 @@ xg_create_frame_widgets (struct frame *f) FIXME: gtk_widget_set_double_buffered is deprecated and might stop working in the future. We need to migrate away from combining X and GTK+ drawing to a pure GTK+ build. */ + +#ifndef HAVE_PGTK gtk_widget_set_double_buffered (wfixed, FALSE); +#endif #if ! GTK_CHECK_VERSION (3, 22, 0) gtk_window_set_wmclass (GTK_WINDOW (wtop), diff --git a/src/pgtkterm.c b/src/pgtkterm.c index e2207e3e211b..9e352ff750c4 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c @@ -22,6 +22,7 @@ along with GNU Emacs. If not, see . */ interpretation of even the system includes. */ #include +#include #include #include #include @@ -63,6 +64,11 @@ along with GNU Emacs. If not, see . */ #define FRAME_CR_CONTEXT(f) ((f)->output_data.pgtk->cr_context) #define FRAME_CR_SURFACE(f) ((f)->output_data.pgtk->cr_surface) +#define FRAME_CR_SURFACE_DESIRED_WIDTH(f) \ + ((f)->output_data.pgtk->cr_surface_desired_width) +#define FRAME_CR_SURFACE_DESIRED_HEIGHT(f) \ + ((f)->output_data.pgtk->cr_surface_desired_height) + struct pgtk_display_info *x_display_list; /* Chain of existing displays */ extern Lisp_Object tip_frame; @@ -4864,6 +4870,7 @@ static void size_allocate(GtkWidget *widget, GtkAllocation *alloc, gpointer *use if (f) { PGTK_TRACE("%dx%d", alloc->width, alloc->height); xg_frame_resized(f, alloc->width, alloc->height); + pgtk_cr_update_surface_desired_size(f, alloc->width, alloc->height); } } @@ -5287,6 +5294,7 @@ static gboolean configure_event(GtkWidget *widget, GdkEvent *event, gpointer *us if (f && widget == FRAME_GTK_OUTER_WIDGET (f)) { PGTK_TRACE("%dx%d", event->configure.width, event->configure.height); xg_frame_resized(f, event->configure.width, event->configure.height); + pgtk_cr_update_surface_desired_size(f, event->configure.width, event->configure.height); } return TRUE; } @@ -6604,6 +6612,40 @@ If set to a non-float value, there will be no wait at all. */); } + +void +pgtk_cr_update_surface_desired_size (struct frame *f, int width, int height) +{ + PGTK_TRACE("pgtk_cr_update_surface_desired_size"); + + if (FRAME_CR_SURFACE_DESIRED_WIDTH (f) != width + || FRAME_CR_SURFACE_DESIRED_HEIGHT (f) != height) + { + cairo_surface_t *old_surface = FRAME_CR_SURFACE(f); + cairo_t *cr = NULL; + cairo_t *old_cr = FRAME_CR_CONTEXT(f); + FRAME_CR_SURFACE(f) = gdk_window_create_similar_surface(gtk_widget_get_window(FRAME_GTK_WIDGET(f)), + CAIRO_CONTENT_COLOR_ALPHA, + width, + height); + + if (old_surface){ + cr = cairo_create(FRAME_CR_SURFACE(f)); + cairo_set_source_surface (cr, old_surface, 0, 0); + + cairo_paint(cr); + FRAME_CR_CONTEXT (f) = cr; + + cairo_destroy(old_cr); + cairo_surface_destroy (old_surface); + } + gtk_widget_queue_draw(FRAME_GTK_WIDGET(f)); + FRAME_CR_SURFACE_DESIRED_WIDTH (f) = width; + FRAME_CR_SURFACE_DESIRED_HEIGHT (f) = height; + } +} + + cairo_t * pgtk_begin_cr_clip (struct frame *f) { diff --git a/src/pgtkterm.h b/src/pgtkterm.h index 2443b1eaa70f..dd79aa36889a 100644 --- a/src/pgtkterm.h +++ b/src/pgtkterm.h @@ -369,6 +369,7 @@ struct pgtk_output #ifdef USE_CAIRO /* Cairo drawing context. */ cairo_t *cr_context; + int cr_surface_desired_width, cr_surface_desired_height; /* Cairo surface for double buffering */ cairo_surface_t *cr_surface; cairo_surface_t *cr_surface_visible_bell; @@ -571,6 +572,7 @@ extern int pgtk_select (int nfds, fd_set *readfds, fd_set *writefds, sigset_t *sigmask); /* Cairo related functions implemented in pgtkterm.c */ +extern void pgtk_cr_update_surface_desired_size (struct frame *, int, int); extern cairo_t *pgtk_begin_cr_clip (struct frame *f); extern void pgtk_end_cr_clip (struct frame *f); extern void pgtk_set_cr_source_with_gc_foreground (struct frame *f, Emacs_GC *gc);