add TopLayout and use combined with ActiveLayout

pull/5/head
Michail Vourlakos 6 years ago
parent 1ec19d6627
commit 9236f18c4e

@ -4,5 +4,6 @@ set(lattedock-app_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/activelayout.cpp
${CMAKE_CURRENT_SOURCE_DIR}/genericlayout.cpp
${CMAKE_CURRENT_SOURCE_DIR}/storage.cpp
${CMAKE_CURRENT_SOURCE_DIR}/toplayout.cpp
PARENT_SCOPE
)

@ -57,7 +57,6 @@ public:
QString lastUsedActivity();
void clearLastUsedActivity(); //!e.g. when we export a layout
void updateLastUsedActivity();
QString name() const;
QString file() const;

@ -21,6 +21,7 @@
#include "activelayout.h"
// local
#include "toplayout.h"
#include "../lattecorona.h"
#include "../layoutmanager.h"
#include "../settings/universalsettings.h"
@ -56,6 +57,7 @@ void ActiveLayout::init()
connect(this, &ActiveLayout::activitiesChanged, this, &ActiveLayout::saveConfig);
connect(this, &ActiveLayout::disableBordersForMaximizedWindowsChanged, this, &ActiveLayout::saveConfig);
connect(this, &ActiveLayout::showInMenuChanged, this, &ActiveLayout::saveConfig);
connect(this, &ActiveLayout::topLayoutNameChanged, this, &ActiveLayout::saveConfig);
}
void ActiveLayout::initToCorona(Latte::Corona *corona)
@ -81,13 +83,12 @@ void ActiveLayout::initToCorona(Latte::Corona *corona)
});
}
if (m_layoutName != MultipleLayoutsName) {
updateLastUsedActivity();
//! Request the TopLayout in case there is one and Latte is functioning in MultipleLayouts mode
if (m_corona->layoutManager()->memoryUsage() == Types::MultipleLayouts && !m_topLayoutName.isEmpty()) {
if (m_corona->layoutManager()->assignActiveToTopLayout(this, m_topLayoutName)) {
setTopLayout(m_corona->layoutManager()->topLayout(m_topLayoutName));
}
}
connect(m_corona->activityConsumer(), &KActivities::Consumer::currentActivityChanged,
this, &ActiveLayout::updateLastUsedActivity);
}
}
@ -173,27 +174,32 @@ void ActiveLayout::setActivities(QStringList activities)
emit activitiesChanged();
}
void ActiveLayout::updateLastUsedActivity()
QString ActiveLayout::topLayoutName() const
{
if (!m_corona) {
return;
}
return m_topLayoutName;
}
if (!m_lastUsedActivity.isEmpty() && !m_corona->layoutManager()->activities().contains(m_lastUsedActivity)) {
clearLastUsedActivity();
void ActiveLayout::setTopLayoutName(QString name)
{
if (m_topLayoutName == name) {
return;
}
QString currentId = m_corona->activitiesConsumer()->currentActivity();
m_topLayoutName = name;
emit topLayoutNameChanged();
}
QStringList appliedActivitiesIds = appliedActivities();
void ActiveLayout::setTopLayout(TopLayout *layout)
{
if (m_topLayout != layout) {
return;
}
disconnect(m_topLayout, &GenericLayout::viewsCountChanged, this, &GenericLayout::viewsCountChanged);
if (m_lastUsedActivity != currentId
&& (appliedActivitiesIds.contains(currentId)
|| m_corona->layoutManager()->memoryUsage() == Types::SingleLayout)) {
m_lastUsedActivity = currentId;
m_topLayout = layout;
emit lastUsedActivityChanged();
}
connect(m_topLayout, &GenericLayout::viewsCountChanged, this, &GenericLayout::viewsCountChanged);
emit viewsCountChanged();
}
bool ActiveLayout::isActiveLayout() const
@ -220,6 +226,7 @@ void ActiveLayout::loadConfig()
{
m_disableBordersForMaximizedWindows = m_layoutGroup.readEntry("disableBordersForMaximizedWindows", false);
m_showInMenu = m_layoutGroup.readEntry("showInMenu", false);
m_topLayoutName = m_layoutGroup.readEntry("topLayoutName", QString());
m_activities = m_layoutGroup.readEntry("activities", QStringList());
emit activitiesChanged();
@ -230,6 +237,7 @@ void ActiveLayout::saveConfig()
qDebug() << "active layout is saving... for layout:" << m_layoutName;
m_layoutGroup.writeEntry("showInMenu", m_showInMenu);
m_layoutGroup.writeEntry("disableBordersForMaximizedWindows", m_disableBordersForMaximizedWindows);
m_layoutGroup.writeEntry("topLayoutName", m_topLayoutName);
m_layoutGroup.writeEntry("activities", m_activities);
m_layoutGroup.sync();

@ -29,6 +29,7 @@
namespace Latte {
class Corona;
class TopLayout;
}
namespace Latte {
@ -57,6 +58,9 @@ public:
//!it is original layout compared to pseudo-layouts that are combinations of multiple-original layouts
bool isOriginalLayout() const;
QString topLayoutName() const;
void setTopLayoutName(QString name);
QStringList activities() const;
void setActivities(QStringList activities);
@ -66,15 +70,17 @@ signals:
void activitiesChanged();
void disableBordersForMaximizedWindowsChanged();
void showInMenuChanged();
void topLayoutNameChanged();
private slots:
void loadConfig();
void saveConfig();
void setTopLayout(TopLayout *layout);
private:
void init();
void importLocalLayout(QString file);
void updateLastUsedActivity();
bool kwin_disabledMaximizedBorders() const;
void kwin_setDisabledMaximizedBorders(bool disable);
@ -82,7 +88,10 @@ private:
private:
bool m_disableBordersForMaximizedWindows{false};
bool m_showInMenu{false};
QString m_topLayoutName;
QStringList m_activities;
QPointer<TopLayout> m_topLayout;
};
}

@ -757,6 +757,15 @@ bool GenericLayout::initToCorona(Latte::Corona *corona)
qDebug() << "Layout ::::: " << name() << " added containments ::: " << m_containments.size();
//! last used activity
if (m_layoutName != MultipleLayoutsName) {
updateLastUsedActivity();
}
//! signals
connect(m_corona->activityConsumer(), &KActivities::Consumer::currentActivityChanged,
this, &GenericLayout::updateLastUsedActivity);
connect(m_corona, &Plasma::Corona::containmentAdded, this, &GenericLayout::addContainment);
//!connect signals after adding the containment
@ -768,6 +777,29 @@ bool GenericLayout::initToCorona(Latte::Corona *corona)
return true;
}
void GenericLayout::updateLastUsedActivity()
{
if (!m_corona) {
return;
}
if (!m_lastUsedActivity.isEmpty() && !m_corona->layoutManager()->activities().contains(m_lastUsedActivity)) {
clearLastUsedActivity();
}
QString currentId = m_corona->activitiesConsumer()->currentActivity();
QStringList appliedActivitiesIds = appliedActivities();
if (m_lastUsedActivity != currentId
&& (appliedActivitiesIds.contains(currentId)
|| m_corona->layoutManager()->memoryUsage() == Types::SingleLayout)) {
m_lastUsedActivity = currentId;
emit lastUsedActivityChanged();
}
}
void GenericLayout::assignToLayout(Latte::View *latteView, QList<Plasma::Containment *> containments)
{
if (!m_corona) {

@ -78,6 +78,8 @@ public:
int viewsCount(QScreen *screen) const;
int viewsCount() const;
Latte::Corona *corona();
QStringList unloadedContainmentsIds();
Types::ViewType latteViewType(int containmentId) const;
@ -141,8 +143,6 @@ private slots:
void destroyedChanged(bool destroyed);
void containmentDestroyed(QObject *cont);
Latte::Corona *corona();
protected:
Latte::Corona *m_corona{nullptr};
@ -152,6 +152,8 @@ protected:
QHash<const Plasma::Containment *, Latte::View *> m_waitingLatteViews;
private:
void updateLastUsedActivity();
//! It can be used in order for LatteViews to not be created automatically when
//! their corresponding containments are created e.g. copyView functionality
bool blockAutomaticLatteViewCreation() const;

@ -0,0 +1,80 @@
/*
* Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com>
*
* This file is part of Latte-Dock
*
* Latte-Dock is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* Latte-Dock is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "toplayout.h"
// local
#include "activelayout.h"
namespace Latte {
TopLayout::TopLayout(ActiveLayout *assigned, QObject *parent, QString layoutFile, QString layoutName)
: Layout::GenericLayout (parent, layoutFile, layoutName)
{
initToCorona(assigned->corona());
addActiveLayout(assigned);
}
TopLayout::~TopLayout()
{
}
const QStringList TopLayout::appliedActivities()
{
if (!m_corona) {
return {};
}
QStringList activities;
for (const auto &layout : m_activeLayouts) {
activities << layout->appliedActivities();
}
return activities;
}
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 viewsCountChanged();
}
}
void TopLayout::removeActiveLayout(ActiveLayout *layout)
{
if (m_activeLayouts.contains(layout)) {
m_activeLayouts.removeAll(layout);
emit activitiesChanged();
emit viewsCountChanged();
}
}
}

@ -0,0 +1,62 @@
/*
* Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com>
*
* This file is part of Latte-Dock
*
* Latte-Dock is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* Latte-Dock is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TOPLAYOUT_H
#define TOPLAYOUT_H
// local
#include "genericlayout.h"
// Qt
#include <QObject>
namespace Latte {
class ActiveLayout;
}
namespace Latte {
//! TopLayout is a layout that exists only as long as it belongs to one or
//! more ActiveLayout(s). It is a layer above an active or more layouts and can
//! be used from ActiveLayouts to share Latte:View(s) . Much of its functionality
//! is provided by the ActiveLayouts it belongs to. For example the activities
//! that its views should be shown is identified only from the active layouts
//! it belongs to
class TopLayout : public Layout::GenericLayout
{
public:
TopLayout(ActiveLayout *assigned, QObject *parent, QString layoutFile, QString layoutName = QString());
~TopLayout() override;
const QStringList appliedActivities();
public slots:
void addActiveLayout(ActiveLayout *layout);
void removeActiveLayout(ActiveLayout *layout);
private:
QList<ActiveLayout *> m_activeLayouts;
};
}
#endif

@ -25,7 +25,9 @@
#include "infoview.h"
#include "launcherssignals.h"
#include "screenpool.h"
#include "layout/abstractlayout.h"
#include "layout/activelayout.h"
#include "layout/toplayout.h"
#include "settings/settingsdialog.h"
#include "settings/universalsettings.h"
#include "view/view.h"
@ -78,6 +80,14 @@ LayoutManager::~LayoutManager()
layout->deleteLater();
}
while (!m_topLayouts.isEmpty()) {
TopLayout *layout = m_topLayouts.at(0);
m_topLayouts.removeFirst();
layout->unloadContainments();
layout->unloadLatteViews();
layout->deleteLater();
}
m_activitiesController->deleteLater();
}
@ -126,7 +136,7 @@ void LayoutManager::load()
void LayoutManager::unload()
{
//! Unload all Layouts
//! Unload all active Layouts
for (const auto layout : m_activeLayouts) {
if (memoryUsage() == Types::MultipleLayouts && layout->isOriginalLayout()) {
layout->syncToLayoutFile(true);
@ -141,14 +151,19 @@ void LayoutManager::unload()
layout->deleteLater();
}
m_activeLayouts.clear();
//! Cleanup pseudo-layout from Containments
if (memoryUsage() == Types::MultipleLayouts) {
// auto containmentsEntries = m_corona->config()->group("Containments");
// containmentsEntries.deleteGroup();
// containmentsEntries.sync();
for (const auto layout : m_topLayouts) {
layout->syncToLayoutFile(true);
layout->unloadContainments();
layout->unloadLatteViews();
clearUnloadedContainmentsFromLinkedFile(layout->unloadedContainmentsIds());
layout->deleteLater();
}
m_topLayouts.clear();
}
//! Remove no-needed temp files
QString temp1File = QDir::homePath() + "/.config/lattedock.copy1.bak";
@ -356,6 +371,42 @@ int LayoutManager::activeLayoutPos(QString id) const
return -1;
}
TopLayout *LayoutManager::topLayout(QString id) const
{
for (int i = 0; i < m_topLayouts.size(); ++i) {
TopLayout *layout = m_topLayouts.at(i);
if (layout->name() == id) {
return layout;
}
}
return nullptr;
}
bool LayoutManager::assignActiveToTopLayout(ActiveLayout *active, QString id)
{
if (memoryUsage() == Types::SingleLayout) {
return false;
}
for (int i = 0; i < m_topLayouts.size(); ++i) {
TopLayout *layout = m_topLayouts.at(i);
if (layout->name() == id) {
layout->addActiveLayout(active);
return true;
}
}
//! If TopLayout was not found, we must create it
TopLayout *top = new TopLayout(active, this, Importer::layoutFilePath(id));
m_topLayouts.append(top);
top->importToCorona();
return true;
}
ActiveLayout *LayoutManager::currentLayout() const
{
if (memoryUsage() == Types::SingleLayout) {

@ -47,6 +47,7 @@ class Corona;
class Importer;
class ActiveLayout;
class LaunchersSignals;
class TopLayout;
class View;
}
@ -99,10 +100,10 @@ public:
//! layout cant be found
ActiveLayout *activeLayout(QString id) const;
int activeLayoutPos(QString id) const;
TopLayout *topLayout(QString id) const;
//! returns the current and active layout based on activities and user preferences
ActiveLayout *currentLayout() const;
LaunchersSignals *launchersSignals();
QStringList activities();
@ -112,6 +113,8 @@ public:
void importDefaultLayout(bool newInstanceIfPresent = false);
void importPresets(bool includeDefault = false);
bool assignActiveToTopLayout(ActiveLayout *active, QString id);
public slots:
void showAboutDialog();
@ -188,6 +191,7 @@ private:
LaunchersSignals *m_launchersSignals{nullptr};
QList<ActiveLayout *> m_activeLayouts;
QList<TopLayout *> m_topLayouts;
KActivities::Controller *m_activitiesController;

Loading…
Cancel
Save