File indexing completed on 2024-12-01 11:10:42
0001 /* 0002 SPDX-FileCopyrightText: 2021 Michail Vourlakos <mvourlakos@gmail.com> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "originalview.h" 0007 #include "clonedview.h" 0008 #include "positioner.h" 0009 #include "../lattecorona.h" 0010 #include "../screenpool.h" 0011 #include "../layouts/storage.h" 0012 0013 // KDE 0014 #include <KLocalizedString> 0015 0016 namespace Latte { 0017 OriginalView::OriginalView(Plasma::Corona *corona, QScreen *targetScreen, bool byPassX11WM) 0018 : View(corona, targetScreen, byPassX11WM) 0019 { 0020 connect(this, &View::containmentChanged, this, [&]() { 0021 if (!this->containment()) { 0022 return; 0023 } 0024 0025 connect(containment(), &Plasma::Applet::destroyedChanged, this, &OriginalView::syncClonesToScreens); 0026 restoreConfig(); 0027 }); 0028 0029 connect(this, &View::layoutChanged, this, &OriginalView::syncClonesToScreens); 0030 connect(this, &OriginalView::screensGroupChanged, this, &OriginalView::syncClonesToScreens); 0031 connect(this, &OriginalView::screensGroupChanged, this, &OriginalView::saveConfig); 0032 } 0033 0034 OriginalView::~OriginalView() 0035 { 0036 cleanClones(); 0037 } 0038 0039 bool OriginalView::isSingle() const 0040 { 0041 return m_screensGroup == Latte::Types::SingleScreenGroup; 0042 } 0043 0044 bool OriginalView::isOriginal() const 0045 { 0046 return true; 0047 } 0048 0049 bool OriginalView::isCloned() const 0050 { 0051 return !isOriginal(); 0052 } 0053 0054 int OriginalView::clonesCount() const 0055 { 0056 return m_clones.count(); 0057 } 0058 0059 int OriginalView::expectedScreenIdFromScreenGroup(const Latte::Types::ScreensGroup &nextScreensGroup) const 0060 { 0061 Data::View view = data(); 0062 view.screensGroup = nextScreensGroup; 0063 return Latte::Layouts::Storage::self()->expectedViewScreenId(m_corona, view); 0064 } 0065 0066 Latte::Types::ScreensGroup OriginalView::screensGroup() const 0067 { 0068 return m_screensGroup; 0069 } 0070 0071 void OriginalView::setScreensGroup(const Latte::Types::ScreensGroup &group) 0072 { 0073 if (m_screensGroup == group) { 0074 return; 0075 } 0076 0077 m_screensGroup = group; 0078 emit screensGroupChanged(); 0079 } 0080 0081 void OriginalView::addClone(Latte::ClonedView *view) 0082 { 0083 if (m_clones.contains(view)) { 0084 return; 0085 } 0086 0087 m_clones << view; 0088 m_waitingCreation.removeAll(view->positioner()->currentScreenId()); 0089 } 0090 0091 void OriginalView::removeClone(Latte::ClonedView *view) 0092 { 0093 if (!m_clones.contains(view)) { 0094 return; 0095 } 0096 0097 int idx = m_clones.indexOf(view); 0098 auto cloned = m_clones.takeAt(idx); 0099 0100 if (!cloned->layout()) { 0101 return; 0102 } 0103 cloned->positioner()->slideOutDuringExit(); 0104 cloned->layout()->removeView(cloned->data()); 0105 } 0106 0107 void OriginalView::createClone(int screenId) 0108 { 0109 if (!layout() || !containment()) { 0110 return; 0111 } 0112 0113 QString templateFile = layout()->storedView(containment()->id()); 0114 0115 if (templateFile.isEmpty()) { 0116 return; 0117 } 0118 0119 Data::ViewsTable templateviews = Layouts::Storage::self()->views(templateFile); 0120 0121 if (templateviews.rowCount() <= 0) { 0122 return; 0123 } 0124 0125 Data::View nextdata = templateviews[0]; 0126 nextdata.name = i18nc("clone of original dock panel, name","Clone of %1", name()); 0127 nextdata.onPrimary = false; 0128 nextdata.screensGroup = Latte::Types::SingleScreenGroup; 0129 nextdata.isClonedFrom = containment()->id(); 0130 nextdata.screen = screenId; 0131 0132 nextdata.setState(Data::View::OriginFromViewTemplate, templateFile); 0133 0134 if (!m_waitingCreation.contains(screenId)) { 0135 m_waitingCreation << screenId; 0136 layout()->newView(nextdata); 0137 } 0138 } 0139 0140 void OriginalView::cleanClones() 0141 { 0142 if (m_clones.count()==0) { 0143 return; 0144 } 0145 0146 while(!m_clones.isEmpty()) { 0147 removeClone(m_clones[0]); 0148 } 0149 } 0150 0151 void OriginalView::reconsiderScreen() 0152 { 0153 View::reconsiderScreen(); 0154 syncClonesToScreens(); 0155 } 0156 0157 void OriginalView::setNextLocationForClones(const QString layoutName, int edge, int alignment) 0158 { 0159 if (m_clones.count()==0) { 0160 return; 0161 } 0162 0163 for (const auto clone : m_clones) { 0164 clone->positioner()->setNextLocation(layoutName, Latte::Types::SingleScreenGroup, "", edge, alignment); 0165 } 0166 } 0167 0168 void OriginalView::addApplet(const QString &pluginId, const int &excludecloneid) 0169 { 0170 if (m_clones.count() == 0) { 0171 return; 0172 } 0173 0174 // add applet in original view 0175 extendedInterface()->addApplet(pluginId); 0176 0177 // add applet in clones and exclude the one that probably produced this triggering 0178 for(const auto clone: m_clones) { 0179 if (clone->containment()->id() == excludecloneid) { 0180 // this way we make sure that an applet will not be double added 0181 continue; 0182 } 0183 0184 clone->extendedInterface()->addApplet(pluginId); 0185 } 0186 } 0187 0188 void OriginalView::addApplet(QObject *mimedata, const int &x, const int &y, const int &excludecloneid) 0189 { 0190 if (m_clones.count() == 0) { 0191 return; 0192 } 0193 0194 // add applet in original view 0195 extendedInterface()->addApplet(mimedata, x, y); 0196 0197 // add applet in clones and exclude the one that probably produced this triggering 0198 for(const auto clone: m_clones) { 0199 if (clone->containment()->id() == excludecloneid) { 0200 // this way we make sure that an applet will not be double added 0201 continue; 0202 } 0203 0204 clone->extendedInterface()->addApplet(mimedata, x, y); 0205 } 0206 } 0207 0208 void OriginalView::syncClonesToScreens() 0209 { 0210 if (isSingle() || (containment() && containment()->destroyed())) { 0211 cleanClones(); 0212 return; 0213 } 0214 0215 QList<int> secondaryscreens = m_corona->screenPool()->secondaryScreenIds(); 0216 0217 for (const auto scrid : secondaryscreens) { 0218 if (m_waitingCreation.contains(scrid)) { 0219 secondaryscreens.removeAll(scrid); 0220 } 0221 } 0222 0223 if (m_screensGroup == Latte::Types::AllSecondaryScreensGroup) { 0224 //! occuped screen from original view in "allsecondaryscreensgroup" must be ignored 0225 secondaryscreens.removeAll(expectedScreenIdFromScreenGroup(m_screensGroup)); 0226 } 0227 0228 QList<Latte::ClonedView *> removable; 0229 0230 for (const auto clone : m_clones) { 0231 if (secondaryscreens.contains(clone->positioner()->currentScreenId())) { 0232 // do nothing valid clone 0233 secondaryscreens.removeAll(clone->positioner()->currentScreenId()); 0234 } else { 0235 // must be removed the screen is not active 0236 removable << clone; 0237 } 0238 } 0239 0240 for (const auto scrid : secondaryscreens) { 0241 if (removable.count() > 0) { 0242 //! move deprecated and available clone to valid secondary screen 0243 auto clone = removable.takeFirst(); 0244 clone->positioner()->setScreenToFollow(m_corona->screenPool()->screenForId(scrid)); 0245 } else { 0246 //! create a new clone 0247 createClone(scrid); 0248 } 0249 } 0250 0251 for (auto removableclone : removable) { 0252 //! remove deprecated clones 0253 removeClone(removableclone); 0254 } 0255 } 0256 0257 void OriginalView::saveConfig() 0258 { 0259 0260 if (!this->containment()) { 0261 return; 0262 } 0263 0264 auto config = this->containment()->config(); 0265 config.writeEntry("screensGroup", (int)m_screensGroup); 0266 } 0267 0268 void OriginalView::restoreConfig() 0269 { 0270 if (!this->containment()) { 0271 return; 0272 } 0273 0274 auto config = this->containment()->config(); 0275 m_screensGroup = static_cast<Latte::Types::ScreensGroup>(config.readEntry("screensGroup", (int)Latte::Types::SingleScreenGroup)); 0276 0277 //! Send changed signals at the end in order to be sure that saveConfig 0278 //! wont rewrite default/invalid values 0279 emit screensGroupChanged(); 0280 } 0281 0282 }