[Libreoffice-commits] core.git: 6 commits - vcl/inc vcl/unx

Caolán McNamara caolanm at redhat.com
Wed Mar 11 09:43:20 PDT 2015


 vcl/inc/unx/gtk/gtkframe.hxx                  |   12 -
 vcl/inc/unx/gtk/gtkgdi.hxx                    |    4 
 vcl/unx/gtk/window/gtksalframe.cxx            |  173 ++++++++++----------------
 vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx |   40 ------
 4 files changed, 78 insertions(+), 151 deletions(-)

New commits:
commit eeef59d94cd358916d1defdb7925e25c740ac8d0
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Mar 11 16:36:43 2015 +0000

    AllocateFrame only needed for gtk3 path
    
    Change-Id: I118f640e770491448b16f1a9387ffe6df5063cd9

diff --git a/vcl/unx/gtk/window/gtksalframe.cxx b/vcl/unx/gtk/window/gtksalframe.cxx
index f3a4353..afcdbe5 100644
--- a/vcl/unx/gtk/window/gtksalframe.cxx
+++ b/vcl/unx/gtk/window/gtksalframe.cxx
@@ -405,6 +405,7 @@ void GtkSalFrame::doKeyCallback( guint state,
     vcl::DeletionListener aDel( this );
 
 #if GTK_CHECK_VERSION(3,0,0)
+#if 0
     // shift-zero forces a re-draw and event is swallowed
     if (keyval == GDK_0)
     {
@@ -424,7 +425,7 @@ void GtkSalFrame::doKeyCallback( guint state,
         fprintf(stderr, "toggle dump frames to %d\n", dumpframes);
         return;
     }
-
+#endif
 #endif
 
     /*
@@ -3115,7 +3116,6 @@ bool GtkSalFrame::Dispatch( const XEvent* pEvent )
                 maGeometry.nWidth  = pEvent->xconfigure.width;
                 maGeometry.nHeight = pEvent->xconfigure.height;
                 setMinMaxSize();
-                AllocateFrame();
                 getDisplay()->SendInternalEvent( this, NULL, SALEVENT_RESIZE );
             }
         }
commit e786d60ceee3e32eff8bd77b13a9d1b3d00e78b9
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Mar 11 16:30:36 2015 +0000

    drop -1 +2 hack unless someone can show a need for it again
    
    Change-Id: Ib6ac83dfe9e187cdbb40ebb539552b4cef824e48

diff --git a/vcl/unx/gtk/window/gtksalframe.cxx b/vcl/unx/gtk/window/gtksalframe.cxx
index 3a84f98..f3a4353 100644
--- a/vcl/unx/gtk/window/gtksalframe.cxx
+++ b/vcl/unx/gtk/window/gtksalframe.cxx
@@ -3391,15 +3391,11 @@ void GtkSalFrame::damaged (const basegfx::B2IBox& rDamageRect)
         cairo_surface_write_to_png(cairo_get_target(getCairoContext()), tmp.getStr());
     }
 
-    /* FIXME: this is a dirty hack, to render buttons correctly, we
-     * should of course remove the -1 and +2, but the whole area
-     * won't be rendered then.
-     */
-    gtk_widget_queue_draw_area( m_pWindow,
-                                rDamageRect.getMinX() - 1,
-                                rDamageRect.getMinY() - 1,
-                                rDamageRect.getWidth() + 2,
-                                rDamageRect.getHeight() + 2 );
+    gtk_widget_queue_draw_area(m_pWindow,
+                               rDamageRect.getMinX(),
+                               rDamageRect.getMinY(),
+                               rDamageRect.getWidth(),
+                               rDamageRect.getHeight());
 }
 
 // blit our backing basebmp buffer to the target cairo context cr
commit 082f7a97f40f1ebacf64b7a1b9fdee2bbde60a07
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Mon Mar 9 10:40:14 2015 +0000

    debug helpers
    
    Change-Id: I75e697a1500cd51ba714d16e3a5f131d922e2906

diff --git a/vcl/unx/gtk/window/gtksalframe.cxx b/vcl/unx/gtk/window/gtksalframe.cxx
index 8e32df6..3a84f98 100644
--- a/vcl/unx/gtk/window/gtksalframe.cxx
+++ b/vcl/unx/gtk/window/gtksalframe.cxx
@@ -382,6 +382,8 @@ struct DamageTracker : public basebmp::IBitmapDeviceDamageTracker
     GtkSalFrame& m_rFrame;
 };
 }
+
+static bool dumpframes = false;
 #endif
 
 void GtkSalFrame::doKeyCallback( guint state,
@@ -406,10 +408,23 @@ void GtkSalFrame::doKeyCallback( guint state,
     // shift-zero forces a re-draw and event is swallowed
     if (keyval == GDK_0)
     {
-        fprintf( stderr, "force re-draw\n");
+        fprintf( stderr, "force widget_queue_draw\n");
         gtk_widget_queue_draw (m_pWindow);
         return;
     }
+    else if (keyval == GDK_1)
+    {
+        fprintf( stderr, "force repaint all\n");
+        TriggerPaintEvent();
+        return;
+    }
+    else if (keyval == GDK_2)
+    {
+        dumpframes = !dumpframes;
+        fprintf(stderr, "toggle dump frames to %d\n", dumpframes);
+        return;
+    }
+
 #endif
 
     /*
@@ -3367,14 +3382,14 @@ void GtkSalFrame::damaged (const basegfx::B2IBox& rDamageRect)
                  (int) rDamageRect.getHeight(),
                  area );
     }
-
-#if FRAME_BY_FRAME_DEBUG
-    static int frame;
-    OString tmp("/tmp/frame" + OString::number(frame++) + ".png");
-    cairo_surface_write_to_png(cairo_get_target(getCairoContext()), tmp.getStr());
 #endif
 
-#endif
+    if (dumpframes)
+    {
+        static int frame;
+        OString tmp("/tmp/frame" + OString::number(frame++) + ".png");
+        cairo_surface_write_to_png(cairo_get_target(getCairoContext()), tmp.getStr());
+    }
 
     /* FIXME: this is a dirty hack, to render buttons correctly, we
      * should of course remove the -1 and +2, but the whole area
commit 21e2dee9029c2a6cb240991ecf07de4ef87653f9
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Fri Mar 6 20:46:19 2015 +0000

    just trust cairo's clipping instead, simples
    
    Change-Id: I44f574b80cee006f7463b5488c5ddb9210f67db5

diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx
index 66a7aa0..b712719 100644
--- a/vcl/inc/unx/gtk/gtkframe.hxx
+++ b/vcl/inc/unx/gtk/gtkframe.hxx
@@ -345,7 +345,6 @@ public:
 #if GTK_CHECK_VERSION(3,0,0)
     // only for gtk3 ...
     cairo_t* getCairoContext();
-    void renderArea( cairo_t *cr, cairo_rectangle_t *src );
     void damaged (const basegfx::B2IBox& rDamageRect);
 #endif
     virtual ~GtkSalFrame();
diff --git a/vcl/unx/gtk/window/gtksalframe.cxx b/vcl/unx/gtk/window/gtksalframe.cxx
index 5b10813..8e32df6 100644
--- a/vcl/unx/gtk/window/gtksalframe.cxx
+++ b/vcl/unx/gtk/window/gtksalframe.cxx
@@ -364,8 +364,6 @@ GetAlternateKeyCode( const sal_uInt16 nKeyCode )
 }
 
 #if GTK_CHECK_VERSION(3,0,0)
-static int debugQueuePureRedraw = 0;
-static bool debugRedboxRedraws = false;
 
 namespace {
 /// Decouple SalFrame lifetime from damagetracker lifetime
@@ -408,17 +406,10 @@ void GtkSalFrame::doKeyCallback( guint state,
     // shift-zero forces a re-draw and event is swallowed
     if (keyval == GDK_0)
     {
-        debugQueuePureRedraw += 2;
-        fprintf( stderr, "force re-draw %d\n", debugQueuePureRedraw );
+        fprintf( stderr, "force re-draw\n");
         gtk_widget_queue_draw (m_pWindow);
         return;
     }
-    if (keyval == GDK_9)
-    {
-        debugRedboxRedraws = !debugRedboxRedraws;
-        fprintf( stderr, "set redboxing to %d\n", debugRedboxRedraws );
-        return;
-    }
 #endif
 
     /*
@@ -3397,58 +3388,18 @@ void GtkSalFrame::damaged (const basegfx::B2IBox& rDamageRect)
 }
 
 // blit our backing basebmp buffer to the target cairo context cr
-void GtkSalFrame::renderArea( cairo_t *cr, cairo_rectangle_t *area )
-{
-    cairo_save( cr );
-
-    cairo_surface_t *pSurface = cairo_get_target(getCairoContext());
-    cairo_set_operator( cr, CAIRO_OPERATOR_OVER );
-    cairo_set_source_surface( cr, pSurface, 0, 0 );
-    SAL_INFO("vcl.gtk3", "rendering" << area->x << "," << area->y << " " << area->width << "x" << area->height);
-    cairo_rectangle( cr, area->x, area->y, area->width, area->height );
-    cairo_fill( cr );
-
-    cairo_restore( cr );
-
-    // Render red rectangles to show what was re-rendered ...
-    if (debugRedboxRedraws)
-    {
-        cairo_save( cr );
-        cairo_set_line_width( cr, 1.0 );
-        cairo_set_source_rgb( cr, 1.0, 0, 0 );
-        cairo_rectangle( cr, area->x + 1.0, area->y + 1.0, area->width - 2.0, area->height - 2.0 );
-        cairo_stroke( cr );
-        cairo_restore( cr );
-    }
-}
-
 gboolean GtkSalFrame::signalDraw( GtkWidget*, cairo_t *cr, gpointer frame )
 {
     GtkSalFrame* pThis = (GtkSalFrame*)frame;
 
-    double x1 = 0.0, y1 = 0.0, x2 = 0.0, y2 = 0.0;
-    cairo_clip_extents (cr, &x1, &y1, &x2, &y2);
+    cairo_save(cr);
 
-    if (debugQueuePureRedraw > 0)
-    {
-        debugQueuePureRedraw--;
-        fprintf (stderr, "skip signalDraw for debug %d\n", debugQueuePureRedraw);
-        cairo_rectangle_t rect = { x1, y1, x2 - x1, y2 - y1 };
-        pThis->renderArea( cr, &rect );
-        return FALSE;
-    }
-
-    // FIXME: we need to profile whether re-rendering the entire
-    // clip region, and just pushing (with renderArea) smaller pieces
-    // is faster ...
-    cairo_rectangle_list_t *rects = cairo_copy_clip_rectangle_list (cr);
-    SAL_INFO("vcl.gtk3", "paint " << rects->num_rectangles << " regions");
-    for (int i = 0; i < rects->num_rectangles; i++) {
-        cairo_rectangle_t rect = rects->rectangles[i];
-        SAL_INFO("vcl.gtk3", "\t" << i << " -> " << rect.x << "," << rect.y << " " << rect.width << "x" << rect.height);
-        pThis->renderArea( cr, &rect );
-    }
-    cairo_rectangle_list_destroy(rects);
+    cairo_surface_t *pSurface = cairo_get_target(pThis->getCairoContext());
+    cairo_set_operator( cr, CAIRO_OPERATOR_OVER );
+    cairo_set_source_surface(cr, pSurface, 0, 0);
+    cairo_paint(cr);
+
+    cairo_restore(cr);
 
     cairo_surface_flush(cairo_get_target(cr));
 
commit f8943281d0961fc3b5c2d84b666a2cd68db962e5
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Fri Mar 6 20:33:13 2015 +0000

    gtk3 fix mem leak
    
    Change-Id: I2f751dbbe088531c6b560be57668d5b929ac20df

diff --git a/vcl/unx/gtk/window/gtksalframe.cxx b/vcl/unx/gtk/window/gtksalframe.cxx
index 8eddea2..5b10813 100644
--- a/vcl/unx/gtk/window/gtksalframe.cxx
+++ b/vcl/unx/gtk/window/gtksalframe.cxx
@@ -3448,6 +3448,7 @@ gboolean GtkSalFrame::signalDraw( GtkWidget*, cairo_t *cr, gpointer frame )
         SAL_INFO("vcl.gtk3", "\t" << i << " -> " << rect.x << "," << rect.y << " " << rect.width << "x" << rect.height);
         pThis->renderArea( cr, &rect );
     }
+    cairo_rectangle_list_destroy(rects);
 
     cairo_surface_flush(cairo_get_target(cr));
 
commit d335ab62114808fcb60c91fd5346bf504edf0a63
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Fri Mar 6 16:27:47 2015 +0000

    make gtk3 performance usable
    
    only render into the backbuffer once, don't re-render on "draw".
    
    In order that make that possible the back-buffer has to be refilled
    on resize events and a whole pile of things had to be fixed in the
    underlying svp backend.
    
    now it scrolls like the wind, well comparitively anyway, and while
    you probably wouldn't want to use it yet, you could in a pinch
    
    Change-Id: I8938fa099e5594fd44c32baaad9043946280212c

diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx
index 5cb0d9c..66a7aa0 100644
--- a/vcl/inc/unx/gtk/gtkframe.hxx
+++ b/vcl/inc/unx/gtk/gtkframe.hxx
@@ -174,7 +174,6 @@ class GtkSalFrame : public SalFrame, public X11WindowProvider
 
     SalX11Screen                    m_nXScreen;
     GtkWidget*                      m_pWindow;
-    int                             m_nDuringRender;
     GdkWindow*                      m_pForeignParent;
     GdkNativeWindow                 m_aForeignParentWindow;
     GdkWindow*                      m_pForeignTopLevel;
@@ -237,8 +236,11 @@ class GtkSalFrame : public SalFrame, public X11WindowProvider
     // signals
     static gboolean     signalButton( GtkWidget*, GdkEventButton*, gpointer );
     static void         signalStyleSet( GtkWidget*, GtkStyle* pPrevious, gpointer );
+#if GTK_CHECK_VERSION(3,0,0)
     static gboolean     signalDraw( GtkWidget*, cairo_t *cr, gpointer );
+#else
     static gboolean     signalExpose( GtkWidget*, GdkEventExpose*, gpointer );
+#endif
     static gboolean     signalFocus( GtkWidget*, GdkEventFocus*, gpointer );
     static gboolean     signalMap( GtkWidget*, GdkEvent*, gpointer );
     static gboolean     signalUnmap( GtkWidget*, GdkEvent*, gpointer );
@@ -300,6 +302,7 @@ class GtkSalFrame : public SalFrame, public X11WindowProvider
     void askForXEmbedFocus( sal_Int32 nTimecode );
 
     void AllocateFrame();
+    void TriggerPaintEvent();
 
     void updateWMClass();
     void SetScreen( unsigned int nNewScreen, int eType, Rectangle *pSize = NULL );
@@ -342,10 +345,8 @@ public:
 #if GTK_CHECK_VERSION(3,0,0)
     // only for gtk3 ...
     cairo_t* getCairoContext();
-    void pushIgnoreDamage();
-    void popIgnoreDamage();
-    bool isDuringRender();
     void renderArea( cairo_t *cr, cairo_rectangle_t *src );
+    void damaged (const basegfx::B2IBox& rDamageRect);
 #endif
     virtual ~GtkSalFrame();
 
@@ -446,8 +447,6 @@ public:
 
     static GtkSalFrame         *getFromWindow( GtkWindow *pWindow );
 
-    void                        damaged (const basegfx::B2IBox& rDamageRect);
-
     virtual Window              GetX11Window() SAL_OVERRIDE;
 };
 
diff --git a/vcl/inc/unx/gtk/gtkgdi.hxx b/vcl/inc/unx/gtk/gtkgdi.hxx
index b88220c..26f2efb 100644
--- a/vcl/inc/unx/gtk/gtkgdi.hxx
+++ b/vcl/inc/unx/gtk/gtkgdi.hxx
@@ -37,10 +37,6 @@ class GtkSalGraphics : public SvpSalGraphics
     GtkSalFrame *mpFrame;
 public:
     GtkSalGraphics( GtkSalFrame *pFrame, GtkWidget *pWindow );
-    virtual void        copyArea( long nDestX, long nDestY,
-                                  long nSrcX, long nSrcY,
-                                  long nSrcWidth, long nSrcHeight,
-                                  sal_uInt16 /*nFlags*/ ) SAL_OVERRIDE;
     virtual bool        drawNativeControl( ControlType nType, ControlPart nPart,
                                                const Rectangle& rControlRegion,
                                                ControlState nState, const ImplControlValue& aValue,
diff --git a/vcl/unx/gtk/window/gtksalframe.cxx b/vcl/unx/gtk/window/gtksalframe.cxx
index 71bddc2..8eddea2 100644
--- a/vcl/unx/gtk/window/gtksalframe.cxx
+++ b/vcl/unx/gtk/window/gtksalframe.cxx
@@ -498,7 +498,6 @@ GtkSalFrame::GtkSalFrame( SalFrame* pParent, sal_uLong nStyle )
     : m_nXScreen( getDisplay()->GetDefaultXScreen() )
 {
     getDisplay()->registerFrame( this );
-    m_nDuringRender     = 0;
     m_bDefaultPos       = true;
     m_bDefaultSize      = ( (nStyle & SAL_FRAME_STYLE_SIZEABLE) && ! pParent );
     m_bWindowIsGtkPlug  = false;
@@ -1500,7 +1499,10 @@ SalGraphics* GtkSalFrame::AcquireGraphics()
 #if GTK_CHECK_VERSION(3,0,0)
                     m_aGraphics[i].pGraphics = new GtkSalGraphics( this, m_pWindow );
                     if( !m_aFrame.get() )
+                    {
                         AllocateFrame();
+                        TriggerPaintEvent();
+                    }
                     m_aGraphics[i].pGraphics->setDevice( m_aFrame );
 #else // common case:
                     m_aGraphics[i].pGraphics = new GtkSalGraphics( this, m_pWindow, m_nXScreen );
@@ -1866,6 +1868,7 @@ void GtkSalFrame::Show( bool bVisible, bool bNoActivate )
             Flush();
         }
         CallCallback( SALEVENT_RESIZE, NULL );
+        TriggerPaintEvent();
     }
 }
 
@@ -2073,6 +2076,9 @@ void GtkSalFrame::SetPosSize( long nX, long nY, long nWidth, long nHeight, sal_u
         CallCallback( SALEVENT_MOVE, NULL );
     else if( bMoved && bSized )
         CallCallback( SALEVENT_MOVERESIZE, NULL );
+
+    if (bSized)
+        TriggerPaintEvent();
 }
 
 void GtkSalFrame::GetClientSize( long& rWidth, long& rHeight )
@@ -2129,7 +2135,6 @@ void GtkSalFrame::SetWindowState( const SalFrameState* pState )
         maGeometry.nWidth   = pState->mnMaximizedWidth;
         maGeometry.nHeight  = pState->mnMaximizedHeight;
         updateScreenNumber();
-        AllocateFrame();
 
         m_nState = GdkWindowState( m_nState | GDK_WINDOW_STATE_MAXIMIZED );
         m_aRestorePosSize = Rectangle( Point( pState->mnX, pState->mnY ),
@@ -2176,6 +2181,7 @@ void GtkSalFrame::SetWindowState( const SalFrameState* pState )
         else
             gtk_window_deiconify( GTK_WINDOW(m_pWindow) );
     }
+    TriggerPaintEvent();
 }
 
 bool GtkSalFrame::GetWindowState( SalFrameState* pState )
@@ -3355,47 +3361,32 @@ cairo_t* GtkSalFrame::getCairoContext()
     cairo_t* cr = cairo_create(target);
     cairo_surface_destroy(target);
     return cr;
-//    return gdk_cairo_create(gtk_widget_get_window(mpFrame->getWindow()));
-}
-
-void GtkSalFrame::pushIgnoreDamage()
-{
-    m_nDuringRender++;
-}
-
-void GtkSalFrame::popIgnoreDamage()
-{
-    m_nDuringRender--;
 }
 
-bool GtkSalFrame::isDuringRender()
-{
-    return m_nDuringRender;
-}
-
-#endif
-
 void GtkSalFrame::damaged (const basegfx::B2IBox& rDamageRect)
 {
-#if !GTK_CHECK_VERSION(3,0,0)
-    (void)rDamageRect;
-#else
-    if ( isDuringRender() )
-        return;
 #if OSL_DEBUG_LEVEL > 1
     long long area = rDamageRect.getWidth() * rDamageRect.getHeight();
     if( area > 32 * 1024 )
     {
         fprintf( stderr, "bitmap damaged  %d %d (%dx%d) area %lld widget\n",
-                 (int) rDamageRect.getMinX(),
-                 (int) rDamageRect.getMinY(),
-                 (int) rDamageRect.getWidth(),
+                  (int) rDamageRect.getMinX(),
+                  (int) rDamageRect.getMinY(),
+                  (int) rDamageRect.getWidth(),
                  (int) rDamageRect.getHeight(),
                  area );
     }
+
+#if FRAME_BY_FRAME_DEBUG
+    static int frame;
+    OString tmp("/tmp/frame" + OString::number(frame++) + ".png");
+    cairo_surface_write_to_png(cairo_get_target(getCairoContext()), tmp.getStr());
 #endif
+
+#endif
+
     /* FIXME: this is a dirty hack, to render buttons correctly, we
-     * should of course remove the -100 and + 200, but the whole area
+     * should of course remove the -1 and +2, but the whole area
      * won't be rendered then.
      */
     gtk_widget_queue_draw_area( m_pWindow,
@@ -3403,10 +3394,8 @@ void GtkSalFrame::damaged (const basegfx::B2IBox& rDamageRect)
                                 rDamageRect.getMinY() - 1,
                                 rDamageRect.getWidth() + 2,
                                 rDamageRect.getHeight() + 2 );
-#endif
 }
 
-#if GTK_CHECK_VERSION(3,0,0)
 // blit our backing basebmp buffer to the target cairo context cr
 void GtkSalFrame::renderArea( cairo_t *cr, cairo_rectangle_t *area )
 {
@@ -3415,6 +3404,7 @@ void GtkSalFrame::renderArea( cairo_t *cr, cairo_rectangle_t *area )
     cairo_surface_t *pSurface = cairo_get_target(getCairoContext());
     cairo_set_operator( cr, CAIRO_OPERATOR_OVER );
     cairo_set_source_surface( cr, pSurface, 0, 0 );
+    SAL_INFO("vcl.gtk3", "rendering" << area->x << "," << area->y << " " << area->width << "x" << area->height);
     cairo_rectangle( cr, area->x, area->y, area->width, area->height );
     cairo_fill( cr );
 
@@ -3448,10 +3438,6 @@ gboolean GtkSalFrame::signalDraw( GtkWidget*, cairo_t *cr, gpointer frame )
         return FALSE;
     }
 
-    // FIXME: we quite probably want to stop re-rendering of pieces
-    // that we know are just damaged by us and hence already re-rendered
-    pThis->pushIgnoreDamage();
-
     // FIXME: we need to profile whether re-rendering the entire
     // clip region, and just pushing (with renderArea) smaller pieces
     // is faster ...
@@ -3460,20 +3446,14 @@ gboolean GtkSalFrame::signalDraw( GtkWidget*, cairo_t *cr, gpointer frame )
     for (int i = 0; i < rects->num_rectangles; i++) {
         cairo_rectangle_t rect = rects->rectangles[i];
         SAL_INFO("vcl.gtk3", "\t" << i << " -> " << rect.x << "," << rect.y << " " << rect.width << "x" << rect.height);
-        struct SalPaintEvent aEvent( rect.x, rect.y, rect.width, rect.height );
-        aEvent.mbImmediateUpdate = true;
-        pThis->CallCallback( SALEVENT_PAINT, &aEvent );
         pThis->renderArea( cr, &rect );
     }
 
-    pThis->popIgnoreDamage();
-
     cairo_surface_flush(cairo_get_target(cr));
 
     return FALSE;
 }
-#endif // GTK_CHECK_VERSION(3,0,0)
-
+#else
 gboolean GtkSalFrame::signalExpose( GtkWidget*, GdkEventExpose* pEvent, gpointer frame )
 {
     GtkSalFrame* pThis = (GtkSalFrame*)frame;
@@ -3485,6 +3465,30 @@ gboolean GtkSalFrame::signalExpose( GtkWidget*, GdkEventExpose* pEvent, gpointer
     return false;
 }
 
+#endif // GTK_CHECK_VERSION(3,0,0)
+
+void GtkSalFrame::TriggerPaintEvent()
+{
+    //Under gtk2 we can basically paint directly into the XWindow and on
+    //additional "expose-event" events we can re-render the missing pieces
+    //
+    //Under gtk3 we have to keep our own buffer up to date and flush it into
+    //the given cairo context on "draw". So we emit a paint event on
+    //opportune resize trigger events to initially fill our backbuffer and then
+    //keep it up to date with our direct paints and tell gtk those regions
+    //have changed and then blit them into the provided cairo context when
+    //we get the "draw"
+    //
+    //The other alternative was to always paint everything on "draw", but
+    //that duplicates the amount of drawing and is hideously slow
+#if GTK_CHECK_VERSION(3,0,0)
+    SAL_INFO("vcl.gtk3", "force painting" << 0 << "," << 0 << " " << maGeometry.nWidth << "x" << maGeometry.nHeight);
+    SalPaintEvent aPaintEvt(0, 0, maGeometry.nWidth, maGeometry.nHeight, true);
+    CallCallback(SALEVENT_PAINT, &aPaintEvt);
+    gtk_widget_queue_draw(m_pWindow);
+#endif
+}
+
 gboolean GtkSalFrame::signalFocus( GtkWidget*, GdkEventFocus* pEvent, gpointer frame )
 {
     GtkSalFrame* pThis = (GtkSalFrame*)frame;
@@ -3588,6 +3592,7 @@ gboolean GtkSalFrame::signalMap( GtkWidget *pWidget, GdkEvent*, gpointer frame )
 #endif
 
     pThis->CallCallback( SALEVENT_RESIZE, NULL );
+    pThis->TriggerPaintEvent();
 
     return false;
 }
@@ -3682,6 +3687,8 @@ gboolean GtkSalFrame::signalConfigure( GtkWidget*, GdkEventConfigure* pEvent, gp
     else if( bSized )
         pThis->CallCallback( SALEVENT_RESIZE, NULL );
 
+    if (bSized)
+        pThis->TriggerPaintEvent();
     return false;
 }
 
@@ -3855,7 +3862,10 @@ gboolean GtkSalFrame::signalState( GtkWidget*, GdkEvent* pEvent, gpointer frame
 {
     GtkSalFrame* pThis = (GtkSalFrame*)frame;
     if( (pThis->m_nState & GDK_WINDOW_STATE_ICONIFIED) != (pEvent->window_state.new_window_state & GDK_WINDOW_STATE_ICONIFIED ) )
+    {
         pThis->getDisplay()->SendInternalEvent( pThis, NULL, SALEVENT_RESIZE );
+        pThis->TriggerPaintEvent();
+    }
 
     if(   (pEvent->window_state.new_window_state & GDK_WINDOW_STATE_MAXIMIZED) &&
         ! (pThis->m_nState & GDK_WINDOW_STATE_MAXIMIZED) )
diff --git a/vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx b/vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx
index 770e857..1743d61 100644
--- a/vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx
+++ b/vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx
@@ -1546,46 +1546,6 @@ GtkSalGraphics::GtkSalGraphics( GtkSalFrame *pFrame, GtkWidget *pWindow )
     gtk_widget_path_free(path);
 }
 
-void GtkSalGraphics::copyArea( long nDestX, long nDestY,
-                               long nSrcX, long nSrcY,
-                               long nSrcWidth, long nSrcHeight,
-                               sal_uInt16 nFlags )
-{
-#if 1
-    SvpSalGraphics::copyArea( nDestX, nDestY, nSrcX, nSrcY, nSrcWidth, nSrcHeight, nFlags );
-#else
-    mpFrame->pushIgnoreDamage();
-    mpFrame->popIgnoreDamage();
-
-    cairo_rectangle_int_t rect = { (int)nSrcX, (int)nSrcY, (int)nSrcWidth, (int)nSrcHeight };
-    cairo_region_t *region = cairo_region_create_rectangle( &rect );
-
-    if (!m_aClipRegion.IsEmpty())
-    {
-        // get clip region and translate it in the opposite direction & intersect ...
-        cairo_region_t *clip_region = cairo_region_create();
-
-        RectangleVector aRectangles;
-        m_aClipRegion.GetRegionRectangles(aRectangles);
-        for (RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
-        {
-            cairo_rectangle_int_t aRect = { (int)aRectIter->Left(), (int)aRectIter->Top(),
-                                            (int)aRectIter->GetWidth(), (int)aRectIter->GetHeight() };
-            cairo_region_union_rectangle( clip_region, &aRect );
-        }
-
-        cairo_region_translate( clip_region, - (nDestX - nSrcX), - (nDestY - nSrcY) );
-        cairo_region_intersect( region, clip_region );
-        cairo_region_destroy( clip_region );
-    }
-
-    // FIXME: this will queue (duplicate) gtk+ re-rendering for the exposed area, c'est la vie
-    gdk_window_move_region( gtk_widget_get_window( mpFrame->getWindow() ),
-                            region, nDestX - nSrcX, nDestY - nSrcY );
-    cairo_region_destroy( region );
-#endif
-}
-
 cairo_t* GtkSalGraphics::getCairoContext()
 {
     return mpFrame->getCairoContext();


More information about the Libreoffice-commits mailing list