File indexing completed on 2024-09-08 13:20:23
0001 /* 0002 * Copyright 2016 Smith AR <audoban@openmailbox.org> 0003 * Michail Vourlakos <mvourlakos@gmail.com> 0004 * 0005 * This file is part of Latte-Dock 0006 * 0007 * Latte-Dock is free software; you can redistribute it and/or 0008 * modify it under the terms of the GNU General Public License as 0009 * published by the Free Software Foundation; either version 2 of 0010 * the License, or (at your option) any later version. 0011 * 0012 * Latte-Dock is distributed in the hope that it will be useful, 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0015 * GNU General Public License for more details. 0016 * 0017 * You should have received a copy of the GNU General Public License 0018 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0019 */ 0020 0021 #include "primaryconfigview.h" 0022 0023 // local 0024 #include <config-latte.h> 0025 #include "secondaryconfigview.h" 0026 #include "../effects.h" 0027 #include "../panelshadows_p.h" 0028 #include "../view.h" 0029 #include "../../lattecorona.h" 0030 #include "../../layouts/manager.h" 0031 #include "../../layout/genericlayout.h" 0032 #include "../../settings/universalsettings.h" 0033 #include "../../shortcuts/globalshortcuts.h" 0034 #include "../../shortcuts/shortcutstracker.h" 0035 #include "../../wm/abstractwindowinterface.h" 0036 0037 // Qt 0038 #include <QQuickItem> 0039 #include <QQmlContext> 0040 #include <QQmlEngine> 0041 #include <QScreen> 0042 0043 // KDE 0044 #include <KLocalizedContext> 0045 #include <KDeclarative/KDeclarative> 0046 #include <KWayland/Client/plasmashell.h> 0047 #include <KWayland/Client/surface.h> 0048 #include <KWindowEffects> 0049 #include <KWindowSystem> 0050 0051 // Plasma 0052 #include <Plasma/Package> 0053 0054 namespace Latte { 0055 namespace ViewPart { 0056 0057 PrimaryConfigView::PrimaryConfigView(Plasma::Containment *containment, Latte::View *view, QWindow *parent) 0058 : PlasmaQuick::ConfigView(containment, parent), 0059 m_latteView(view) 0060 { 0061 m_corona = qobject_cast<Latte::Corona *>(m_latteView->containment()->corona()); 0062 0063 setupWaylandIntegration(); 0064 0065 if (KWindowSystem::isPlatformX11()) { 0066 m_corona->wm()->registerIgnoredWindow(winId()); 0067 } else { 0068 connect(m_corona->wm(), &WindowSystem::AbstractWindowInterface::latteWindowAdded, this, [&]() { 0069 if (m_waylandWindowId.isNull()) { 0070 m_waylandWindowId = m_corona->wm()->winIdFor("latte-dock", geometry()); 0071 m_corona->wm()->registerIgnoredWindow(m_waylandWindowId); 0072 } 0073 }); 0074 } 0075 0076 setScreen(m_latteView->screen()); 0077 0078 if (containment) { 0079 setIcon(qGuiApp->windowIcon()); 0080 } 0081 0082 m_screenSyncTimer.setSingleShot(true); 0083 m_screenSyncTimer.setInterval(100); 0084 0085 connect(this, &QQuickView::widthChanged, this, &PrimaryConfigView::updateEffects); 0086 connect(this, &QQuickView::heightChanged, this, &PrimaryConfigView::updateEffects); 0087 0088 connect(this, &PrimaryConfigView::availableScreenGeometryChanged, this, &PrimaryConfigView::syncGeometry); 0089 connect(this, &PrimaryConfigView::complexityChanged, this, &PrimaryConfigView::saveConfig); 0090 connect(this, &PrimaryConfigView::complexityChanged, this, &PrimaryConfigView::updateShowInlineProperties); 0091 connect(this, &PrimaryConfigView::complexityChanged, this, &PrimaryConfigView::syncGeometry); 0092 0093 connect(this, &QQuickView::statusChanged, [&](QQuickView::Status status) { 0094 if (status == QQuickView::Ready) { 0095 updateEffects(); 0096 } 0097 }); 0098 0099 connections << connect(&m_screenSyncTimer, &QTimer::timeout, this, [this]() { 0100 setScreen(m_latteView->screen()); 0101 setFlags(wFlags()); 0102 0103 if (KWindowSystem::isPlatformX11()) { 0104 #if KF5_VERSION_MINOR >= 45 0105 KWindowSystem::setState(winId(), NET::SkipTaskbar | NET::SkipPager | NET::SkipSwitcher); 0106 #else 0107 KWindowSystem::setState(winId(), NET::SkipTaskbar | NET::SkipPager); 0108 #endif 0109 0110 KWindowSystem::setOnAllDesktops(winId(), true); 0111 } 0112 0113 syncGeometry(); 0114 syncSlideEffect(); 0115 }); 0116 connections << connect(m_latteView->visibility(), &VisibilityManager::modeChanged, this, &PrimaryConfigView::syncGeometry); 0117 connections << connect(containment, &Plasma::Containment::immutabilityChanged, this, &PrimaryConfigView::immutabilityChanged); 0118 0119 m_thicknessSyncTimer.setSingleShot(true); 0120 m_thicknessSyncTimer.setInterval(200); 0121 connections << connect(&m_thicknessSyncTimer, &QTimer::timeout, this, [this]() { 0122 syncGeometry(); 0123 }); 0124 0125 connections << connect(m_latteView, &Latte::View::normalThicknessChanged, [&]() { 0126 m_thicknessSyncTimer.start(); 0127 }); 0128 0129 if (m_corona) { 0130 connections << connect(m_corona, &Latte::Corona::raiseViewsTemporaryChanged, this, &PrimaryConfigView::raiseDocksTemporaryChanged); 0131 connections << connect(m_corona, &Latte::Corona::availableScreenRectChangedFrom, this, &PrimaryConfigView::updateAvailableScreenGeometry); 0132 } 0133 0134 if (m_latteView->layout()) { 0135 emit m_latteView->layout()->setLastConfigViewFor(m_latteView); 0136 } 0137 } 0138 0139 PrimaryConfigView::~PrimaryConfigView() 0140 { 0141 qDebug() << "ConfigView deleting ..."; 0142 0143 m_corona->dialogShadows()->removeWindow(this); 0144 0145 m_corona->wm()->unregisterIgnoredWindow(KWindowSystem::isPlatformX11() ? winId() : m_waylandWindowId); 0146 0147 deleteSecondaryWindow(); 0148 0149 for (const auto &var : connections) { 0150 QObject::disconnect(var); 0151 } 0152 } 0153 0154 void PrimaryConfigView::init() 0155 { 0156 qDebug() << "dock config view : initialization started..."; 0157 m_originalByPassWM = m_latteView->byPassWM(); 0158 m_originalMode = m_latteView->visibility()->mode(); 0159 0160 loadConfig(); 0161 0162 setDefaultAlphaBuffer(true); 0163 setColor(Qt::transparent); 0164 m_corona->dialogShadows()->addWindow(this); 0165 rootContext()->setContextProperty(QStringLiteral("latteView"), m_latteView); 0166 rootContext()->setContextProperty(QStringLiteral("shortcutsEngine"), m_corona->globalShortcuts()->shortcutsTracker()); 0167 rootContext()->setContextProperty(QStringLiteral("viewConfig"), this); 0168 0169 if (m_corona) { 0170 rootContext()->setContextProperty(QStringLiteral("universalSettings"), m_corona->universalSettings()); 0171 rootContext()->setContextProperty(QStringLiteral("layoutsManager"), m_corona->layoutsManager()); 0172 } 0173 0174 KDeclarative::KDeclarative kdeclarative; 0175 kdeclarative.setDeclarativeEngine(engine()); 0176 kdeclarative.setTranslationDomain(QStringLiteral("latte-dock")); 0177 #if KF5_VERSION_MINOR >= 45 0178 kdeclarative.setupContext(); 0179 kdeclarative.setupEngine(engine()); 0180 #else 0181 kdeclarative.setupBindings(); 0182 #endif 0183 0184 QByteArray tempFilePath = "lattedockconfigurationui"; 0185 0186 updateEnabledBorders(); 0187 updateAvailableScreenGeometry(); 0188 0189 auto source = QUrl::fromLocalFile(m_latteView->containment()->corona()->kPackage().filePath(tempFilePath)); 0190 setSource(source); 0191 syncGeometry(); 0192 syncSlideEffect(); 0193 0194 qDebug() << "dock config view : initialization ended..."; 0195 } 0196 0197 inline Qt::WindowFlags PrimaryConfigView::wFlags() const 0198 { 0199 return (flags() | Qt::FramelessWindowHint /*| Qt::WindowStaysOnTopHint*/) & ~Qt::WindowDoesNotAcceptFocus; 0200 } 0201 0202 QQuickView *PrimaryConfigView::secondaryWindow() 0203 { 0204 return m_secConfigView; 0205 } 0206 0207 void PrimaryConfigView::createSecondaryWindow() 0208 { 0209 if (m_secConfigView) { 0210 return; 0211 } 0212 0213 m_secConfigView = new SecondaryConfigView(m_latteView, this); 0214 m_secConfigView->init(); 0215 } 0216 0217 void PrimaryConfigView::deleteSecondaryWindow() 0218 { 0219 if (m_secConfigView) { 0220 auto secWindow = m_secConfigView; 0221 m_secConfigView = nullptr; 0222 secWindow->deleteLater(); 0223 0224 if (KWindowSystem::isPlatformX11()) { 0225 //! this is needed in order for subtracked mask of secondary window to 0226 //! be released properly when changing for Advanced to Basic mode. 0227 //! Under wayland this is not needed because masks do not break any visuals. 0228 m_latteView->effects()->updateMask(); 0229 } 0230 } 0231 } 0232 0233 void PrimaryConfigView::updateAvailableScreenGeometry(View *origin) 0234 { 0235 int currentScrId = m_latteView->positioner()->currentScreenId(); 0236 m_availableScreenGeometry = m_corona->availableScreenRectWithCriteria(currentScrId, QString(), {}, {}, true); 0237 0238 emit availableScreenGeometryChanged(); 0239 } 0240 0241 QRect PrimaryConfigView::availableScreenGeometry() const 0242 { 0243 return m_availableScreenGeometry; 0244 } 0245 0246 QRect PrimaryConfigView::geometryWhenVisible() const 0247 { 0248 return m_geometryWhenVisible; 0249 } 0250 0251 void PrimaryConfigView::requestActivate() 0252 { 0253 if (KWindowSystem::isPlatformWayland() && m_shellSurface) { 0254 if (m_waylandWindowId.isNull()) { 0255 m_waylandWindowId = m_corona->wm()->winIdFor("latte-dock", geometry()); 0256 } 0257 0258 m_corona->wm()->requestActivate(m_waylandWindowId); 0259 } else { 0260 QQuickView::requestActivate(); 0261 } 0262 } 0263 0264 void PrimaryConfigView::syncGeometry() 0265 { 0266 if (!m_latteView || !m_latteView->layout() || !m_latteView->containment() || !rootObject()) { 0267 return; 0268 } 0269 0270 const QSize size(rootObject()->width(), rootObject()->height()); 0271 setMaximumSize(size); 0272 setMinimumSize(size); 0273 resize(size); 0274 0275 const auto location = m_latteView->containment()->location(); 0276 const auto scrGeometry = m_latteView->screenGeometry(); 0277 const auto availGeometry = m_availableScreenGeometry; 0278 0279 int clearThickness = m_latteView->editThickness(); 0280 0281 QPoint position{0, 0}; 0282 0283 int xPos{0}; 0284 int yPos{0}; 0285 0286 switch (m_latteView->formFactor()) { 0287 case Plasma::Types::Horizontal: { 0288 if (m_complexity == Latte::Types::ExpertSettings) { 0289 if (qApp->isLeftToRight()) { 0290 xPos = availGeometry.x() + availGeometry.width() - size.width(); 0291 } else { 0292 xPos = availGeometry.x(); 0293 } 0294 } else { 0295 xPos = scrGeometry.center().x() - size.width() / 2; 0296 } 0297 0298 if (location == Plasma::Types::TopEdge) { 0299 yPos = scrGeometry.y() + clearThickness; 0300 } else if (location == Plasma::Types::BottomEdge) { 0301 yPos = scrGeometry.y() + scrGeometry.height() - clearThickness - size.height(); 0302 } 0303 } 0304 break; 0305 0306 case Plasma::Types::Vertical: { 0307 if (location == Plasma::Types::LeftEdge) { 0308 xPos = scrGeometry.x() + clearThickness; 0309 yPos = availGeometry.y() + (availGeometry.height() - size.height())/2; 0310 } else if (location == Plasma::Types::RightEdge) { 0311 xPos = scrGeometry.x() + scrGeometry.width() - clearThickness - size.width(); 0312 yPos = availGeometry.y() + (availGeometry.height() - size.height())/2; 0313 } 0314 } 0315 break; 0316 0317 default: 0318 qWarning() << "no sync geometry, wrong formFactor"; 0319 break; 0320 } 0321 0322 position = {xPos, yPos}; 0323 0324 updateEnabledBorders(); 0325 0326 m_geometryWhenVisible = QRect(position.x(), position.y(), size.width(), size.height()); 0327 0328 setPosition(position); 0329 0330 if (m_shellSurface) { 0331 m_shellSurface->setPosition(position); 0332 } 0333 0334 updateShowInlineProperties(); 0335 0336 emit m_latteView->configWindowGeometryChanged(); 0337 } 0338 0339 void PrimaryConfigView::syncSlideEffect() 0340 { 0341 if (!m_latteView || !m_latteView->containment()) { 0342 return; 0343 } 0344 0345 auto slideLocation = WindowSystem::AbstractWindowInterface::Slide::None; 0346 0347 switch (m_latteView->containment()->location()) { 0348 case Plasma::Types::TopEdge: 0349 slideLocation = WindowSystem::AbstractWindowInterface::Slide::Top; 0350 break; 0351 0352 case Plasma::Types::RightEdge: 0353 slideLocation = WindowSystem::AbstractWindowInterface::Slide::Right; 0354 break; 0355 0356 case Plasma::Types::BottomEdge: 0357 slideLocation = WindowSystem::AbstractWindowInterface::Slide::Bottom; 0358 break; 0359 0360 case Plasma::Types::LeftEdge: 0361 slideLocation = WindowSystem::AbstractWindowInterface::Slide::Left; 0362 break; 0363 0364 default: 0365 qDebug() << staticMetaObject.className() << "wrong location"; 0366 break; 0367 } 0368 0369 m_corona->wm()->slideWindow(*this, slideLocation); 0370 } 0371 0372 void PrimaryConfigView::showEvent(QShowEvent *ev) 0373 { 0374 QQuickWindow::showEvent(ev); 0375 0376 if (!m_latteView) { 0377 return; 0378 } 0379 0380 m_corona->wm()->setViewExtraFlags(*this); 0381 setFlags(wFlags()); 0382 0383 syncGeometry(); 0384 syncSlideEffect(); 0385 0386 if (m_latteView && m_latteView->containment()) 0387 m_latteView->containment()->setUserConfiguring(true); 0388 0389 m_screenSyncTimer.start(); 0390 QTimer::singleShot(400, this, &PrimaryConfigView::syncGeometry); 0391 0392 emit showSignal(); 0393 } 0394 0395 void PrimaryConfigView::hideEvent(QHideEvent *ev) 0396 { 0397 if (!m_latteView) { 0398 deleteLater(); 0399 //QQuickWindow::hideEvent(ev); 0400 return; 0401 } 0402 0403 if (m_latteView->containment()) { 0404 m_latteView->containment()->setUserConfiguring(false); 0405 } 0406 0407 // QQuickWindow::hideEvent(ev); 0408 0409 const auto mode = m_latteView->visibility()->mode(); 0410 0411 if ((mode == Types::AlwaysVisible || mode == Types::WindowsGoBelow) 0412 && !(m_originalMode == Types::AlwaysVisible || m_originalMode == Types::WindowsGoBelow)) { 0413 //! mode changed to AlwaysVisible OR WindowsGoBelow FROM Dodge mode 0414 if (m_originalByPassWM) { 0415 //! if original by pass is active 0416 m_latteView->layout()->recreateView(m_latteView->containment()); 0417 } 0418 } else if (m_latteView->byPassWM() != m_originalByPassWM) { 0419 m_latteView->layout()->recreateView(m_latteView->containment()); 0420 } 0421 0422 deleteLater(); 0423 } 0424 0425 void PrimaryConfigView::focusOutEvent(QFocusEvent *ev) 0426 { 0427 Q_UNUSED(ev); 0428 0429 const auto *focusWindow = qGuiApp->focusWindow(); 0430 0431 if (!m_latteView 0432 || (focusWindow && (focusWindow->flags().testFlag(Qt::Popup) 0433 || focusWindow->flags().testFlag(Qt::ToolTip))) 0434 || m_latteView->alternativesIsShown()) { 0435 return; 0436 } 0437 0438 if (!m_blockFocusLost && !m_latteView->containsMouse() 0439 && (!m_secConfigView || (m_secConfigView && !m_secConfigView->isActive()))) { 0440 hideConfigWindow(); 0441 } 0442 } 0443 0444 void PrimaryConfigView::setupWaylandIntegration() 0445 { 0446 if (m_shellSurface || !KWindowSystem::isPlatformWayland() || !m_latteView || !m_latteView->containment()) { 0447 // already setup 0448 return; 0449 } 0450 0451 if (m_corona) { 0452 using namespace KWayland::Client; 0453 PlasmaShell *interface = m_corona->waylandCoronaInterface(); 0454 0455 if (!interface) { 0456 return; 0457 } 0458 0459 Surface *s = Surface::fromWindow(this); 0460 0461 if (!s) { 0462 return; 0463 } 0464 0465 qDebug() << "wayland primary settings surface was created..."; 0466 0467 m_shellSurface = interface->createSurface(s, this); 0468 m_shellSurface->setSkipTaskbar(true); 0469 #if KF5_VERSION_MINOR >= 47 0470 m_shellSurface->setSkipSwitcher(true); 0471 #endif 0472 0473 syncGeometry(); 0474 } 0475 } 0476 0477 bool PrimaryConfigView::event(QEvent *e) 0478 { 0479 if (e->type() == QEvent::PlatformSurface) { 0480 if (auto pe = dynamic_cast<QPlatformSurfaceEvent *>(e)) { 0481 switch (pe->surfaceEventType()) { 0482 case QPlatformSurfaceEvent::SurfaceCreated: 0483 0484 if (m_shellSurface) { 0485 break; 0486 } 0487 0488 setupWaylandIntegration(); 0489 break; 0490 0491 case QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed: 0492 if (m_shellSurface) { 0493 delete m_shellSurface; 0494 m_shellSurface = nullptr; 0495 qDebug() << "WAYLAND config window surface was deleted..."; 0496 } 0497 0498 break; 0499 } 0500 } 0501 } 0502 0503 return PlasmaQuick::ConfigView::event(e); 0504 } 0505 0506 0507 void PrimaryConfigView::immutabilityChanged(Plasma::Types::ImmutabilityType type) 0508 { 0509 if (type != Plasma::Types::Mutable && isVisible()) 0510 hideConfigWindow(); 0511 } 0512 0513 bool PrimaryConfigView::sticker() const 0514 { 0515 return m_blockFocusLost; 0516 } 0517 0518 void PrimaryConfigView::setSticker(bool blockFocusLost) 0519 { 0520 if (m_blockFocusLost == blockFocusLost) 0521 return; 0522 0523 m_blockFocusLost = blockFocusLost; 0524 } 0525 0526 bool PrimaryConfigView::showInlineProperties() const 0527 { 0528 return m_showInlineProperties; 0529 } 0530 void PrimaryConfigView::setShowInlineProperties(bool show) 0531 { 0532 if (m_showInlineProperties == show) { 0533 return; 0534 } 0535 0536 m_showInlineProperties = show; 0537 emit showInlinePropertiesChanged(); 0538 } 0539 0540 void PrimaryConfigView::updateShowInlineProperties() 0541 { 0542 if (!m_latteView) { 0543 return; 0544 } 0545 0546 bool showSecWindow{false}; 0547 bool complexityApprovedSecWindow{false}; 0548 0549 0550 if (m_complexity != Latte::Types::BasicSettings 0551 && !(m_complexity == Latte::Types::ExpertSettings && m_latteView->formFactor() == Plasma::Types::Vertical)) { 0552 showSecWindow = true; 0553 complexityApprovedSecWindow = true; 0554 } 0555 0556 //! consider screen geometry for showing or not the secondary window 0557 if (!geometryWhenVisible().isNull()) { 0558 createSecondaryWindow(); 0559 0560 if (m_secConfigView->geometryWhenVisible().intersects(geometryWhenVisible())) { 0561 showSecWindow = false; 0562 } else if (complexityApprovedSecWindow) { 0563 showSecWindow = true; 0564 } 0565 } 0566 0567 if (showSecWindow) { 0568 if (!m_secConfigView) { 0569 createSecondaryWindow(); 0570 } 0571 0572 QTimer::singleShot(150, m_secConfigView, SLOT(show())); 0573 setShowInlineProperties(false); 0574 } else { 0575 deleteSecondaryWindow(); 0576 setShowInlineProperties(true); 0577 } 0578 0579 // qDebug() << " showSecWindow:" << showSecWindow << " _ " << " inline:"<< !showSecWindow; 0580 } 0581 0582 int PrimaryConfigView::complexity() const 0583 { 0584 return (int)m_complexity; 0585 } 0586 0587 void PrimaryConfigView::setComplexity(int complexity) 0588 { 0589 if ((int)m_complexity == complexity) { 0590 return; 0591 } 0592 0593 m_complexity = static_cast<Latte::Types::SettingsComplexity>(complexity); 0594 0595 emit complexityChanged(); 0596 } 0597 0598 void PrimaryConfigView::hideConfigWindow() 0599 { 0600 if (m_shellSurface) { 0601 //!NOTE: Avoid crash in wayland environment with qt5.9 0602 close(); 0603 } else { 0604 hide(); 0605 } 0606 } 0607 0608 void PrimaryConfigView::updateLaunchersForGroup(int groupInt) 0609 { 0610 Types::LaunchersGroup group = (Types::LaunchersGroup)groupInt; 0611 0612 //! when the layout/global launchers list is empty then the current dock launchers are used for them 0613 //! as a start point 0614 if (m_corona && m_latteView->layout()) { 0615 if ((group == Types::LayoutLaunchers && m_latteView->layout()->launchers().isEmpty()) 0616 || (group == Types::GlobalLaunchers && m_corona->universalSettings()->launchers().isEmpty())) { 0617 0618 Plasma::Containment *c = m_latteView->containment(); 0619 0620 const auto &applets = c->applets(); 0621 0622 for (auto *applet : applets) { 0623 KPluginMetaData meta = applet->kPackage().metadata(); 0624 0625 if (meta.pluginId() == "org.kde.latte.plasmoid") { 0626 if (QQuickItem *appletInterface = applet->property("_plasma_graphicObject").value<QQuickItem *>()) { 0627 const auto &childItems = appletInterface->childItems(); 0628 0629 if (childItems.isEmpty()) { 0630 continue; 0631 } 0632 0633 for (QQuickItem *item : childItems) { 0634 if (auto *metaObject = item->metaObject()) { 0635 // not using QMetaObject::invokeMethod to avoid warnings when calling 0636 // this on applets that don't have it or other child items since this 0637 // is pretty much trial and error. 0638 // Also, "var" arguments are treated as QVariant in QMetaObject 0639 0640 int methodIndex = metaObject->indexOfMethod("getLauncherList()"); 0641 0642 if (methodIndex == -1) { 0643 continue; 0644 } 0645 0646 QMetaMethod method = metaObject->method(methodIndex); 0647 0648 QVariant launchers; 0649 0650 if (method.invoke(item, Q_RETURN_ARG(QVariant, launchers))) { 0651 if (group == Types::LayoutLaunchers) { 0652 m_latteView->layout()->setLaunchers(launchers.toStringList()); 0653 } else if (group == Types::GlobalLaunchers) { 0654 m_corona->universalSettings()->setLaunchers(launchers.toStringList()); 0655 } 0656 } 0657 } 0658 } 0659 } 0660 } 0661 } 0662 } 0663 } 0664 0665 } 0666 0667 //!BEGIN borders 0668 Plasma::FrameSvg::EnabledBorders PrimaryConfigView::enabledBorders() const 0669 { 0670 return m_enabledBorders; 0671 } 0672 0673 void PrimaryConfigView::updateEnabledBorders() 0674 { 0675 if (!this->screen()) { 0676 return; 0677 } 0678 0679 Plasma::FrameSvg::EnabledBorders borders = Plasma::FrameSvg::AllBorders; 0680 0681 switch (m_latteView->location()) { 0682 case Plasma::Types::TopEdge: 0683 borders &= m_inReverse ? ~Plasma::FrameSvg::BottomBorder : ~Plasma::FrameSvg::TopBorder; 0684 break; 0685 0686 case Plasma::Types::LeftEdge: 0687 borders &= ~Plasma::FrameSvg::LeftBorder; 0688 break; 0689 0690 case Plasma::Types::RightEdge: 0691 borders &= ~Plasma::FrameSvg::RightBorder; 0692 break; 0693 0694 case Plasma::Types::BottomEdge: 0695 borders &= m_inReverse ? ~Plasma::FrameSvg::TopBorder : ~Plasma::FrameSvg::BottomBorder; 0696 break; 0697 0698 default: 0699 break; 0700 } 0701 0702 if (m_enabledBorders != borders) { 0703 m_enabledBorders = borders; 0704 0705 m_corona->dialogShadows()->addWindow(this, m_enabledBorders); 0706 0707 emit enabledBordersChanged(); 0708 } 0709 } 0710 //!END borders 0711 0712 void PrimaryConfigView::updateEffects() 0713 { 0714 //! Don't apply any effect before the wayland surface is created under wayland 0715 //! https://bugs.kde.org/show_bug.cgi?id=392890 0716 if (KWindowSystem::isPlatformWayland() && !m_shellSurface) { 0717 return; 0718 } 0719 0720 if (!m_background) { 0721 m_background = new Plasma::FrameSvg(this); 0722 } 0723 0724 if (m_background->imagePath() != "widgets/panel-background") { 0725 m_background->setImagePath(QStringLiteral("widgets/panel-background")); 0726 } 0727 0728 m_background->setEnabledBorders(m_enabledBorders); 0729 m_background->resizeFrame(size()); 0730 0731 QRegion mask = m_background->mask(); 0732 0733 QRegion fixedMask = mask.isNull() ? QRegion(QRect(0,0,width(),height())) : mask; 0734 0735 if (!fixedMask.isEmpty()) { 0736 setMask(fixedMask); 0737 } else { 0738 setMask(QRegion()); 0739 } 0740 0741 if (KWindowSystem::compositingActive()) { 0742 KWindowEffects::enableBlurBehind(winId(), true, fixedMask); 0743 } else { 0744 KWindowEffects::enableBlurBehind(winId(), false); 0745 } 0746 } 0747 0748 //!BEGIN configuration 0749 void PrimaryConfigView::loadConfig() 0750 { 0751 if (!m_latteView || !m_latteView->containment()) { 0752 return; 0753 } 0754 auto config = m_latteView->containment()->config(); 0755 int complexity = config.readEntry("settingsComplexity", (int)Latte::Types::BasicSettings); 0756 setComplexity(static_cast<Latte::Types::SettingsComplexity>(complexity)); 0757 } 0758 0759 void PrimaryConfigView::saveConfig() 0760 { 0761 if (!m_latteView || !m_latteView->containment()) { 0762 return; 0763 } 0764 0765 auto config = m_latteView->containment()->config(); 0766 config.writeEntry("settingsComplexity", (int)m_complexity); 0767 config.sync(); 0768 } 0769 //!END configuration 0770 0771 } 0772 } 0773