1
0
mirror of https://github.com/KDE/latte-dock.git synced 2024-12-25 19:21:41 +03:00

fix crashes from loading/unloading layouts

This commit is contained in:
Michail Vourlakos 2019-04-07 17:20:10 +03:00
parent 9236f18c4e
commit dc9553b3ca
7 changed files with 73 additions and 70 deletions

View File

@ -52,6 +52,16 @@ ActiveLayout::~ActiveLayout()
}
}
void ActiveLayout::unloadContainments()
{
Layout::GenericLayout::unloadContainments();
if (m_topLayout) {
disconnect(m_topLayout, &Layout::GenericLayout::viewsCountChanged, this, &Layout::GenericLayout::viewsCountChanged);
m_topLayout->removeActiveLayout(this);
}
}
void ActiveLayout::init()
{
connect(this, &ActiveLayout::activitiesChanged, this, &ActiveLayout::saveConfig);
@ -191,14 +201,14 @@ void ActiveLayout::setTopLayoutName(QString name)
void ActiveLayout::setTopLayout(TopLayout *layout)
{
if (m_topLayout != layout) {
if (m_topLayout == layout) {
return;
}
disconnect(m_topLayout, &GenericLayout::viewsCountChanged, this, &GenericLayout::viewsCountChanged);
disconnect(m_topLayout, &Layout::GenericLayout::viewsCountChanged, this, &Layout::GenericLayout::viewsCountChanged);
m_topLayout = layout;
connect(m_topLayout, &GenericLayout::viewsCountChanged, this, &GenericLayout::viewsCountChanged);
connect(m_topLayout, &Layout::GenericLayout::viewsCountChanged, this, &Layout::GenericLayout::viewsCountChanged);
emit viewsCountChanged();
}
@ -262,4 +272,6 @@ const QStringList ActiveLayout::appliedActivities()
}
}
}

View File

@ -64,6 +64,8 @@ public:
QStringList activities() const;
void setActivities(QStringList activities);
//! overrides
void unloadContainments() override;
const QStringList appliedActivities() override;
signals:

View File

@ -64,6 +64,7 @@ void GenericLayout::unloadContainments()
//!disconnect signals in order to avoid crashes when the layout is unloading
disconnect(this, &GenericLayout::viewsCountChanged, m_corona, &Plasma::Corona::availableScreenRectChanged);
disconnect(this, &GenericLayout::viewsCountChanged, m_corona, &Plasma::Corona::availableScreenRegionChanged);
disconnect(m_corona->activityConsumer(), &KActivities::Consumer::currentActivityChanged, this, &GenericLayout::updateLastUsedActivity);
qDebug() << "Layout - " + name() + " unload: containments ... size ::: " << m_containments.size()
<< " ,latteViews in memory ::: " << m_latteViews.size()

View File

@ -96,7 +96,7 @@ public:
void lock(); //! make it only read-only
void renameLayout(QString newName);
void syncLatteViewsToScreens();
void unloadContainments();
virtual void unloadContainments();
void unloadLatteViews();
void unlock(); //! make it writable which it should be the default

View File

@ -56,13 +56,8 @@ void TopLayout::addActiveLayout(ActiveLayout *layout)
if (layout != nullptr && !m_activeLayouts.contains(layout)) {
m_activeLayouts.append(layout);
connect(layout, &QObject::destroyed, this, [&]() {
disconnect(layout, &GenericLayout::activitiesChanged, this, &GenericLayout::activitiesChanged);
removeActiveLayout(layout);
});
connect(layout, &GenericLayout::activitiesChanged, this, &GenericLayout::activitiesChanged);
emit activitiesChanged();
emit viewsCountChanged();
}
}
@ -70,9 +65,16 @@ void TopLayout::addActiveLayout(ActiveLayout *layout)
void TopLayout::removeActiveLayout(ActiveLayout *layout)
{
if (m_activeLayouts.contains(layout)) {
qDebug() << "TOPLAYOUT <" << name() << "> : Removing active layout, " << layout->name();
m_activeLayouts.removeAll(layout);
disconnect(layout, &GenericLayout::activitiesChanged, this, &GenericLayout::activitiesChanged);
emit activitiesChanged();
emit viewsCountChanged();
//! viewsCount signal is not needed to be trigerred here because
//! in such case the views number has not been changed for the rest
//! active layouts
}
}

View File

@ -72,21 +72,7 @@ LayoutManager::~LayoutManager()
m_importer->deleteLater();
m_launchersSignals->deleteLater();
while (!m_activeLayouts.isEmpty()) {
ActiveLayout *layout = m_activeLayouts.at(0);
m_activeLayouts.removeFirst();
layout->unloadContainments();
layout->unloadLatteViews();
layout->deleteLater();
}
while (!m_topLayouts.isEmpty()) {
TopLayout *layout = m_topLayouts.at(0);
m_topLayouts.removeFirst();
layout->unloadContainments();
layout->unloadLatteViews();
layout->deleteLater();
}
unload();
m_activitiesController->deleteLater();
}
@ -115,7 +101,7 @@ void LayoutManager::load()
}
//! Check if the multiple-layouts hidden file is present, add it if it isnt
if (!QFile(QDir::homePath() + "/.config/latte/" + ActiveLayout::MultipleLayoutsName + ".layout.latte").exists()) {
if (!QFile(QDir::homePath() + "/.config/latte/" + Layout::AbstractLayout::MultipleLayoutsName + ".layout.latte").exists()) {
importPreset(MultipleLayoutsPresetId, false);
}
@ -125,7 +111,7 @@ void LayoutManager::load()
this, &LayoutManager::currentActivityChanged);
connect(m_corona->m_activityConsumer, &KActivities::Consumer::runningActivitiesChanged,
this, [&]() {
this, [&]() {
if (memoryUsage() == Types::MultipleLayouts) {
syncMultipleLayoutsToActivities();
}
@ -136,33 +122,44 @@ void LayoutManager::load()
void LayoutManager::unload()
{
//! Unload all active Layouts
for (const auto layout : m_activeLayouts) {
if (memoryUsage() == Types::MultipleLayouts && layout->isOriginalLayout()) {
bool multipleMode{activeLayout(Layout::AbstractLayout::MultipleLayoutsName)};
//! Unload all ActiveLayouts
while (!m_activeLayouts.isEmpty()) {
ActiveLayout *layout = m_activeLayouts.at(0);
m_activeLayouts.removeFirst();
if (layout->isOriginalLayout() && multipleMode) {
layout->syncToLayoutFile(true);
}
layout->unloadContainments();
layout->unloadLatteViews();
if (memoryUsage() == Types::MultipleLayouts && layout->isOriginalLayout()) {
clearUnloadedContainmentsFromLinkedFile(layout->unloadedContainmentsIds());
if (layout->isOriginalLayout() && multipleMode) {
clearUnloadedContainmentsFromLinkedFile(layout->unloadedContainmentsIds(), true);
}
layout->deleteLater();
delete layout;
}
m_activeLayouts.clear();
//! Cleanup pseudo-layout from Containments
if (memoryUsage() == Types::MultipleLayouts) {
for (const auto layout : m_topLayouts) {
//! Unload all TopLayouts
while (!m_topLayouts.isEmpty()) {
TopLayout *layout = m_topLayouts.at(0);
m_topLayouts.removeFirst();
if (multipleMode) {
layout->syncToLayoutFile(true);
layout->unloadContainments();
layout->unloadLatteViews();
clearUnloadedContainmentsFromLinkedFile(layout->unloadedContainmentsIds());
layout->deleteLater();
}
m_topLayouts.clear();
layout->unloadContainments();
layout->unloadLatteViews();
if (multipleMode) {
clearUnloadedContainmentsFromLinkedFile(layout->unloadedContainmentsIds(), true);
}
delete layout;
}
//! Remove no-needed temp files
@ -419,7 +416,7 @@ ActiveLayout *LayoutManager::currentLayout() const
}
for (auto layout : m_activeLayouts) {
if ((layout->name() != ActiveLayout::MultipleLayoutsName) && (layout->activities().isEmpty())) {
if ((layout->name() != Layout::AbstractLayout::MultipleLayoutsName) && (layout->activities().isEmpty())) {
return layout;
}
}
@ -684,7 +681,8 @@ bool LayoutManager::switchToLayout(QString layoutName, int previousMemoryUsage)
return false;
}
//! First Check If that Layout is already present
//! First Check If that Layout is already present and in that case
//! we can just switch to the proper Activity
if (memoryUsage() == Types::MultipleLayouts && previousMemoryUsage == -1) {
ActiveLayout *layout = activeLayout(layoutName);
@ -710,6 +708,10 @@ bool LayoutManager::switchToLayout(QString layoutName, int previousMemoryUsage)
emit currentLayoutIsSwitching(layout->name());
}
}
for (const auto layout : m_topLayouts) {
emit currentLayoutIsSwitching(layout->name());
}
}
QString lPath = layoutPath(layoutName);
@ -720,8 +722,8 @@ bool LayoutManager::switchToLayout(QString layoutName, int previousMemoryUsage)
if (!lPath.isEmpty()) {
if (memoryUsage() == Types::SingleLayout) {
emit currentLayoutIsSwitching(currentLayoutName());
} else if (memoryUsage() == Types::MultipleLayouts && layoutName != ActiveLayout::MultipleLayoutsName) {
// emit currentLayoutIsSwitching(currentLayoutName());
} else if (memoryUsage() == Types::MultipleLayouts && layoutName != Layout::AbstractLayout::MultipleLayoutsName) {
ActiveLayout toLayout(this, lPath);
QStringList toActivities = toLayout.activities();
@ -752,31 +754,15 @@ bool LayoutManager::switchToLayout(QString layoutName, int previousMemoryUsage)
bool initializingMultipleLayouts{false};
if (memoryUsage() == Types::MultipleLayouts && !activeLayout(ActiveLayout::MultipleLayoutsName)) {
if (memoryUsage() == Types::MultipleLayouts && !activeLayout(Layout::AbstractLayout::MultipleLayoutsName)) {
initializingMultipleLayouts = true;
}
if (memoryUsage() == Types::SingleLayout || initializingMultipleLayouts || previousMemoryUsage == Types::MultipleLayouts) {
while (!m_activeLayouts.isEmpty()) {
ActiveLayout *layout = m_activeLayouts.at(0);
m_activeLayouts.removeFirst();
if (layout->isOriginalLayout() && previousMemoryUsage == Types::MultipleLayouts) {
layout->syncToLayoutFile(true);
}
layout->unloadContainments();
layout->unloadLatteViews();
if (layout->isOriginalLayout() && previousMemoryUsage == Types::MultipleLayouts) {
clearUnloadedContainmentsFromLinkedFile(layout->unloadedContainmentsIds(), true);
}
delete layout;
}
unload();
if (initializingMultipleLayouts) {
fixedLayoutName = QString(ActiveLayout::MultipleLayoutsName);
fixedLayoutName = QString(Layout::AbstractLayout::MultipleLayoutsName);
fixedLPath = layoutPath(fixedLayoutName);
}
@ -830,7 +816,7 @@ bool LayoutManager::switchToLayout(QString layoutName, int previousMemoryUsage)
}
if ((!lastUsedActivityFound && assignedActivities.count() == 0)
|| !assignedActivities.contains(m_corona->m_activityConsumer->currentActivity())) {
|| !assignedActivities.contains(m_corona->m_activityConsumer->currentActivity())) {
//! Starting the activities must be done asynchronous because otherwise
//! the activity manager cant close multiple activities
@ -871,7 +857,7 @@ void LayoutManager::syncMultipleLayoutsToActivities(QString layoutForOrphans)
QStringList layoutsToUnload;
QStringList layoutsToLoad;
layoutsToLoad << ActiveLayout::MultipleLayoutsName;
layoutsToLoad << Layout::AbstractLayout::MultipleLayoutsName;
bool allRunningActivitiesWillBeReserved{true};
@ -906,7 +892,7 @@ void LayoutManager::syncMultipleLayoutsToActivities(QString layoutForOrphans)
//! Unload no needed Layouts
for (const auto &layoutName : layoutsToUnload) {
if (layoutName != ActiveLayout::MultipleLayoutsName) {
if (layoutName != Layout::AbstractLayout::MultipleLayoutsName) {
ActiveLayout *layout = activeLayout(layoutName);
int posLayout = activeLayoutPos(layoutName);

View File

@ -743,7 +743,7 @@ void View::setFontPixelSize(int size)
void View::applyActivitiesToWindows()
{
if (m_visibility) {
if (m_visibility && m_managedLayout) {
QStringList activities = m_managedLayout->appliedActivities();
m_windowsTracker->setWindowOnActivities(*this, activities);