[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    [PATCH] Menu's not painted correctly.
From:       Waldo Bastian <bastian () kde ! org>
Date:       2002-01-30 7:17:46
[Download RAW message or body]

Dear friends,

Last weekends up date of qt-copy has caused the return of the dreaded "Menubar 
doesn't get completely painted when application starts up". Not all 
applications seems to suffer from it, but the effect can be experienced in 
e.g. ksirc.

The reason that we had to live without this bug for many weeks is the first 
attached patch [qmenubar.pacth], courtesy of Lubos Lunak <l.lunak@sh.cvut.cz> 
It should be noted that this patch doesn't really try to fix this particular 
bug, it merily seems to do so as a side-effect.

Maks Orlovich pointed out that QMenuBar seems to end up with badSize=true. 
Some investigation with ksirc has learned that appearantly the conditions can 
be such when QMenuBar::show() gets called that the following happens:
* The menubar was resized (e.g. by resize(parentWidget()->width(), height() ); 
from QMenuBar::show() ) which posts a resizeEvent
* calculateRects updates the menubar layout (badSize is now false)
* then QWidget::show() gets called which first processes the resizeEvent. This 
invalidates the layout (badSize = true) and then the menubar is actually 
shown.

Unfotunately this situation will more or less persist and the layout will not 
get updated to take this last resizeEvent in account. The result is that only 
the first menu-item is shown, appearantly because the layout happens to be 
such that all menu-items are shown below each other.

The solution then seems to be to process the resize events before the 
calculateRects call in QMenuBar::show() Which leads to the second path 
attached [qmenubar2.patch] this does indeed solve the problem for ksirc.

Please review and include in Qt 3.0.2

Cheers,
Waldo
-- 
bastian@kde.org  |   SuSE Labs KDE Developer  |  bastian@suse.com

["qmenubar.patch" (text/x-diff)]

Index: qmenubar.cpp
===================================================================
RCS file: /home/kde/qt-copy/src/widgets/qmenubar.cpp,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- qmenubar.cpp	2001/12/12 13:15:16	1.34
+++ qmenubar.cpp	2001/12/29 22:48:13	1.35
@@ -1,5 +1,5 @@
 /****************************************************************************
-** $Id: qmenubar.cpp,v 1.34 2001/12/12 13:15:16 mueller Exp $
+** $Id: qmenubar.cpp,v 1.35 2001/12/29 22:48:13 lunakl Exp $
 **
 ** Implementation of QMenuBar class
 **
@@ -52,6 +52,7 @@
 #include <ctype.h>
 #include "../kernel/qinternal_p.h"
 #include "qstyle.h"
+#include "qtimer.h"
 #if defined(QT_ACCESSIBILITY_SUPPORT)
 #include "qaccessible.h"
 #endif
@@ -237,6 +238,7 @@
     hasmouse = 0;
     defaultup = 0;
     toggleclose = 0;
+    pendingdelayedupdates = 0;
     if ( parent ) {
 	// filter parent events for resizing
 	parent->installEventFilter( this );
@@ -339,10 +341,10 @@
 {
     QMenuData::menuContentsChanged();
 #ifndef QT_NO_ACCEL
-    setupAccelerators();
+    delayedSetupAccelerators();
 #endif
     badSize = TRUE;				// might change the size
-    calculateRects();
+    delayedCalculateRects();
     if ( isVisible() ) {
 	update();
 #ifndef QT_NO_MAINWINDOW
@@ -386,12 +388,39 @@
 
 void QMenuBar::menuStateChanged()
 {
+#ifndef QT_NO_ACCEL
+    delayedSetupAccelerators(); // ### when we have a good solution for the accel \
vs. focus widget problem, remove that. That is only a workaround +#endif
+    if( isVisible())
+        update();
+}
+
 #ifndef QT_NO_ACCEL
-    setupAccelerators(); // ### when we have a good solution for the accel vs. focus \
widget problem, remove that. That is only a workaround +void \
QMenuBar::delayedSetupAccelerators() +{
+    if( pendingdelayedupdates )
+        return;
+    QTimer::singleShot( 0, this, SLOT( performDelayedUpdates()));
+    pendingdelayedupdates = 1;
+}
 #endif
-    update();
+
+void QMenuBar::delayedCalculateRects()
+{
+    if( pendingdelayedupdates )
+        return;
+    QTimer::singleShot( 0, this, SLOT( performDelayedUpdates()));
+    pendingdelayedupdates = 1;
 }
 
+void QMenuBar::performDelayedUpdates()
+{
+#ifndef QT_NO_ACCEL
+    setupAccelerators();
+#endif
+    calculateRects();
+    pendingdelayedupdates = 0;
+}
 
 void QMenuBar::menuInsPopup( QPopupMenu *popup )
 {
Index: qmenubar.h
===================================================================
RCS file: /home/kde/qt-copy/src/widgets/qmenubar.h,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- qmenubar.h	2001/12/12 13:15:16	1.34
+++ qmenubar.h	2001/12/29 22:48:13	1.35
@@ -1,5 +1,5 @@
 /****************************************************************************
-** $Id: qmenubar.h,v 1.34 2001/12/12 13:15:16 mueller Exp $
+** $Id: qmenubar.h,v 1.35 2001/12/29 22:48:13 lunakl Exp $
 **
 ** Definition of QMenuBar class
 **
@@ -117,6 +117,7 @@
     void	accelActivated( int itemId );
     void	accelDestroyed();
 #endif
+    void        performDelayedUpdates();
 
 private:
     void	menuInsPopup( QPopupMenu * );
@@ -132,10 +133,12 @@
     void setAltMode( bool );
 
     int		calculateRects( int max_width = -1 );
+    void        delayedCalculateRects();
 
 #ifndef QT_NO_ACCEL
     void	setupAccelerators();
     QAccel     *autoaccel;
+    void        delayedSetupAccelerators();
 #endif
     QRect      *irects;
     int		rightSide;
@@ -146,6 +149,7 @@
     uint	hasmouse : 1;
     uint 	defaultup : 1;
     uint 	toggleclose : 1;
+    uint        pendingdelayedupdates : 1;
 
     friend class QPopupMenu;
 


["qmenubar2.patch" (text/x-diff)]

Index: qmenubar.cpp
===================================================================
RCS file: /home/kde/qt-copy/src/widgets/qmenubar.cpp,v
retrieving revision 1.37
diff -u -r1.37 qmenubar.cpp
--- qmenubar.cpp	2002/01/26 20:49:32	1.37
+++ qmenubar.cpp	2002/01/30 07:10:37
@@ -706,6 +706,7 @@
 
     if ( parentWidget() )
 	resize( parentWidget()->width(), height() );
+    QApplication::sendPostedEvents( this, QEvent::Resize );
     calculateRects();
 
 #if defined(Q_WS_MAC) && !defined(QMAC_QMENUBAR_NO_NATIVE)


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic