mirror of
https://github.com/KDE/latte-dock.git
synced 2025-08-12 05:49:24 +03:00
many improvements for MultipleLayouts case
This commit is contained in:
@ -88,8 +88,6 @@ DockCorona::DockCorona(bool defaultLayoutOnStartup, QString layoutNameOnStartUp,
|
||||
qmlRegisterTypes();
|
||||
QFontDatabase::addApplicationFont(kPackage().filePath("tangerineFont"));
|
||||
|
||||
//connect(this, &Corona::containmentAdded, this, &DockCorona::addDock);
|
||||
|
||||
if (m_activityConsumer && (m_activityConsumer->serviceStatus() == KActivities::Consumer::Running)) {
|
||||
load();
|
||||
}
|
||||
@ -279,6 +277,11 @@ bool DockCorona::appletExists(uint containmentId, uint appletId) const
|
||||
return false;
|
||||
}
|
||||
|
||||
KActivities::Consumer *DockCorona::activitiesConsumer() const
|
||||
{
|
||||
return m_activityConsumer;
|
||||
}
|
||||
|
||||
ScreenPool *DockCorona::screenPool() const
|
||||
{
|
||||
return m_screenPool;
|
||||
@ -855,6 +858,10 @@ void DockCorona::loadDefaultLayout()
|
||||
defaultContainment->setLocation(Plasma::Types::BottomEdge);
|
||||
}
|
||||
|
||||
if (m_layoutManager->memoryUsage() == Dock::MultipleLayouts) {
|
||||
config.writeEntry("layoutId", m_layoutManager->currentLayoutName());
|
||||
}
|
||||
|
||||
defaultContainment->updateConstraints(Plasma::Types::StartupCompletedConstraint);
|
||||
|
||||
defaultContainment->save(config);
|
||||
@ -864,7 +871,7 @@ void DockCorona::loadDefaultLayout()
|
||||
emit containmentAdded(defaultContainment);
|
||||
emit containmentCreated(defaultContainment);
|
||||
|
||||
m_layoutManager->addDock(defaultContainment);
|
||||
//m_layoutManager->addDock(defaultContainment);
|
||||
defaultContainment->createApplet(QStringLiteral("org.kde.latte.plasmoid"));
|
||||
defaultContainment->createApplet(QStringLiteral("org.kde.plasma.analogclock"));
|
||||
}
|
||||
|
@ -92,6 +92,7 @@ public:
|
||||
void aboutApplication();
|
||||
void closeApplication();
|
||||
|
||||
KActivities::Consumer *activitiesConsumer() const;
|
||||
ScreenPool *screenPool() const;
|
||||
UniversalSettings *universalSettings() const;
|
||||
LayoutManager *layoutManager() const;
|
||||
|
@ -1290,6 +1290,7 @@ void DockView::setManagedLayout(Layout *layout)
|
||||
|
||||
m_managedLayout = layout;
|
||||
|
||||
qDebug() << "DOCK VIEW FROM LAYOUT ::: " << layout->name() << " - activities: " << layout->appliedActivities();
|
||||
m_visibility->setDockOnActivities(layout->appliedActivities());
|
||||
|
||||
emit managedLayoutChanged();
|
||||
|
@ -318,9 +318,9 @@ private:
|
||||
QMenu *m_contextMenu;
|
||||
QMetaMethod m_appletContainsMethod;
|
||||
QQuickItem *m_appletContainsMethodItem{nullptr};
|
||||
Layout *m_managedLayout{nullptr};
|
||||
QPointer<PlasmaQuick::ConfigView> m_configView;
|
||||
QPointer<VisibilityManager> m_visibility;
|
||||
QPointer<Layout> m_managedLayout;
|
||||
QPointer<QScreen> m_screenToFollow;
|
||||
|
||||
QString m_screenToFollowId;
|
||||
|
@ -346,7 +346,7 @@ void Layout::saveConfig()
|
||||
|
||||
void Layout::addContainment(Plasma::Containment *containment)
|
||||
{
|
||||
if (m_containments.contains(containment)) {
|
||||
if (!containment || m_containments.contains(containment)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -365,6 +365,7 @@ void Layout::addContainment(Plasma::Containment *containment)
|
||||
}
|
||||
|
||||
if (containmentInLayout) {
|
||||
addDock(containment);
|
||||
connect(containment, &QObject::destroyed, this, &Layout::containmentDestroyed);
|
||||
}
|
||||
}
|
||||
@ -449,6 +450,8 @@ void Layout::containmentDestroyed(QObject *cont)
|
||||
|
||||
void Layout::addDock(Plasma::Containment *containment, bool forceLoading, int expDockScreen)
|
||||
{
|
||||
qDebug() << "Layout :::: " << m_layoutName << " ::: addDock was called... m_containments :: " << m_containments.size();
|
||||
|
||||
if (!containment || !m_corona || !containment->kPackage().isValid()) {
|
||||
qWarning() << "the requested containment plugin can not be located or loaded";
|
||||
return;
|
||||
@ -456,14 +459,20 @@ void Layout::addDock(Plasma::Containment *containment, bool forceLoading, int ex
|
||||
|
||||
auto metadata = containment->kPackage().metadata();
|
||||
|
||||
qDebug() << "step 1...";
|
||||
|
||||
if (metadata.pluginId() != "org.kde.latte.containment")
|
||||
return;
|
||||
|
||||
qDebug() << "step 2...";
|
||||
|
||||
for (auto *dock : m_dockViews) {
|
||||
if (dock->containment() == containment)
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "step 3...";
|
||||
|
||||
QScreen *nextScreen{qGuiApp->primaryScreen()};
|
||||
|
||||
bool onPrimary = containment->config().readEntry("onPrimary", true);
|
||||
@ -493,11 +502,12 @@ void Layout::addDock(Plasma::Containment *containment, bool forceLoading, int ex
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
qDebug() << "adding dock rejected, screen not available : " << connector;
|
||||
qDebug() << "adding dock rejected, screen not available ! : " << connector;
|
||||
return;
|
||||
}
|
||||
} else if (onPrimary) {
|
||||
if (m_corona->explicitDockOccupyEdge(m_corona->screenPool()->primaryScreenId(), containment->location())) {
|
||||
qDebug() << "CORONA ::: adding dock rejected, the edge is occupied by explicit dock ! : " << containment->location();
|
||||
//we must check that an onPrimary dock should never catch up the same edge on
|
||||
//the same screen with an explicit dock
|
||||
return;
|
||||
@ -536,6 +546,10 @@ void Layout::addDock(Plasma::Containment *containment, bool forceLoading, int ex
|
||||
connect(containment, &Plasma::Containment::appletAlternativesRequested
|
||||
, m_corona, &DockCorona::showAlternativesForApplet, Qt::QueuedConnection);
|
||||
|
||||
if (m_corona->layoutManager()->memoryUsage() == Dock::MultipleLayouts) {
|
||||
connect(containment, &Plasma::Containment::appletCreated, this, &Layout::appletCreated);
|
||||
}
|
||||
|
||||
//! Qt 5.9 creates a crash for this in wayland, that is why the check is used
|
||||
//! but on the other hand we need this for copy to work correctly and show
|
||||
//! the copied dock under X11
|
||||
@ -695,6 +709,62 @@ void Layout::copyDock(Plasma::Containment *containment)
|
||||
}
|
||||
}
|
||||
|
||||
void Layout::appletCreated(Plasma::Applet *applet)
|
||||
{
|
||||
//! In Multiple Layout the orphaned systrays must be assigned to layouts
|
||||
//! when the user adds them
|
||||
KConfigGroup appletSettings = applet->containment()->config().group("Applets").group(QString::number(applet->id())).group("Configuration");
|
||||
|
||||
QString systrayId = appletSettings.readEntry("SystrayContainmentId", "-1");
|
||||
|
||||
if (systrayId != "-1") {
|
||||
uint sId = systrayId.toUInt();
|
||||
|
||||
foreach (auto containment, m_corona->containments()) {
|
||||
if (containment->id() == sId) {
|
||||
containment->config().writeEntry("layoutId", m_layoutName);
|
||||
}
|
||||
|
||||
addContainment(containment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Layout::importToCorona()
|
||||
{
|
||||
if (!m_corona) {
|
||||
return;
|
||||
}
|
||||
|
||||
//! Settting mutable for create a containment
|
||||
m_corona->setImmutability(Plasma::Types::Mutable);
|
||||
|
||||
QString temp1File = QDir::homePath() + "/.config/lattedock.copy1.bak";
|
||||
|
||||
//! WE NEED A WAY TO COPY A CONTAINMENT!!!!
|
||||
QFile copyFile(temp1File);
|
||||
|
||||
if (copyFile.exists())
|
||||
copyFile.remove();
|
||||
|
||||
// QFile(m_layoutFile).copy(temp1File);
|
||||
|
||||
KSharedConfigPtr newFile = KSharedConfig::openConfig(temp1File);
|
||||
KConfigGroup copyGroup = KConfigGroup(newFile, "Containments");
|
||||
KConfigGroup current_containments = KConfigGroup(m_filePtr, "Containments");
|
||||
|
||||
current_containments.copyTo(©Group);
|
||||
|
||||
copyGroup.sync();
|
||||
|
||||
//! update ids to unique ones
|
||||
QString temp2File = newUniqueIdsLayoutFromFile(temp1File);
|
||||
|
||||
|
||||
//! Finally import the configuration
|
||||
importLayoutFile(temp2File);
|
||||
}
|
||||
|
||||
QString Layout::availableId(QStringList all, QStringList assigned, int base)
|
||||
{
|
||||
bool found = false;
|
||||
|
@ -81,6 +81,7 @@ public:
|
||||
void copyDock(Plasma::Containment *containment);
|
||||
void recreateDock(Plasma::Containment *containment);
|
||||
void syncDockViewsToScreens();
|
||||
void importToCorona();
|
||||
const QStringList appliedActivities();
|
||||
|
||||
QHash<const Plasma::Containment *, DockView *> *dockViews();
|
||||
@ -99,6 +100,7 @@ private slots:
|
||||
void saveConfig();
|
||||
|
||||
void addContainment(Plasma::Containment *containment);
|
||||
void appletCreated(Plasma::Applet *applet);
|
||||
void destroyedChanged(bool destroyed);
|
||||
void containmentDestroyed(QObject *cont);
|
||||
|
||||
|
@ -55,6 +55,8 @@ LayoutManager::LayoutManager(QObject *parent)
|
||||
m_dynamicSwitchTimer.setSingleShot(true);
|
||||
showInfoWindowChanged();
|
||||
connect(&m_dynamicSwitchTimer, &QTimer::timeout, this, &LayoutManager::confirmDynamicSwitch);
|
||||
|
||||
m_currentActivityId = m_corona->m_activityConsumer->currentActivity();
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,6 +117,24 @@ void LayoutManager::unload()
|
||||
layout->unloadDockViews();
|
||||
layout->deleteLater();
|
||||
}
|
||||
|
||||
if (memoryUsage() == Dock::MultipleLayouts) {
|
||||
auto containmentsEntries = m_corona->config()->group("Containments");
|
||||
containmentsEntries.deleteGroup();
|
||||
containmentsEntries.sync();
|
||||
}
|
||||
|
||||
QString temp1File = QDir::homePath() + "/.config/lattedock.copy1.bak";
|
||||
QString temp2File = QDir::homePath() + "/.config/lattedock.copy2.bak";
|
||||
|
||||
QFile file1(temp1File);
|
||||
QFile file2(temp2File);
|
||||
|
||||
if (file1.exists())
|
||||
file1.remove();
|
||||
|
||||
if (file2.exists())
|
||||
file2.remove();
|
||||
}
|
||||
|
||||
DockCorona *LayoutManager::corona()
|
||||
@ -139,8 +159,20 @@ LaunchersSignals *LayoutManager::launchersSignals()
|
||||
|
||||
QString LayoutManager::currentLayoutName() const
|
||||
{
|
||||
if (m_corona && m_corona->universalSettings()) {
|
||||
if (memoryUsage() == Dock::SingleLayout) {
|
||||
return m_corona->universalSettings()->currentLayoutName();
|
||||
} else if (memoryUsage() == Dock::MultipleLayouts) {
|
||||
foreach (auto layout, m_activeLayouts) {
|
||||
if (layout->activities().contains(m_currentActivityId)) {
|
||||
return layout->name();
|
||||
}
|
||||
}
|
||||
|
||||
foreach (auto layout, m_activeLayouts) {
|
||||
if ((layout->name() != Layout::MultipleLayoutsName) && (layout->activities().isEmpty())) {
|
||||
return layout->name();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QString();
|
||||
@ -282,7 +314,21 @@ void LayoutManager::syncDockViewsToScreens()
|
||||
|
||||
QHash<const Plasma::Containment *, DockView *> *LayoutManager::currentDockViews() const
|
||||
{
|
||||
return m_activeLayouts.at(0)->dockViews();
|
||||
if (memoryUsage() == Dock::SingleLayout) {
|
||||
return m_activeLayouts.at(0)->dockViews();
|
||||
} else {
|
||||
foreach (auto layout, m_activeLayouts) {
|
||||
if (layout->activities().contains(m_currentActivityId)) {
|
||||
return layout->dockViews();
|
||||
}
|
||||
}
|
||||
|
||||
foreach (auto layout, m_activeLayouts) {
|
||||
if ((layout->name() != Layout::MultipleLayoutsName) && (layout->activities().isEmpty())) {
|
||||
return layout->dockViews();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Layout *LayoutManager::activeLayout(QString id) const
|
||||
@ -300,11 +346,15 @@ Layout *LayoutManager::activeLayout(QString id) const
|
||||
|
||||
void LayoutManager::currentActivityChanged(const QString &id)
|
||||
{
|
||||
qDebug() << "activity changed :: " << id;
|
||||
m_currentActivityId = id;
|
||||
|
||||
m_shouldSwitchToLayout = shouldSwitchToLayout(id);
|
||||
if (memoryUsage() == Dock::SingleLayout) {
|
||||
qDebug() << "activity changed :: " << id;
|
||||
|
||||
m_dynamicSwitchTimer.start();
|
||||
m_shouldSwitchToLayout = shouldSwitchToLayout(id);
|
||||
|
||||
m_dynamicSwitchTimer.start();
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutManager::showInfoWindowChanged()
|
||||
@ -433,7 +483,7 @@ void LayoutManager::loadLatteLayout(QString layoutPath)
|
||||
|
||||
void LayoutManager::importLatteLayout(QString layoutPath)
|
||||
{
|
||||
|
||||
//! This might not be needed as it is Layout responsibility
|
||||
}
|
||||
|
||||
bool LayoutManager::switchToLayout(QString layoutName)
|
||||
@ -458,33 +508,129 @@ bool LayoutManager::switchToLayout(QString layoutName)
|
||||
//! sessions.
|
||||
QTimer::singleShot(250, [this, layoutName, lPath]() {
|
||||
qDebug() << layoutName << " - " << lPath;
|
||||
QString fixedLPath = lPath;
|
||||
QString fixedLayoutName = layoutName;
|
||||
|
||||
while (!m_activeLayouts.isEmpty()) {
|
||||
Layout *layout = m_activeLayouts.at(0);
|
||||
m_activeLayouts.removeFirst();
|
||||
layout->unloadContainments();
|
||||
layout->unloadDockViews();
|
||||
layout->deleteLater();
|
||||
bool initializingMultipleLayouts{false};
|
||||
|
||||
if (memoryUsage() == Dock::MultipleLayouts && !activeLayout(Layout::MultipleLayoutsName)) {
|
||||
initializingMultipleLayouts = true;
|
||||
}
|
||||
|
||||
Layout *newLayout = new Layout(this, lPath, layoutName);
|
||||
m_activeLayouts.append(newLayout);
|
||||
newLayout->initToCorona(m_corona);
|
||||
if (memoryUsage() == Dock::SingleLayout || initializingMultipleLayouts) {
|
||||
while (!m_activeLayouts.isEmpty()) {
|
||||
Layout *layout = m_activeLayouts.at(0);
|
||||
m_activeLayouts.removeFirst();
|
||||
layout->unloadContainments();
|
||||
layout->unloadDockViews();
|
||||
layout->deleteLater();
|
||||
}
|
||||
|
||||
if (initializingMultipleLayouts) {
|
||||
fixedLayoutName = QString(Layout::MultipleLayoutsName);
|
||||
fixedLPath = layoutPath(fixedLayoutName);
|
||||
}
|
||||
|
||||
Layout *newLayout = new Layout(this, fixedLPath, fixedLayoutName);
|
||||
m_activeLayouts.append(newLayout);
|
||||
newLayout->initToCorona(m_corona);
|
||||
|
||||
loadLatteLayout(fixedLPath);
|
||||
|
||||
emit activeLayoutsChanged();
|
||||
}
|
||||
|
||||
if (memoryUsage() == Dock::MultipleLayouts) {
|
||||
syncMultipleLayoutsToActivities(layoutName);
|
||||
}
|
||||
|
||||
loadLatteLayout(lPath);
|
||||
m_corona->universalSettings()->setCurrentLayoutName(layoutName);
|
||||
|
||||
if (!layoutIsAssigned(layoutName)) {
|
||||
m_corona->universalSettings()->setLastNonAssignedLayoutName(layoutName);
|
||||
}
|
||||
|
||||
emit activeLayoutsChanged();
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LayoutManager::syncMultipleLayoutsToActivities(QString layoutForOrphans)
|
||||
{
|
||||
QList<Layout *> layoutsToUnload;
|
||||
QStringList layoutsToLoad;
|
||||
|
||||
bool allRunningActivitiesWillBeReserved{true};
|
||||
|
||||
if (layoutForOrphans.isEmpty() || m_assignedLayouts.values().contains(layoutForOrphans)) {
|
||||
layoutForOrphans = m_corona->universalSettings()->lastNonAssignedLayoutName();
|
||||
}
|
||||
|
||||
foreach (auto activity, runningActivities()) {
|
||||
if (!m_assignedLayouts[activity].isEmpty()) {
|
||||
if (!layoutsToLoad.contains(m_assignedLayouts[activity])) {
|
||||
layoutsToLoad.append(m_assignedLayouts[activity]);
|
||||
}
|
||||
} else {
|
||||
allRunningActivitiesWillBeReserved = false;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (auto layout, m_activeLayouts) {
|
||||
Layout *tempLayout{nullptr};
|
||||
|
||||
if (!layoutsToLoad.contains(layout->name())) {
|
||||
tempLayout = layout;
|
||||
} else if (layout->activities().isEmpty() && allRunningActivitiesWillBeReserved) {
|
||||
//! in such case the layout for the orphaned must be unloaded
|
||||
tempLayout = layout;
|
||||
}
|
||||
|
||||
if (tempLayout && !layoutsToUnload.contains(tempLayout)) {
|
||||
layoutsToUnload << tempLayout;
|
||||
}
|
||||
}
|
||||
|
||||
//! Unload no needed Layouts
|
||||
foreach (auto layout, layoutsToUnload) {
|
||||
if (layout->name() != Layout::MultipleLayoutsName) {
|
||||
Layout *tempLayout = layoutsToUnload.at(0);
|
||||
layoutsToUnload.removeFirst();
|
||||
tempLayout->unloadContainments();
|
||||
tempLayout->unloadDockViews();
|
||||
tempLayout->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
//! Add Layout for orphan activities
|
||||
if (!allRunningActivitiesWillBeReserved) {
|
||||
if (!activeLayout(layoutForOrphans)) {
|
||||
Layout *newLayout = new Layout(this, layoutPath(layoutForOrphans), layoutForOrphans);
|
||||
|
||||
if (newLayout) {
|
||||
m_activeLayouts.append(newLayout);
|
||||
newLayout->initToCorona(m_corona);
|
||||
newLayout->importToCorona();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! Add needed Layouts based on Activities
|
||||
foreach (auto layoutName, layoutsToLoad) {
|
||||
if (!activeLayout(layoutName)) {
|
||||
Layout *newLayout = new Layout(this, QString(layoutPath(layoutName)), layoutName);
|
||||
|
||||
if (newLayout) {
|
||||
m_activeLayouts.append(newLayout);
|
||||
newLayout->initToCorona(m_corona);
|
||||
newLayout->importToCorona();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
emit activeLayoutsChanged();
|
||||
}
|
||||
|
||||
QString LayoutManager::newLayout(QString layoutName, QString preset)
|
||||
{
|
||||
QDir layoutDir(QDir::homePath() + "/.config/latte");
|
||||
|
@ -120,6 +120,7 @@ private slots:
|
||||
void currentActivityChanged(const QString &id);
|
||||
void showInfoWindowChanged();
|
||||
void showWidgetsExplorer();
|
||||
void syncMultipleLayoutsToActivities(QString layoutForOrphans);
|
||||
|
||||
private:
|
||||
void confirmDynamicSwitch();
|
||||
@ -154,6 +155,7 @@ private:
|
||||
bool layoutIsAssigned(QString layoutName);
|
||||
QStringList validActivities(QStringList currentList);
|
||||
|
||||
QString m_currentActivityId;
|
||||
QStringList m_layouts;
|
||||
QStringList m_menuLayouts;
|
||||
QStringList m_presetsPaths;
|
||||
|
@ -33,7 +33,7 @@ namespace Latte {
|
||||
VisibilityManagerPrivate::VisibilityManagerPrivate(PlasmaQuick::ContainmentView *view, VisibilityManager *q)
|
||||
: QObject(nullptr), q(q), view(view), wm(&WindowSystem::self())
|
||||
{
|
||||
DockView *dockView = qobject_cast<DockView *>(view);
|
||||
dockView = qobject_cast<DockView *>(view);
|
||||
dockCorona = qobject_cast<DockCorona *>(view->corona());
|
||||
|
||||
if (dockView) {
|
||||
@ -126,6 +126,27 @@ inline void VisibilityManagerPrivate::setMode(Dock::Visibility mode)
|
||||
if (!configuring && view->screen())
|
||||
wm->setDockStruts(*view, dockGeometry, view->containment()->location());
|
||||
});
|
||||
|
||||
|
||||
if (dockCorona && dockCorona->layoutManager()->memoryUsage() == Dock::MultipleLayouts) {
|
||||
if (dockView->managedLayout() && (dockView->managedLayout()->name() == dockCorona->layoutManager()->currentLayoutName())) {
|
||||
wm->setDockStruts(*view, dockGeometry, view->location());
|
||||
} else {
|
||||
wm->removeDockStruts(*view);
|
||||
}
|
||||
|
||||
connections[2] = connect(dockCorona->activitiesConsumer(), &KActivities::Consumer::currentActivityChanged, this, [&]() {
|
||||
Layout *mLayout = dockView->managedLayout();
|
||||
|
||||
if (mLayout && (mLayout->name() == dockCorona->layoutManager()->currentLayoutName())) {
|
||||
wm->setDockStruts(*view, dockGeometry, view->location());
|
||||
} else {
|
||||
wm->removeDockStruts(*view);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
raiseDock(true);
|
||||
}
|
||||
break;
|
||||
|
@ -19,6 +19,7 @@
|
||||
namespace Latte {
|
||||
|
||||
class DockCorona;
|
||||
class DockView;
|
||||
class VisibilityManager;
|
||||
|
||||
/*!
|
||||
@ -101,6 +102,7 @@ public:
|
||||
std::array<QMetaObject::Connection, 7> connectionsDynBackground;
|
||||
WindowId lastActiveWindowWid;
|
||||
DockCorona *dockCorona;
|
||||
DockView *dockView;
|
||||
};
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user