[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-core-devel
Subject: Re: got it! (Re: Kicker memory leaks)
From: Josef Weidendorfer <Josef.Weidendorfer () gmx ! de>
Date: 2002-05-08 22:56:40
[Download RAW message or body]
Hi,
a follow-up:
I looked into the KDirWatch problem with PanelBrowserMenu again,
because the KDirWatch instance should have been deleted even
before my patch, and I found the real problem:
NO PanelBrowserMenu instance is deleted at all, my patch changes
nothing about the memory leak (OK: the menu regeneration are
a lot less now).
Reason: The manual of
QPopupMenu::insertItem(*,*,QPopupMenu)
that is used for inserting new menus states, that inserted submenus
aren't deleted when clearing the menu! Thus, submenus exist as long
as the parent exists, and as the top parent is kicker itself, the QObject
cleanup happens only at kicker termination; all the submenus which are
regenerated on a KDirWatch event, are NEVER deleted till termination!
Attached patch:
=2D PanelBrowserMenu::slotClear reimplements KPanelMenu::slotClear
and correctly delete the submenus (Question: should submenu
deletion handling be done in KPanelMenu, as this deletion bug probably
exists for the K-Menu too ?!??).
=2D KDirWatch events simply call slotClear; this is much better than
regenerating menus that aren't visible at all. The menus are always
regenerated if needed before they are shown (slotAboutToShow calls
initialize() !)
=2D Menus should NOT be changed when shown. When shown, a change
is marked in a dirty flag. When the menu is shown the next time,
the menu is updated before (in initialize()).
=2D Start KDirWatch as late as possible (in initialize()), and remove
it as early as possible (in slotClear())
This leads to a much saner behaviour now. Note that opening a
quickbrowser on /proc/self or on /tmp while compiling rendered
kicker useless before this change.
Please check and commit to BRANCH and HEAD again :-)
Cheers,
Josef
On Wednesday 08 May 2002 18:27, Matthias Elter wrote:
> On Wednesday 08 May 2002 17:54, Josef Weidendorfer wrote:
> > Can somebody check and apply to BRANCH and HEAD?
> > (Perhaps even for KDE 3.0.1)
>
> Done, thanks.
>
> Matthias
["kicker.diff" (text/x-diff)]
? ~kicker.diff
Index: ui/browser_mnu.cpp
===================================================================
RCS file: /home/kde/kdebase/kicker/ui/browser_mnu.cpp,v
retrieving revision 1.37
diff -u -3 -p -r1.37 browser_mnu.cpp
--- ui/browser_mnu.cpp 2002/05/08 16:27:37 1.37
+++ ui/browser_mnu.cpp 2002/05/08 22:57:47
@@ -54,25 +54,33 @@ PanelBrowserMenu::PanelBrowserMenu(QStri
: KPanelMenu(path, parent, name)
, _mimecheckTimer(0)
, _startid(startid)
+ , _dirty(false)
{
+ _subMenus.setAutoDelete(true);
_lastpress = QPoint(-1, -1);
setAcceptDrops(true); // Should depend on permissions of path.
// we are not interested for dirty events on files inside the
- // directory (see reinitializeIfNeeded)
+ // directory (see slotClearIfNeeded)
connect( &_dirWatch, SIGNAL(dirty(const QString&)),
- this, SLOT(reinitializeIfNeeded(const QString&)) );
+ this, SLOT(slotClearIfNeeded(const QString&)) );
connect( &_dirWatch, SIGNAL(created(const QString&)),
- this, SLOT(reinitialize()) );
+ this, SLOT(slotClear()) );
connect( &_dirWatch, SIGNAL(deleted(const QString&)),
- this, SLOT(reinitialize()) );
- _dirWatch.addDir( path );
+ this, SLOT(slotClear()) );
+
+ kdDebug() << "PanelBrowserMenu Constructor " << path << endl;
+}
+
+PanelBrowserMenu::~PanelBrowserMenu()
+{
+ kdDebug() << "PanelBrowserMenu Destructor " << path() << endl;
}
-void PanelBrowserMenu::reinitializeIfNeeded(const QString& p)
+void PanelBrowserMenu::slotClearIfNeeded(const QString& p)
{
- if (p == path())
- reinitialize();
+ if (p == path())
+ slotClear();
}
@@ -80,9 +88,24 @@ void PanelBrowserMenu::initialize()
{
_lastpress = QPoint(-1, -1);
+ // don't change menu if already visible
+ if (isVisible())
+ return;
+
+ if (_dirty) {
+ // directory content changed while menu was visible
+ slotClear();
+ setInitialized(false);
+ _dirty = false;
+ }
+
if (initialized()) return;
setInitialized(true);
+ // start watching if not already done
+ if (!_dirWatch.contains(path()))
+ _dirWatch.addDir( path() );
+
// setup icon map
initIconMap();
@@ -254,7 +277,7 @@ void PanelBrowserMenu::initialize()
++it;
if( it.current() ) {
insertSeparator();
- insertItem(CICON("folder_open"), i18n("More..."), new \
PanelBrowserMenu(path(), this, 0, run_id)); + \
append(CICON("folder_open"), i18n("More..."), new PanelBrowserMenu(path(), this, 0, \
run_id)); }
break;
}
@@ -324,6 +347,8 @@ void PanelBrowserMenu::append(const QPix
// insert submenu
insertItem(pixmap, newTitle, subMenu);
+ // remember submenu for later deletion
+ _subMenus.append(subMenu);
}
void PanelBrowserMenu::mousePressEvent(QMouseEvent *e)
@@ -437,6 +462,21 @@ void PanelBrowserMenu::slotMimeCheck()
changeItem(id, CICON(icon), file);
}
+void PanelBrowserMenu::slotClear()
+{
+ // no need to watch any further
+ if (_dirWatch.contains(path()))
+ _dirWatch.removeDir( path() );
+
+ // don't change menu if already visible
+ if (isVisible()) {
+ _dirty = true;
+ return;
+ }
+ KPanelMenu::slotClear();
+ _subMenus.clear(); // deletes submenus
+}
+
void PanelBrowserMenu::initIconMap()
{
if(_icons) return;
@@ -455,3 +495,4 @@ void PanelBrowserMenu::initIconMap()
_icons->insert("exec", SmallIcon("exec"));
_icons->insert("chardevice", SmallIcon("chardevice"));
}
+
Index: ui/browser_mnu.h
===================================================================
RCS file: /home/kde/kdebase/kicker/ui/browser_mnu.h,v
retrieving revision 1.14
diff -u -3 -p -r1.14 browser_mnu.h
--- ui/browser_mnu.h 2002/05/08 16:27:37 1.14
+++ ui/browser_mnu.h 2002/05/08 22:57:47
@@ -25,6 +25,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE
#define __browser_mnu_h__
#include <qmap.h>
+#include <qptrlist.h>
#include <kpanelmenu.h>
#include <kdirwatch.h>
@@ -34,6 +35,7 @@ class PanelBrowserMenu : public KPanelMe
public:
PanelBrowserMenu(QString path, QWidget *parent = 0, const char *name = 0, int \
startid = 0); + ~PanelBrowserMenu();
void append(const QPixmap &pixmap, const QString &title, const QString \
&filename, bool mimecheck);
void append(const QPixmap &pixmap, const QString &title, PanelBrowserMenu \
*subMenu); @@ -46,14 +48,14 @@ protected slots:
void slotOpenTerminal();
void slotOpenFileManager();
void slotMimeCheck();
- void reinitializeIfNeeded(const QString&);
+ void slotClearIfNeeded(const QString&);
+ void slotClear();
protected:
void mousePressEvent(QMouseEvent *);
void mouseMoveEvent(QMouseEvent *);
void dropEvent(QDropEvent *ev);
void dragEnterEvent(QDragEnterEvent *ev);
-
void initIconMap();
QPoint _lastpress;
@@ -61,10 +63,12 @@ protected:
QMap<int, bool> _mimemap;
QTimer *_mimecheckTimer;
KDirWatch _dirWatch;
+ QPtrList<PanelBrowserMenu> _subMenus;
int _startid;
bool _showhidden;
int _maxentries;
+ bool _dirty;
static QMap<QString, QPixmap> *_icons;
};
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic