From eb627dd0702a9e2fd89021aff34dc4767d39532c Mon Sep 17 00:00:00 2001 From: Michail Vourlakos Date: Sun, 30 Aug 2020 14:34:56 +0300 Subject: [PATCH] multiple mode:animate properly layouts unloading --- app/layouts/synchronizer.cpp | 82 +++++++++++++++++++++++------------- app/layouts/synchronizer.h | 1 + app/view/positioner.cpp | 9 +++- app/view/positioner.h | 2 + app/view/view.cpp | 2 +- 5 files changed, 65 insertions(+), 31 deletions(-) diff --git a/app/layouts/synchronizer.cpp b/app/layouts/synchronizer.cpp index fd43702a4..f3202abe3 100644 --- a/app/layouts/synchronizer.cpp +++ b/app/layouts/synchronizer.cpp @@ -43,6 +43,8 @@ #include #include +#define LAYOUTSINITINTERVAL 350 + namespace Latte { namespace Layouts { @@ -546,7 +548,7 @@ bool Synchronizer::initSingleMode(QString layoutName) //! this code must be called asynchronously because it can create crashes otherwise. //! Tasks plasmoid case that triggers layouts switching through its context menu - QTimer::singleShot(350, [this, layoutName, layoutpath]() { + QTimer::singleShot(LAYOUTSINITINTERVAL, [this, layoutName, layoutpath]() { qDebug() << " ... initializing layout in single mode : " << layoutName << " - " << layoutpath; unloadLayouts(); @@ -576,7 +578,7 @@ bool Synchronizer::initMultipleMode(QString layoutName) //! this code must be called asynchronously because it can create crashes otherwise. //! Tasks plasmoid case that triggers layouts switching through its context menu - QTimer::singleShot(350, [this, layoutName]() { + QTimer::singleShot(LAYOUTSINITINTERVAL, [this, layoutName]() { qDebug() << " ... initializing layout in multiple mode : " << layoutName ; unloadLayouts(); @@ -657,18 +659,18 @@ void Synchronizer::syncMultipleLayoutsToActivities() qDebug() << " ---- --------- ------ syncMultipleLayoutsToActivities ------- "; qDebug() << " ---- --------- ------ ------------------------------- ------- "; - QStringList layoutsToUnload; - QStringList layoutsToLoad; - QStringList currents = centralLayoutsNames(); + QStringList layoutNamesToUnload; + QStringList layoutNamesToLoad; + QStringList currentNames = centralLayoutsNames(); //! discover OnAllActivities layouts if (m_assignedLayouts.contains(Data::Layout::ALLACTIVITIESID)) { - layoutsToLoad << m_assignedLayouts[Data::Layout::ALLACTIVITIESID]; + layoutNamesToLoad << m_assignedLayouts[Data::Layout::ALLACTIVITIESID]; } //! discover ForFreeActivities layouts if (m_assignedLayouts.contains(Data::Layout::FREEACTIVITIESID)) { - layoutsToLoad << m_assignedLayouts[Data::Layout::FREEACTIVITIESID]; + layoutNamesToLoad << m_assignedLayouts[Data::Layout::FREEACTIVITIESID]; } //! discover layouts assigned to explicit activities based on running activities @@ -680,41 +682,41 @@ void Synchronizer::syncMultipleLayoutsToActivities() } if (m_assignedLayouts.contains(activity)) { - layoutsToLoad << m_assignedLayouts[activity]; + layoutNamesToLoad << m_assignedLayouts[activity]; } } //! discover layouts that must be unloaded because of running activities changes for (const auto layout : m_centralLayouts) { - if (!layoutsToLoad.contains(layout->name())) { - layoutsToUnload << layout->name(); + if (!layoutNamesToLoad.contains(layout->name())) { + layoutNamesToUnload << layout->name(); } } QString defaultForcedLayout; //! Safety - if (layoutsToLoad.isEmpty()) { + if (layoutNamesToLoad.isEmpty()) { //! If no layout is found then force loading Default Layout QString layoutPath = m_manager->corona()->templatesManager()->newLayout("", i18n(Templates::DEFAULTLAYOUTTEMPLATENAME)); - layoutsToLoad << Layout::AbstractLayout::layoutName(layoutPath); - m_manager->setOnAllActivities(layoutsToLoad[0]); - defaultForcedLayout = layoutsToLoad[0]; + layoutNamesToLoad << Layout::AbstractLayout::layoutName(layoutPath); + m_manager->setOnAllActivities(layoutNamesToLoad[0]); + defaultForcedLayout = layoutNamesToLoad[0]; } QStringList newlyActivatedLayouts; //! Add needed Layouts based on Activities settings - for (const auto &layoutName : layoutsToLoad) { - if (!centralLayout(layoutName)) { - CentralLayout *newLayout = new CentralLayout(this, QString(layoutPath(layoutName)), layoutName); + for (const auto &layoutname : layoutNamesToLoad) { + if (!centralLayout(layoutname)) { + CentralLayout *newLayout = new CentralLayout(this, QString(layoutPath(layoutname)), layoutname); if (newLayout) { - qDebug() << "ACTIVATING LAYOUT ::::: " << layoutName; + qDebug() << "ACTIVATING LAYOUT ::::: " << layoutname; addLayout(newLayout); newLayout->importToCorona(); - if (!defaultForcedLayout.isEmpty() && defaultForcedLayout == layoutName) { + if (!defaultForcedLayout.isEmpty() && defaultForcedLayout == layoutname) { emit newLayoutAdded(newLayout->data()); } @@ -732,12 +734,39 @@ void Synchronizer::syncMultipleLayoutsToActivities() } //! Unload no needed Layouts - for (const auto &layoutName : layoutsToUnload) { - CentralLayout *layout = centralLayout(layoutName); - int posLayout = centralLayoutPos(layoutName); + + //! hide layouts that will be removed in the end + if (!layoutNamesToUnload.isEmpty()) { + for (const auto layoutname : layoutNamesToUnload) { + emit currentLayoutIsSwitching(layoutname); + } + + QTimer::singleShot(LAYOUTSINITINTERVAL, [this, layoutNamesToUnload]() { + unloadLayouts(layoutNamesToUnload); + }); + } + + qSort(currentNames); + qSort(layoutNamesToLoad); + + if (currentNames != layoutNamesToLoad) { + emit centralLayoutsChanged(); + } +} + +void Synchronizer::unloadLayouts(const QStringList &layoutNames) +{ + if (layoutNames.isEmpty()) { + return; + } + + //! Unload no needed Layouts + for (const auto &layoutname : layoutNames) { + CentralLayout *layout = centralLayout(layoutname); + int posLayout = centralLayoutPos(layoutname); if (posLayout >= 0) { - qDebug() << "REMOVING LAYOUT ::::: " << layoutName; + qDebug() << "REMOVING LAYOUT ::::: " << layoutname; m_centralLayouts.removeAt(posLayout); layout->syncToLayoutFile(true); @@ -748,12 +777,7 @@ void Synchronizer::syncMultipleLayoutsToActivities() } } - qSort(currents); - qSort(layoutsToLoad); - - if (currents != layoutsToLoad) { - emit centralLayoutsChanged(); - } + emit centralLayoutsChanged(); } void Synchronizer::updateKWinDisabledBorders() diff --git a/app/layouts/synchronizer.h b/app/layouts/synchronizer.h index b803b67a2..af208c57e 100644 --- a/app/layouts/synchronizer.h +++ b/app/layouts/synchronizer.h @@ -141,6 +141,7 @@ private slots: private: void addLayout(CentralLayout *layout); void unloadCentralLayout(CentralLayout *layout); + void unloadLayouts(const QStringList &layoutNames); bool initSingleMode(QString layoutName); bool initMultipleMode(QString layoutName); diff --git a/app/view/positioner.cpp b/app/view/positioner.cpp index 32b8d6d03..e20f05c26 100644 --- a/app/view/positioner.cpp +++ b/app/view/positioner.cpp @@ -274,10 +274,12 @@ QString Positioner::currentScreenName() const void Positioner::onCurrentLayoutIsSwitching(const QString &layoutName) { - if (!m_view || !m_view->layout() || m_view->layout()->name() != layoutName) { + if (!m_view || !m_view->layout() || m_view->layout()->name() != layoutName || !m_view->isVisible()) { return; } + m_inLayoutUnloading = true; + auto slideLocation = WindowSystem::AbstractWindowInterface::Slide::None; switch (m_view->containment()->location()) { @@ -961,6 +963,11 @@ void Positioner::initSignalingForLocationChangeSliding() }); } +bool Positioner::inLayoutUnloading() +{ + return m_inLayoutUnloading; +} + bool Positioner::inLocationAnimation() { return ((m_goToLocation != Plasma::Types::Floating) || (m_moveToLayout != "") || m_goToScreen); diff --git a/app/view/positioner.h b/app/view/positioner.h index 9b6ebf4d0..7958cdb7b 100644 --- a/app/view/positioner.h +++ b/app/view/positioner.h @@ -69,6 +69,7 @@ public: int slideOffset() const; void setSlideOffset(int offset); + bool inLayoutUnloading(); bool inLocationAnimation(); bool inSlideAnimation() const; @@ -156,6 +157,7 @@ private: private: bool m_inDelete{false}; + bool m_inLayoutUnloading{false}; bool m_inLocationAnimation{false}; bool m_inSlideAnimation{false}; diff --git a/app/view/view.cpp b/app/view/view.cpp index 3439e0936..cf124cfe0 100644 --- a/app/view/view.cpp +++ b/app/view/view.cpp @@ -1181,7 +1181,7 @@ void View::setLayout(Layout::GenericLayout *layout) m_visibleHackTimer2.setSingleShot(true); connectionsLayout << connect(this, &QWindow::visibleChanged, this, [&]() { - if (m_layout && !inDelete() & !isVisible()) { + if (m_layout && !inDelete() && !isVisible() && !m_positioner->inLayoutUnloading()) { m_visibleHackTimer1.start(); m_visibleHackTimer2.start(); }