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

List:       kde-core-devel
Subject:    Re: KToolBar problem
From:       Reginald Stadlbauer <reggie () trolltech ! com>
Date:       2000-10-06 17:50:34
[Download RAW message or body]

On Fri, 06 Oct 2000, Michael Reiher wrote:

> > Hi
>
> There is some evil problem in KToolBar which leads to weird crashes in
> Konqueror in certain cases when you manipulate your boorkmarks. The most
> relieable way is probably deleting a bunch of bookmarks at once.
>
> The problem is that KToolBar keeps a second list of widgets which is read
> during rebuildLayout() and if there are illegal pointers in it -> crash.
> Widgets are removed from that list either explicitly or by a ChildRemove
> event. So normally when you delete a widget it gets cleand out by the
> event. However if you delete it so quickly that the ChildInserted event
> dosnīt get posted QObject simply deletes the Remove(and the Inserted)
> event. So KToolBar doesnīt get notifyed about the remove. And this is the
> case when modifying bookmarks. KBookmarkBar runs slotBookmarksChanged()
> which rebuilds the bookmarkbar. There is some kind of placeholder widget or
> whatever which gets simply deleted. KBookmarkbar doesnīt get the Removed
> event and keeps it -> crash on next layout.
>
> Iīm kinda unsure what to do now. Possible solutions:
> 1. Remove the placeholder widget. Doesnīt seem to serve any useful purpose
> anyway.
> 2. Explicitly remove it when clearing KBookmarkBar
> But these two are actually cheating and donīt fix the real Problem;-)
>
> 3. Implement some mechanism which compares KToolBars "widgets" list with
> the children() list and throw out illegal pointers. Though this one would
> have to be put in *every* place which accesses the widget list. Hmm...
>
> IMO all three are sub optimal. With regard to the current freeze Iīd go for
> 1. or 2. as they are the least dangerous. Attached a patch for 2.
>
> Any comments, please? Has anyone a better idea? Perhaps someone with more
> insight into
> KToolBar?

Ok, following patch in KToolBar fixes the problem for me. Could be done 
cleaner with using QGuarderPtr<QWidget> in the list and maps instead of 
QWidget, but I think this wouldn't be binary compatible. So please review and 
test this one:

cvs server: Diffing .
Index: ktoolbar.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdeui/ktoolbar.cpp,v
retrieving revision 1.244
diff -u -u -r1.244 ktoolbar.cpp
--- ktoolbar.cpp        2000/09/25 17:04:36     1.244
+++ ktoolbar.cpp        2000/10/06 19:39:49
@@ -132,6 +132,8 @@
 {
     connect( parent, SIGNAL(orientationChanged(Orientation)),
              this, SLOT(setOrientation(Orientation)) );
+    connect( this, SIGNAL(destroyed()),
+             parent, SLOT(widgetDestroyed()));
     setOrientation( o );
     setBackgroundMode( parent->backgroundMode() );
     setBackgroundOrigin( ParentOrigin );
@@ -1336,6 +1338,8 @@
            insertWidgetInternal( (QWidget*)e->child(), dummy, -1 );
            if ( !e->child()->inherits( "QPopupMenu" ) )
                ( (QWidget*)e->child() )->show();
+           connect( (QWidget*)e->child(), SIGNAL( destroyed() ),
+                    this, SLOT( widgetDestroyed() ) );
        } else {
            widgets.removeRef( (QWidget*)e->child() );
        }
@@ -1975,6 +1979,18 @@
       break;
   default: break;
   }
+}
+
+void KToolBar::widgetDestroyed()
+{
+    if ( !sender()->inherits( "QWidget" ) )
+       return;
+    widgets.removeRef( (QWidget*)sender() );
+    QMap< QWidget*, int >::Iterator it = widget2id.find( (QWidget*)sender() 
);
+    if ( it == widget2id.end() )
+       return;
+    widget2id.remove( it );
+    id2widget.remove( *it );
 }
 
 #include "ktoolbar.moc"
Index: ktoolbar.h
===================================================================
RCS file: /home/kde/kdelibs/kdeui/ktoolbar.h,v
retrieving revision 1.123
diff -u -u -r1.123 ktoolbar.h
--- ktoolbar.h  2000/09/25 17:04:36     1.123
+++ ktoolbar.h  2000/10/06 19:39:49
@@ -998,7 +998,8 @@
     void slotRepaint();
     void toolBarPosChanged( QToolBar *tb );
     void slotContextAboutToShow();
-
+    void widgetDestroyed();
+
 private:
     void init( bool readConfig = true, bool honorStyle = false );
     void doConnections( KToolBarButton *button );                            
  

-- 
Reggie (reggie@trolltech.com)

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

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