From 2b5c43a5413fba30bc088df42db970f015c120b1 Mon Sep 17 00:00:00 2001 From: Michail Vourlakos Date: Thu, 5 Jan 2017 17:48:27 +0200 Subject: [PATCH] fix #41, a crash when a dock was removed --removing connections on xwindowinterface destructor --removing connections on dockview destructor --remove xwindowinterface that was created from visibilitymanager in its destructor --- app/dockview.cpp | 12 +++++-- app/dockview.h | 3 ++ app/visibilitymanager.cpp | 76 ++++++++++++++++++++------------------- app/xwindowinterface.cpp | 32 ++++++++++------- app/xwindowinterface.h | 3 +- 5 files changed, 74 insertions(+), 52 deletions(-) diff --git a/app/dockview.cpp b/app/dockview.cpp index b805faebc..ac7e2d69b 100644 --- a/app/dockview.cpp +++ b/app/dockview.cpp @@ -98,12 +98,20 @@ DockView::DockView(Plasma::Corona *corona, QScreen *targetScreen) DockCorona *dcorona = qobject_cast(this->corona()); if (dcorona) { - connect(dcorona, &DockCorona::containmentsNoChanged, this, &DockView::updateDocksCount); + connections << connect(dcorona, &DockCorona::containmentsNoChanged, this, &DockView::updateDocksCount); } } DockView::~DockView() { + qDebug() << "dock view deleting..."; + + foreach (auto var, connections) { + QObject::disconnect(var); + } + + qDebug() << "dock view connections deleted..."; + if (m_visibility) { m_visibility->deleteLater(); } @@ -125,7 +133,7 @@ void DockView::init() m_timerGeometry.start(); }); - connect(&WindowSystem::self(), &WindowSystem::compositingChanged + connections << connect(&WindowSystem::self(), &WindowSystem::compositingChanged , this, [&]() { emit compositingChanged(); } , Qt::QueuedConnection); diff --git a/app/dockview.h b/app/dockview.h index 92f029e99..26780c796 100644 --- a/app/dockview.h +++ b/app/dockview.h @@ -96,6 +96,7 @@ public: bool tasksPresent() const; void adaptToScreen(QScreen *screen); + void unload(); QQmlListProperty screens(); static int countScreens(QQmlListProperty *property); @@ -174,6 +175,8 @@ private: Plasma::Theme *theme{nullptr}; QPointer m_visibility; + + QList connections; void initWindow(); diff --git a/app/visibilitymanager.cpp b/app/visibilitymanager.cpp index 3c4782885..905d90737 100644 --- a/app/visibilitymanager.cpp +++ b/app/visibilitymanager.cpp @@ -64,6 +64,7 @@ VisibilityManagerPrivate::VisibilityManagerPrivate(PlasmaQuick::ContainmentView VisibilityManagerPrivate::~VisibilityManagerPrivate() { wm->removeDockStruts(); + wm->deleteLater(); } inline void VisibilityManagerPrivate::setMode(Dock::Visibility mode) @@ -178,7 +179,7 @@ void VisibilityManagerPrivate::setBlockHiding(bool blockHiding) this->blockHiding = blockHiding; - qDebug() << "blockHiding:" << blockHiding; + qDebug() << "blockHiding:" << blockHiding; if (this->blockHiding) { timerHide.stop(); @@ -375,42 +376,46 @@ inline void VisibilityManagerPrivate::restoreConfig() bool VisibilityManagerPrivate::event(QEvent *ev) { switch (ev->type()) { - case QEvent::Enter: - if (containsMouse) + case QEvent::Enter: + if (containsMouse) + break; + + containsMouse = true; + emit q->containsMouseChanged(); + + if (mode != Dock::AlwaysVisible) + raiseDock(true); + break; - - containsMouse = true; - emit q->containsMouseChanged(); - - if (mode != Dock::AlwaysVisible) - raiseDock(true); - - break; - case QEvent::Leave: - if (!containsMouse) + + case QEvent::Leave: + if (!containsMouse) + break; + + containsMouse = false; + emit q->containsMouseChanged(); + updateHiddenState(); + + break; + + case QEvent::DragEnter: + dragEnter = true; + emit q->mustBeShown(); + + break; + + case QEvent::DragLeave: + case QEvent::Drop: + dragEnter = false; + updateHiddenState(); + + break; + + case QEvent::Show: + wm->setDockDefaultFlags(); + restoreConfig(); + break; - - containsMouse = false; - emit q->containsMouseChanged(); - updateHiddenState(); - - break; - case QEvent::DragEnter: - dragEnter = true; - emit q->mustBeShown(); - - break; - case QEvent::DragLeave: - case QEvent::Drop: - dragEnter = false; - updateHiddenState(); - - break; - case QEvent::Show: - wm->setDockDefaultFlags(); - restoreConfig(); - - break; } return QObject::event(ev); @@ -490,4 +495,3 @@ void VisibilityManager::updateDockGeometry(const QRect &geometry) } //! END: VisibilityManager implementation } - diff --git a/app/xwindowinterface.cpp b/app/xwindowinterface.cpp index 08ac4620f..890198a5f 100644 --- a/app/xwindowinterface.cpp +++ b/app/xwindowinterface.cpp @@ -35,14 +35,14 @@ XWindowInterface::XWindowInterface(QQuickWindow *const view, QObject *parent) { Q_ASSERT(view != nullptr); - connect(KWindowSystem::self(), &KWindowSystem::activeWindowChanged - , this, &AbstractWindowInterface::activeWindowChanged); - - connect(KWindowSystem::self() - , static_cast - (&KWindowSystem::windowChanged) - , this, &XWindowInterface::windowChangedProxy); - + connections << connect(KWindowSystem::self(), &KWindowSystem::activeWindowChanged + , this, &AbstractWindowInterface::activeWindowChanged); + + connections << connect(KWindowSystem::self() + , static_cast + (&KWindowSystem::windowChanged) + , this, &XWindowInterface::windowChangedProxy); + auto addWindow = [&](WId wid) { if (std::find(m_windows.cbegin(), m_windows.cend(), wid) == m_windows.cend()) { if (isValidWindow(KWindowInfo(wid, NET::WMWindowType))) { @@ -52,18 +52,18 @@ XWindowInterface::XWindowInterface(QQuickWindow *const view, QObject *parent) } }; - connect(KWindowSystem::self(), &KWindowSystem::windowAdded, this, addWindow); + connections << connect(KWindowSystem::self(), &KWindowSystem::windowAdded, this, addWindow); - connect(KWindowSystem::self(), &KWindowSystem::windowRemoved, [this](WId wid) { + connections << connect(KWindowSystem::self(), &KWindowSystem::windowRemoved, [this](WId wid) { if (std::find(m_windows.cbegin(), m_windows.cend(), wid) != m_windows.end()) { m_windows.remove(wid); emit windowRemoved(wid); } }); - connect(KWindowSystem::self(), &KWindowSystem::currentDesktopChanged - , this, &AbstractWindowInterface::currentDesktopChanged); - + connections << connect(KWindowSystem::self(), &KWindowSystem::currentDesktopChanged + , this, &AbstractWindowInterface::currentDesktopChanged); + // fill windows list foreach (const auto &wid, KWindowSystem::self()->windows()) { addWindow(wid); @@ -72,7 +72,13 @@ XWindowInterface::XWindowInterface(QQuickWindow *const view, QObject *parent) XWindowInterface::~XWindowInterface() { + qDebug() << "x window interface deleting..."; + + foreach (auto var, connections) { + QObject::disconnect(var); + } + qDebug() << "x window interface connections removed..."; } void XWindowInterface::setDockDefaultFlags() diff --git a/app/xwindowinterface.h b/app/xwindowinterface.h index 020ca671c..e61c23778 100644 --- a/app/xwindowinterface.h +++ b/app/xwindowinterface.h @@ -54,6 +54,8 @@ private: void windowChangedProxy(WId wid, NET::Properties prop1, NET::Properties2 prop2); WId m_desktopId; + + QList connections; }; } @@ -62,4 +64,3 @@ private: -