emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

feature/pgtk 385e85c 038/100: End Resize flickering by copying surface r


From: Yuuki Harano
Subject: feature/pgtk 385e85c 038/100: End Resize flickering by copying surface rather than just clearing
Date: Tue, 24 Nov 2020 08:02:32 -0500 (EST)

branch: feature/pgtk
commit 385e85c3dde572fd9832670feb871e3b7715b156
Author: Jeff Walsh <jawalsh@localhost.localdomain>
Commit: Jeff Walsh <fejfighter@gmail.com>

    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
---
 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 394d81a..8cdbe3e 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 67ff378..74eb08d 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -22,6 +22,7 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
    interpretation of even the system includes. */
 #include <config.h>
 
+#include <cairo.h>
 #include <fcntl.h>
 #include <math.h>
 #include <pthread.h>
@@ -63,6 +64,11 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 
 #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 694a85b..d441e16 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);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]