From: Jeff Walsh Date: Mon, 13 Jan 2020 05:17:50 +0000 (+1100) Subject: End Resize flickering by copying surface rather than just clearing X-Git-Tag: emacs-29.0.90~3822 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=385e85c3dde572fd9832670feb871e3b7715b156;p=emacs.git End Resize flickering by copying surface rather than just clearing * src/pgtkterm.h (struct pgtk_output): store desired sizes * src/pgtkterm.c (FRAME_CR_SURFACE_DESIRED_HEIGHT) (FRAME_CR_SURFACE_DESIRED_WIDTH, size_allocate, configure_event) (pgtk_cr_update_surface_desired_size): add "desired" size for handling surface change * src/gtkutil.c (xg_frame_resized, xg_create_frame_widgets): remove surface destroy, turn off double buffer call --- diff --git a/src/gtkutil.c b/src/gtkutil.c index 394d81ace60..8cdbe3e4ad5 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -1053,9 +1053,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 } } @@ -1449,7 +1446,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 67ff3786332..74eb08d3301 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; @@ -4851,6 +4857,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); } } @@ -5274,6 +5281,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; } @@ -6574,6 +6582,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 694a85bac2e..d441e16106e 100644 --- a/src/pgtkterm.h +++ b/src/pgtkterm.h @@ -366,6 +366,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; @@ -568,6 +569,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);