diff options
-rw-r--r-- | vcl/inc/salframe.hxx | 5 | ||||
-rw-r--r-- | vcl/inc/unx/gtk/gtkframe.hxx | 9 | ||||
-rw-r--r-- | vcl/source/app/salvtables.cxx | 7 | ||||
-rw-r--r-- | vcl/source/window/paint.cxx | 11 | ||||
-rw-r--r-- | vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx | 28 | ||||
-rw-r--r-- | vcl/unx/gtk/window/gtksalframe.cxx | 41 |
6 files changed, 66 insertions, 35 deletions
diff --git a/vcl/inc/salframe.hxx b/vcl/inc/salframe.hxx index acdb9b4b2d5e..f5213a101851 100644 --- a/vcl/inc/salframe.hxx +++ b/vcl/inc/salframe.hxx @@ -101,6 +101,9 @@ class VCL_PLUGIN_PUBLIC SalFrame : public vcl::DeletionNotifier , public SalGeometryProvider { +protected: + bool m_bAwaitingSizeConfirmation; +private: // the VCL window corresponding to this frame VclPtr<vcl::Window> m_pWindow; SALFRAMEPROC m_pProc; @@ -242,6 +245,8 @@ public: // (e.g. input methods, printer update handlers). long CallCallback( sal_uInt16 nEvent, const void* pEvent ) const { return m_pProc ? long(m_pProc( m_pWindow, const_cast<SalFrame*>(this), nEvent, pEvent )) : 0; } + + bool AwaitingSizeConfirmation() const { return m_bAwaitingSizeConfirmation; } }; #endif // INCLUDED_VCL_INC_SALFRAME_HXX diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx index 194a20dc9e4c..d46b87214e74 100644 --- a/vcl/inc/unx/gtk/gtkframe.hxx +++ b/vcl/inc/unx/gtk/gtkframe.hxx @@ -295,6 +295,15 @@ class GtkSalFrame : public SalFrame, public X11WindowProvider return (m_nStyle & nMask) != 0; } + //call gtk_window_resize if the current size differs and + //block Paints until Configure is received and the size + //is valid again + void window_resize(long nWidth, long nHeight); + //call gtk_widget_set_size_request if the current size request differs and + //block Paints until Configure is received and the size + //is valid again + void widget_set_size_request(long nWidth, long nHeight); + void resizeWindow( long nWidth, long nHeight ); void moveWindow( long nX, long nY ); diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index c51f4f60d954..7a68df22197d 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -29,7 +29,12 @@ #include <salmenu.hxx> -SalFrame::SalFrame() : m_pWindow( NULL ), m_pProc( NULL ) {} +SalFrame::SalFrame() + : m_bAwaitingSizeConfirmation(false) + , m_pWindow(NULL) + , m_pProc(NULL) +{ +} // this file contains the virtual destructors of the sal interface // compilers usually put their vtables where the destructor is diff --git a/vcl/source/window/paint.cxx b/vcl/source/window/paint.cxx index ae29766694c1..2bca30ea2ef0 100644 --- a/vcl/source/window/paint.cxx +++ b/vcl/source/window/paint.cxx @@ -584,12 +584,17 @@ IMPL_LINK_NOARG_TYPED(Window, ImplHandlePaintHdl, Idle *, void) return; } - // save paint events until resizing is done - if( !ImplDoTiledRendering() && - mpWindowImpl->mbFrame && mpWindowImpl->mpFrameData->maResizeIdle.IsActive() ) + // save paint events until resizing or initial sizing done + if (!ImplDoTiledRendering() && mpWindowImpl->mbFrame && + (mpWindowImpl->mpFrameData->maResizeIdle.IsActive() || + mpWindowImpl->mpFrame->AwaitingSizeConfirmation())) + { mpWindowImpl->mpFrameData->maPaintIdle.Start(); + } else if ( mpWindowImpl->mbReallyVisible ) + { ImplCallOverlapPaint(); + } } IMPL_LINK_NOARG_TYPED(Window, ImplHandleResizeTimerHdl, Idle *, void) diff --git a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx index 365dba82fc7f..463d9fe00ced 100644 --- a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx +++ b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx @@ -2914,31 +2914,11 @@ bool GtkSalGraphics::NWPaintGTKTabItem( ControlType nType, ControlPart, } END_CACHE_PIXMAP_RENDER( pixmapRect, pixmap, mask ) - // tdf#91301 workaround - // - // After introduction of the Idle processing, something has changed so - // that the underlying GetGdkWindow() does not update its size fast enough; - // even though the gtk_window_resize is called before the Window::Erase() - // (that actually paints the background) etc. - // - // The consequence of the not-yet-updated gdkDrawable is that we cache - // something that has the correct background in the top left 200x200 - // pixels, but the rest is just copied from the screen. - // - // Let's for now just not cache when the GetGdkWindow() is smaller than - // what we actually paint; TODO find the root cause. - gint width, height; - gdk_drawable_get_size(GetGdkWindow(), &width, &height); - bool bAllowCaching = (pixmapRect.Right() < width) && (pixmapRect.Bottom() < height); - // cache data - if (bAllowCaching) - { - if (nType == CTRL_TAB_ITEM) - aCacheItems.Fill(nType, nState, pixmapRect, pixmap, mask); - else - aCachePage.Fill(nType, nState, pixmapRect, pixmap, mask); - } + if( nType == CTRL_TAB_ITEM ) + aCacheItems.Fill( nType, nState, pixmapRect, pixmap, mask ); + else + aCachePage.Fill( nType, nState, pixmapRect, pixmap, mask ); return true; } diff --git a/vcl/unx/gtk/window/gtksalframe.cxx b/vcl/unx/gtk/window/gtksalframe.cxx index e590a8ab1bcd..d13acf0e37ae 100644 --- a/vcl/unx/gtk/window/gtksalframe.cxx +++ b/vcl/unx/gtk/window/gtksalframe.cxx @@ -933,12 +933,36 @@ void GtkSalFrame::moveWindow( long nX, long nY ) gtk_window_move( GTK_WINDOW(m_pWindow), nX, nY ); } +void GtkSalFrame::widget_set_size_request(long nWidth, long nHeight) +{ + gint nOrigwidth, nOrigheight; + gtk_widget_get_size_request(m_pWindow, &nOrigwidth, &nOrigheight); + if (nOrigwidth != nWidth || nOrigheight != nHeight) + { + m_bAwaitingSizeConfirmation = true; + gtk_widget_set_size_request(m_pWindow, nWidth, nHeight ); + } +} + +void GtkSalFrame::window_resize(long nWidth, long nHeight) +{ + gint nOrigwidth, nOrigheight; + gtk_window_get_size(GTK_WINDOW(m_pWindow), &nOrigwidth, &nOrigheight); + if (nOrigwidth != nWidth || nOrigheight != nHeight) + { + m_bAwaitingSizeConfirmation = true; + gtk_window_resize(GTK_WINDOW(m_pWindow), nWidth, nHeight); + } +} + void GtkSalFrame::resizeWindow( long nWidth, long nHeight ) { if( isChild( false, true ) ) - gtk_widget_set_size_request( m_pWindow, nWidth, nHeight ); + { + widget_set_size_request(nWidth, nHeight); + } else if( ! isChild( true, false ) ) - gtk_window_resize( GTK_WINDOW(m_pWindow), nWidth, nHeight ); + window_resize(nWidth, nHeight); } /* @@ -1459,7 +1483,7 @@ void GtkSalFrame::Init( SystemParentData* pSysData ) &aRoot, &x_ret, &y_ret, &w, &h, &bw, &d ); maGeometry.nWidth = w; maGeometry.nHeight = h; - gtk_window_resize( GTK_WINDOW(m_pWindow), w, h ); + window_resize(w, h); gtk_window_move( GTK_WINDOW(m_pWindow), 0, 0 ); if( ! m_bWindowIsGtkPlug ) { @@ -1955,10 +1979,12 @@ void GtkSalFrame::setMinMaxSize() aHints |= GDK_HINT_MAX_SIZE; } if( aHints ) + { gtk_window_set_geometry_hints( GTK_WINDOW(m_pWindow), NULL, &aGeo, GdkWindowHints( aHints ) ); + } } } @@ -1979,7 +2005,7 @@ void GtkSalFrame::SetMinClientSize( long nWidth, long nHeight ) m_aMinSize = Size( nWidth, nHeight ); if( m_pWindow ) { - gtk_widget_set_size_request( m_pWindow, nWidth, nHeight ); + widget_set_size_request(nWidth, nHeight ); // Show does a setMinMaxSize if( IS_WIDGET_MAPPED( m_pWindow ) ) setMinMaxSize(); @@ -2040,9 +2066,9 @@ void GtkSalFrame::SetPosSize( long nX, long nY, long nWidth, long nHeight, sal_u maGeometry.nHeight = nHeight; if( isChild( false, true ) ) - gtk_widget_set_size_request( m_pWindow, nWidth, nHeight ); + widget_set_size_request(nWidth, nHeight); else if( ! ( m_nState & GDK_WINDOW_STATE_MAXIMIZED ) ) - gtk_window_resize( GTK_WINDOW(m_pWindow), nWidth, nHeight ); + window_resize(nWidth, nHeight); setMinMaxSize(); } else if( m_bDefaultSize ) @@ -2365,7 +2391,7 @@ void GtkSalFrame::SetScreen( unsigned int nNewScreen, int eType, Rectangle *pSiz // temporarily re-sizeable if( !(m_nStyle & SAL_FRAME_STYLE_SIZEABLE) ) gtk_window_set_resizable( GTK_WINDOW(m_pWindow), TRUE ); - gtk_window_resize( GTK_WINDOW( m_pWindow ), maGeometry.nWidth, maGeometry.nHeight ); + window_resize(maGeometry.nWidth, maGeometry.nHeight); //I wonder if we should instead leave maGeometry alone and rely on //configure-event to trigger signalConfigure and set it there AllocateFrame(); @@ -3683,6 +3709,7 @@ gboolean GtkSalFrame::signalUnmap( GtkWidget*, GdkEvent*, gpointer frame ) gboolean GtkSalFrame::signalConfigure( GtkWidget*, GdkEventConfigure* pEvent, gpointer frame ) { GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame); + pThis->m_bAwaitingSizeConfirmation = false; bool bMoved = false, bSized = false; int x = pEvent->x, y = pEvent->y; |