You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
latte-dock/app/view/originalview.cpp

283 lines
7.2 KiB
C++

/*
SPDX-FileCopyrightText: 2021 Michail Vourlakos <mvourlakos@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "originalview.h"
#include "clonedview.h"
#include "positioner.h"
#include "../lattecorona.h"
#include "../screenpool.h"
#include "../layouts/storage.h"
// KDE
#include <KLocalizedString>
namespace Latte {
OriginalView::OriginalView(Plasma::Corona *corona, QScreen *targetScreen, bool byPassX11WM)
: View(corona, targetScreen, byPassX11WM)
{
connect(this, &View::containmentChanged, this, [&]() {
if (!this->containment()) {
return;
}
connect(containment(), &Plasma::Applet::destroyedChanged, this, &OriginalView::syncClonesToScreens);
restoreConfig();
});
connect(this, &View::layoutChanged, this, &OriginalView::syncClonesToScreens);
connect(this, &OriginalView::screensGroupChanged, this, &OriginalView::syncClonesToScreens);
connect(this, &OriginalView::screensGroupChanged, this, &OriginalView::saveConfig);
}
OriginalView::~OriginalView()
{
cleanClones();
}
bool OriginalView::isSingle() const
{
return m_screensGroup == Latte::Types::SingleScreenGroup;
}
bool OriginalView::isOriginal() const
{
return true;
}
bool OriginalView::isCloned() const
{
return !isOriginal();
}
int OriginalView::clonesCount() const
{
return m_clones.count();
}
int OriginalView::expectedScreenIdFromScreenGroup(const Latte::Types::ScreensGroup &nextScreensGroup) const
{
Data::View view = data();
view.screensGroup = nextScreensGroup;
return Latte::Layouts::Storage::self()->expectedViewScreenId(m_corona, view);
}
Latte::Types::ScreensGroup OriginalView::screensGroup() const
{
return m_screensGroup;
}
void OriginalView::setScreensGroup(const Latte::Types::ScreensGroup &group)
{
if (m_screensGroup == group) {
return;
}
m_screensGroup = group;
emit screensGroupChanged();
}
void OriginalView::addClone(Latte::ClonedView *view)
{
if (m_clones.contains(view)) {
return;
}
m_clones << view;
m_waitingCreation.removeAll(view->positioner()->currentScreenId());
}
void OriginalView::removeClone(Latte::ClonedView *view)
{
if (!m_clones.contains(view)) {
return;
}
int idx = m_clones.indexOf(view);
auto cloned = m_clones.takeAt(idx);
if (!cloned->layout()) {
return;
}
cloned->positioner()->slideOutDuringExit();
cloned->layout()->removeView(cloned->data());
}
void OriginalView::createClone(int screenId)
{
if (!layout() || !containment()) {
return;
}
QString templateFile = layout()->storedView(containment()->id());
if (templateFile.isEmpty()) {
return;
}
Data::ViewsTable templateviews = Layouts::Storage::self()->views(templateFile);
if (templateviews.rowCount() <= 0) {
return;
}
Data::View nextdata = templateviews[0];
nextdata.name = i18nc("clone of original dock panel, name","Clone of %1", name());
nextdata.onPrimary = false;
nextdata.screensGroup = Latte::Types::SingleScreenGroup;
nextdata.isClonedFrom = containment()->id();
nextdata.screen = screenId;
nextdata.setState(Data::View::OriginFromViewTemplate, templateFile);
if (!m_waitingCreation.contains(screenId)) {
m_waitingCreation << screenId;
layout()->newView(nextdata);
}
}
void OriginalView::cleanClones()
{
if (m_clones.count()==0) {
return;
}
while(!m_clones.isEmpty()) {
removeClone(m_clones[0]);
}
}
void OriginalView::reconsiderScreen()
{
View::reconsiderScreen();
syncClonesToScreens();
}
void OriginalView::setNextLocationForClones(const QString layoutName, int edge, int alignment)
{
if (m_clones.count()==0) {
return;
}
for (const auto clone : m_clones) {
clone->positioner()->setNextLocation(layoutName, Latte::Types::SingleScreenGroup, "", edge, alignment);
}
}
void OriginalView::addApplet(const QString &pluginId, const int &excludecloneid)
{
if (m_clones.count() == 0) {
return;
}
// add applet in original view
extendedInterface()->addApplet(pluginId);
// add applet in clones and exclude the one that probably produced this triggering
for(const auto clone: m_clones) {
if (clone->containment()->id() == excludecloneid) {
// this way we make sure that an applet will not be double added
continue;
}
clone->extendedInterface()->addApplet(pluginId);
}
}
void OriginalView::addApplet(QObject *mimedata, const int &x, const int &y, const int &excludecloneid)
{
if (m_clones.count() == 0) {
return;
}
// add applet in original view
extendedInterface()->addApplet(mimedata, x, y);
// add applet in clones and exclude the one that probably produced this triggering
for(const auto clone: m_clones) {
if (clone->containment()->id() == excludecloneid) {
// this way we make sure that an applet will not be double added
continue;
}
clone->extendedInterface()->addApplet(mimedata, x, y);
}
}
void OriginalView::syncClonesToScreens()
{
if (isSingle() || (containment() && containment()->destroyed())) {
cleanClones();
return;
}
QList<int> secondaryscreens = m_corona->screenPool()->secondaryScreenIds();
for (const auto scrid : secondaryscreens) {
if (m_waitingCreation.contains(scrid)) {
secondaryscreens.removeAll(scrid);
}
}
if (m_screensGroup == Latte::Types::AllSecondaryScreensGroup) {
//! occuped screen from original view in "allsecondaryscreensgroup" must be ignored
secondaryscreens.removeAll(expectedScreenIdFromScreenGroup(m_screensGroup));
}
QList<Latte::ClonedView *> removable;
for (const auto clone : m_clones) {
if (secondaryscreens.contains(clone->positioner()->currentScreenId())) {
// do nothing valid clone
secondaryscreens.removeAll(clone->positioner()->currentScreenId());
} else {
// must be removed the screen is not active
removable << clone;
}
}
for (const auto scrid : secondaryscreens) {
if (removable.count() > 0) {
//! move deprecated and available clone to valid secondary screen
auto clone = removable.takeFirst();
clone->positioner()->setScreenToFollow(m_corona->screenPool()->screenForId(scrid));
} else {
//! create a new clone
createClone(scrid);
}
}
for (auto removableclone : removable) {
//! remove deprecated clones
removeClone(removableclone);
}
}
void OriginalView::saveConfig()
{
if (!this->containment()) {
return;
}
auto config = this->containment()->config();
config.writeEntry("screensGroup", (int)m_screensGroup);
}
void OriginalView::restoreConfig()
{
if (!this->containment()) {
return;
}
auto config = this->containment()->config();
m_screensGroup = static_cast<Latte::Types::ScreensGroup>(config.readEntry("screensGroup", (int)Latte::Types::SingleScreenGroup));
//! Send changed signals at the end in order to be sure that saveConfig
//! wont rewrite default/invalid values
emit screensGroupChanged();
}
}