diff --git a/app/dock/dockview.cpp b/app/dock/dockview.cpp index 611c0abe..fbf519e4 100644 --- a/app/dock/dockview.cpp +++ b/app/dock/dockview.cpp @@ -1,1171 +1,1162 @@ /* * Copyright 2016 Smith AR * Michail Vourlakos * * 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 . */ #include "dockview.h" #include "dockconfigview.h" #include "dockmenumanager.h" #include "effects.h" #include "panelshadows_p.h" #include "positioner.h" #include "visibilitymanager.h" #include "../dockcorona.h" #include "../layout.h" #include "../layoutmanager.h" #include "../screenpool.h" #include "../plasmathemeextended.h" #include "../universalsettings.h" #include "../../liblattedock/extras.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Latte { //! both alwaysVisible and dockWinBehavior are passed through corona because //! during the dock window creation containment hasn't been set, but these variables //! are needed in order for window flags to be set correctly DockView::DockView(Plasma::Corona *corona, QScreen *targetScreen, bool dockWindowBehavior) : PlasmaQuick::ContainmentView(corona), m_menuManager(new DockMenuManager(this)), m_effects(new View::Effects(this)), m_positioner(new View::Positioner(this)) //needs to be created after Effects becuase it catches some of its signals { setTitle(corona->kPackage().metadata().name()); setIcon(qGuiApp->windowIcon()); setResizeMode(QuickViewSharedEngine::SizeRootObjectToView); setColor(QColor(Qt::transparent)); setClearBeforeRendering(true); const auto flags = Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::NoDropShadowWindowHint | Qt::WindowDoesNotAcceptFocus; if (dockWindowBehavior) { setFlags(flags); } else { setFlags(flags | Qt::BypassWindowManagerHint); } KWindowSystem::setOnAllDesktops(winId(), true); if (targetScreen) m_positioner->setScreenToFollow(targetScreen); else m_positioner->setScreenToFollow(qGuiApp->primaryScreen()); connect(this, &DockView::containmentChanged , this, [ &, dockWindowBehavior]() { qDebug() << "dock view c++ containment changed 1..."; if (!this->containment()) return; qDebug() << "dock view c++ containment changed 2..."; //! First load default values from file restoreConfig(); //! Afterwards override that values in case during creation something different is needed setDockWinBehavior(dockWindowBehavior); //! Check the screen assigned to this dock reconsiderScreen(); if (!m_visibility) { m_visibility = new VisibilityManager(this); connect(m_visibility, &VisibilityManager::isHiddenChanged, this, [&]() { if (m_visibility->isHidden()) { deactivateApplets(); } }); } connect(this->containment(), SIGNAL(statusChanged(Plasma::Types::ItemStatus)), SLOT(statusChanged(Plasma::Types::ItemStatus))); }, Qt::DirectConnection); auto *dockCorona = qobject_cast(this->corona()); if (dockCorona) { connect(dockCorona, &DockCorona::docksCountChanged, this, &DockView::docksCountChanged); connect(this, &DockView::docksCountChanged, this, &DockView::totalDocksCountChanged); connect(dockCorona, &DockCorona::dockLocationChanged, this, &DockView::dockLocationChanged); } } DockView::~DockView() { m_inDelete = true; disconnect(corona(), &Plasma::Corona::availableScreenRectChanged, this, &DockView::availableScreenRectChanged); disconnect(containment(), SIGNAL(statusChanged(Plasma::Types::ItemStatus)), this, SLOT(statusChanged(Plasma::Types::ItemStatus))); qDebug() << "dock view deleting..."; rootContext()->setContextProperty(QStringLiteral("dock"), nullptr); //! this disconnect does not free up connections correctly when //! dockView is deleted. A crash for this example is the following: //! switch to Alternative Session and disable compositing, //! the signal creating the crash was probably from deleted //! windows. //! this->disconnect(); if (m_configView) { m_configView->setVisible(false);//hide(); } if (m_menuManager) { delete m_menuManager; } //needs to be deleted before Effects becuase it catches some of its signals if (m_positioner) { delete m_positioner; } if (m_effects) { delete m_effects; } if (m_visibility) delete m_visibility; } void DockView::init() { connect(this, &QQuickWindow::screenChanged, this, &DockView::docksCountChanged); connect(this, &QQuickWindow::xChanged, this, &DockView::xChanged); connect(this, &QQuickWindow::xChanged, this, &DockView::updateAbsDockGeometry); connect(this, &QQuickWindow::yChanged, this, &DockView::yChanged); connect(this, &QQuickWindow::yChanged, this, &DockView::updateAbsDockGeometry); connect(this, &QQuickWindow::widthChanged, this, &DockView::widthChanged); connect(this, &QQuickWindow::widthChanged, this, &DockView::updateAbsDockGeometry); connect(this, &QQuickWindow::heightChanged, this, &DockView::heightChanged); connect(this, &QQuickWindow::heightChanged, this, &DockView::updateAbsDockGeometry); connect(corona(), &Plasma::Corona::availableScreenRectChanged, this, &DockView::availableScreenRectChanged); connect(m_positioner, &View::Positioner::currentScreenChanged, this, &DockView::currentScreenChanged); connect(m_positioner, &View::Positioner::onHideWindowsForSlidingOut, this, &DockView::hideWindowsForSlidingOut); connect(m_positioner, &View::Positioner::screenGeometryChanged, this, &DockView::screenGeometryChanged); connect(this, &DockView::dockWinBehaviorChanged, this, &DockView::saveConfig); connect(this, &DockView::onPrimaryChanged, this, &DockView::saveConfig); connect(this, &DockView::isPreferredForShortcutsChanged, this, &DockView::saveConfig); - connect(&m_theme, &Plasma::Theme::themeChanged, this, &DockView::themeChanged); - connect(&m_theme, &Plasma::Theme::themeChanged, this, &DockView::themeHasShadowChanged); - connect(this, SIGNAL(normalThicknessChanged()), corona(), SIGNAL(availableScreenRectChanged())); connect(m_menuManager, &DockMenuManager::contextMenuChanged, this, &DockView::contextMenuIsShownChanged); ///!!!!! rootContext()->setContextProperty(QStringLiteral("dock"), this); auto *dockCorona = qobject_cast(this->corona()); if (dockCorona) { rootContext()->setContextProperty(QStringLiteral("universalSettings"), dockCorona->universalSettings()); rootContext()->setContextProperty(QStringLiteral("layoutManager"), dockCorona->layoutManager()); rootContext()->setContextProperty(QStringLiteral("themeExtended"), dockCorona->themeExtended()); } setSource(corona()->kPackage().filePath("lattedockui")); // setVisible(true); m_positioner->syncGeometry(); if (!KWindowSystem::isPlatformWayland()) { setVisible(true); } qDebug() << "SOURCE:" << source(); } bool DockView::inDelete() const { return m_inDelete; } void DockView::disconnectSensitiveSignals() { disconnect(corona(), &Plasma::Corona::availableScreenRectChanged, this, &DockView::availableScreenRectChanged); setManagedLayout(nullptr); if (visibility()) { visibility()->setEnabledDynamicBackground(false); } } void DockView::availableScreenRectChanged() { if (m_inDelete) return; if (formFactor() == Plasma::Types::Vertical) { m_positioner->syncGeometry(); } } void DockView::setupWaylandIntegration() { if (m_shellSurface) return; if (DockCorona *c = qobject_cast(corona())) { using namespace KWayland::Client; PlasmaShell *interface {c->waylandDockCoronaInterface()}; if (!interface) return; Surface *s{Surface::fromWindow(this)}; if (!s) return; m_shellSurface = interface->createSurface(s, this); qDebug() << "WAYLAND dock window surface was created..."; m_shellSurface->setSkipTaskbar(true); m_shellSurface->setRole(PlasmaShellSurface::Role::Panel); m_shellSurface->setPanelBehavior(PlasmaShellSurface::PanelBehavior::WindowsGoBelow); } } KWayland::Client::PlasmaShellSurface *DockView::surface() { return m_shellSurface; } //! the main function which decides if this dock is at the //! correct screen void DockView::reconsiderScreen() { m_positioner->reconsiderScreen(); } void DockView::addNewDock() { auto *dockCorona = qobject_cast(this->corona()); if (dockCorona) { dockCorona->loadDefaultLayout(); } } void DockView::copyDock() { m_managedLayout->copyDock(containment()); } void DockView::removeDock() { if (totalDocksCount() > 1) { QAction *removeAct = this->containment()->actions()->action(QStringLiteral("remove")); if (removeAct) { removeAct->trigger(); } } } QQmlListProperty DockView::screens() { return QQmlListProperty(this, nullptr, &countScreens, &atScreens); } int DockView::countScreens(QQmlListProperty *property) { Q_UNUSED(property) return qGuiApp->screens().count(); } QScreen *DockView::atScreens(QQmlListProperty *property, int index) { Q_UNUSED(property) return qGuiApp->screens().at(index); } QString DockView::currentScreen() const { return m_positioner->currentScreenName(); } bool DockView::settingsWindowIsShown() { auto configView = qobject_cast(m_configView); return (configView != nullptr); } void DockView::showSettingsWindow() { showConfigurationInterface(containment()); applyActivitiesToWindows(); } void DockView::showConfigurationInterface(Plasma::Applet *applet) { if (!applet || !applet->containment()) return; Plasma::Containment *c = qobject_cast(applet); if (m_configView && c && c->isContainment() && c == this->containment()) { if (m_configView->isVisible()) { m_configView->setVisible(false); //m_configView->hide(); } else { m_configView->setVisible(true); //m_configView->show(); } return; } else if (m_configView) { if (m_configView->applet() == applet) { m_configView->setVisible(true); //m_configView->show(); m_configView->requestActivate(); return; } else { m_configView->setVisible(false); //m_configView->hide(); m_configView->deleteLater(); } } bool delayConfigView = false; if (c && containment() && c->isContainment() && c->id() == this->containment()->id()) { m_configView = new DockConfigView(c, this); delayConfigView = true; } else { m_configView = new PlasmaQuick::ConfigView(applet); } m_configView.data()->init(); if (!delayConfigView) { m_configView->setVisible(true); //m_configView.data()->show(); } else { //add a timer for showing the configuration window the first time it is //created in order to give the containmnent's layouts the time to //calculate the window's height if (!KWindowSystem::isPlatformWayland()) { QTimer::singleShot(150, m_configView, SLOT(show())); } else { QTimer::singleShot(150, [this]() { m_configView->setVisible(true); }); } } } QRect DockView::localGeometry() const { return m_localGeometry; } void DockView::setLocalGeometry(const QRect &geometry) { if (m_localGeometry == geometry) { return; } m_localGeometry = geometry; emit localGeometryChanged(); updateAbsDockGeometry(); } void DockView::updateAbsDockGeometry(bool bypassChecks) { //! there was a -1 in height and width here. The reason of this //! if I remember correctly was related to multi-screen but I cant //! remember exactly the reason, something related to rigth edge in //! multi screen environment. BUT this was breaking the entire AlwaysVisible //! experience with struts. Removing them in order to restore correct //! behavior and keeping this comment in order to check for //! multi-screen breakage QRect absGeometry {x() + m_localGeometry.x(), y() + m_localGeometry.y() , m_localGeometry.width(), m_localGeometry.height()}; if (m_absGeometry == absGeometry && !bypassChecks) return; m_absGeometry = absGeometry; emit absGeometryChanged(m_absGeometry); //! this is needed in order to update correctly the screenGeometries if (visibility() && corona() && visibility()->mode() == Dock::AlwaysVisible) { emit corona()->availableScreenRectChanged(); emit corona()->availableScreenRegionChanged(); } } void DockView::statusChanged(Plasma::Types::ItemStatus status) { if (containment()) { if (containment()->status() >= Plasma::Types::NeedsAttentionStatus && containment()->status() != Plasma::Types::HiddenStatus) { setBlockHiding(true); } else { setBlockHiding(false); } } } bool DockView::alternativesIsShown() const { return m_alternativesIsShown; } void DockView::setAlternativesIsShown(bool show) { if (m_alternativesIsShown == show) { return; } m_alternativesIsShown = show; setBlockHiding(show); emit alternativesIsShownChanged(); } bool DockView::contextMenuIsShown() const { if (!m_menuManager) { return false; } return m_menuManager->contextMenu(); } int DockView::currentThickness() const { if (formFactor() == Plasma::Types::Vertical) { return m_effects->mask().isNull() ? width() : m_effects->mask().width() - m_effects->innerShadow(); } else { return m_effects->mask().isNull() ? height() : m_effects->mask().height() - m_effects->innerShadow(); } } int DockView::normalThickness() const { return m_normalThickness; } void DockView::setNormalThickness(int thickness) { if (m_normalThickness == thickness) { return; } m_normalThickness = thickness; emit normalThicknessChanged(); } int DockView::docksCount() const { if (!m_managedLayout) { return 0; } return m_managedLayout->docksCount(screen()); } int DockView::totalDocksCount() const { if (!m_managedLayout) { return 0; } return m_managedLayout->docksCount(); } int DockView::docksWithTasks() { if (!m_managedLayout) return 0; return m_managedLayout->noDocksWithTasks(); } bool DockView::dockWinBehavior() const { return m_dockWinBehavior; } void DockView::setDockWinBehavior(bool dock) { if (m_dockWinBehavior == dock) { return; } m_dockWinBehavior = dock; emit dockWinBehaviorChanged(); } bool DockView::behaveAsPlasmaPanel() const { return m_behaveAsPlasmaPanel; } void DockView::setBehaveAsPlasmaPanel(bool behavior) { if (m_behaveAsPlasmaPanel == behavior) { return; } m_behaveAsPlasmaPanel = behavior; if (m_behaveAsPlasmaPanel && m_effects->drawShadows()) { PanelShadows::self()->addWindow(this, m_effects->enabledBorders()); } else { PanelShadows::self()->removeWindow(this); } emit behaveAsPlasmaPanelChanged(); } bool DockView::inEditMode() const { return m_inEditMode; } void DockView::setInEditMode(bool edit) { if (m_inEditMode == edit) { return; } m_inEditMode = edit; emit inEditModeChanged(); } bool DockView::isPreferredForShortcuts() const { return m_isPreferredForShortcuts; } void DockView::setIsPreferredForShortcuts(bool preferred) { if (m_isPreferredForShortcuts == preferred) { return; } m_isPreferredForShortcuts = preferred; emit isPreferredForShortcutsChanged(); if (m_isPreferredForShortcuts && m_managedLayout) { emit m_managedLayout->preferredViewForShortcutsChanged(this); } } void DockView::preferredViewForShortcutsChangedSlot(DockView *view) { if (view != this) { setIsPreferredForShortcuts(false); } } bool DockView::onPrimary() const { return m_onPrimary; } void DockView::setOnPrimary(bool flag) { if (m_onPrimary == flag) { return; } m_onPrimary = flag; emit onPrimaryChanged(); } float DockView::maxLength() const { return m_maxLength; } void DockView::setMaxLength(float length) { if (m_maxLength == length) { return; } m_maxLength = length; emit maxLengthChanged(); } int DockView::maxThickness() const { return m_maxThickness; } void DockView::setMaxThickness(int thickness) { if (m_maxThickness == thickness) return; m_maxThickness = thickness; emit maxThicknessChanged(); } int DockView::alignment() const { return m_alignment; } void DockView::setAlignment(int alignment) { Dock::Alignment align = static_cast(alignment); if (m_alignment == alignment) { return; } m_alignment = align; emit alignmentChanged(); } -bool DockView::themeHasShadow() const -{ - return PanelShadows::self()->enabled(); -} - - QRect DockView::absGeometry() const { return m_absGeometry; } QRect DockView::screenGeometry() const { if (this->screen()) { QRect geom = this->screen()->geometry(); return geom; } return QRect(); } int DockView::offset() const { return m_offset; } void DockView::setOffset(int offset) { if (m_offset == offset) { return; } m_offset = offset; emit offsetChanged(); } int DockView::fontPixelSize() const { return m_fontPixelSize; } void DockView::setFontPixelSize(int size) { if (m_fontPixelSize == size) { return; } m_fontPixelSize = size; emit fontPixelSizeChanged(); } void DockView::applyActivitiesToWindows() { if (m_visibility) { QStringList activities = m_managedLayout->appliedActivities(); m_visibility->setWindowOnActivities(*this, activities); if (m_configView) { m_visibility->setWindowOnActivities(*m_configView, activities); auto configView = qobject_cast(m_configView); if (configView && configView->secondaryWindow()) { m_visibility->setWindowOnActivities(*configView->secondaryWindow(), activities); } } if (m_visibility->supportsKWinEdges()) { m_visibility->applyActivitiesToHiddenWindows(activities); } } } Layout *DockView::managedLayout() const { return m_managedLayout; } void DockView::setManagedLayout(Layout *layout) { if (m_managedLayout == layout) { return; } // clear mode for (auto &c : connectionsManagedLayout) { disconnect(c); } m_managedLayout = layout; if (m_managedLayout) { //! Sometimes the activity isnt completely ready, by adding a delay //! we try to catch up QTimer::singleShot(100, [this]() { if (m_managedLayout && m_visibility) { qDebug() << "DOCK VIEW FROM LAYOUT ::: " << m_managedLayout->name() << " - activities: " << m_managedLayout->appliedActivities(); applyActivitiesToWindows(); emit activitiesChanged(); } }); connectionsManagedLayout[0] = connect(m_managedLayout, &Layout::preferredViewForShortcutsChanged, this, &DockView::preferredViewForShortcutsChangedSlot); } DockCorona *dockCorona = qobject_cast(this->corona()); if (dockCorona->layoutManager()->memoryUsage() == Dock::MultipleLayouts) { connectionsManagedLayout[1] = connect(dockCorona->activitiesConsumer(), &KActivities::Consumer::runningActivitiesChanged, this, [&]() { if (m_managedLayout && m_visibility) { qDebug() << "DOCK VIEW FROM LAYOUT (runningActivitiesChanged) ::: " << m_managedLayout->name() << " - activities: " << m_managedLayout->appliedActivities(); applyActivitiesToWindows(); emit activitiesChanged(); } }); connectionsManagedLayout[2] = connect(m_managedLayout, &Layout::activitiesChanged, this, [&]() { if (m_managedLayout) { applyActivitiesToWindows(); emit activitiesChanged(); } }); connectionsManagedLayout[3] = connect(dockCorona->layoutManager(), &LayoutManager::layoutsChanged, this, [&]() { if (m_managedLayout) { applyActivitiesToWindows(); emit activitiesChanged(); } }); //!IMPORTANT!!! ::: This fixes a bug when closing an Activity all docks from all Activities are //! disappearing! With this they reappear!!! connectionsManagedLayout[4] = connect(this, &QWindow::visibleChanged, this, [&]() { if (!isVisible() && m_managedLayout) { QTimer::singleShot(100, [this]() { if (m_managedLayout && containment() && !containment()->destroyed()) { setVisible(true); applyActivitiesToWindows(); emit activitiesChanged(); } }); QTimer::singleShot(1500, [this]() { if (m_managedLayout && containment() && !containment()->destroyed()) { setVisible(true); applyActivitiesToWindows(); emit activitiesChanged(); } }); } }); } emit managedLayoutChanged(); } void DockView::moveToLayout(QString layoutName) { if (!m_managedLayout) { return; } QList containments = m_managedLayout->unassignFromLayout(this); DockCorona *dockCorona = qobject_cast(this->corona()); if (dockCorona && containments.size() > 0) { Layout *newLayout = dockCorona->layoutManager()->activeLayout(layoutName); if (newLayout) { newLayout->assignToLayout(this, containments); } } } void DockView::setBlockHiding(bool block) { if (!block) { auto *configView = qobject_cast(m_configView); if (m_alternativesIsShown || (configView && configView->sticker() && configView->isVisible())) { return; } if (m_visibility) { m_visibility->setBlockHiding(false); } } else { if (m_visibility) { m_visibility->setBlockHiding(true); } } } void DockView::hideWindowsForSlidingOut() { setBlockHiding(false); if (m_configView) { auto configDialog = qobject_cast(m_configView); if (configDialog) { configDialog->hideConfigWindow(); } } } //! remove latte tasks plasmoid void DockView::removeTasksPlasmoid() { if (!tasksPresent() || !containment()) { return; } foreach (Plasma::Applet *applet, containment()->applets()) { KPluginMetaData meta = applet->kPackage().metadata(); if (meta.pluginId() == "org.kde.latte.plasmoid") { QAction *closeApplet = applet->actions()->action(QStringLiteral("remove")); if (closeApplet) { closeApplet->trigger(); //! remove only the first found return; } } } } //! check if the tasks plasmoid exist in the dock bool DockView::tasksPresent() { if (!this->containment()) { return false; } foreach (Plasma::Applet *applet, this->containment()->applets()) { const auto &provides = KPluginMetaData::readStringList(applet->pluginMetaData().rawData(), QStringLiteral("X-Plasma-Provides")); if (provides.contains(QLatin1String("org.kde.plasma.multitasking"))) { return true; } } return false; } //! check if the tasks plasmoid exist in the dock bool DockView::latteTasksPresent() { if (!this->containment()) { return false; } foreach (Plasma::Applet *applet, this->containment()->applets()) { KPluginMetaData metadata = applet->pluginMetaData(); if (metadata.pluginId() == "org.kde.latte.plasmoid") { return true; } } return false; } //!check if the plasmoid with _name_ exists in the midedata bool DockView::mimeContainsPlasmoid(QMimeData *mimeData, QString name) { if (!mimeData) { return false; } if (mimeData->hasFormat(QStringLiteral("text/x-plasmoidservicename"))) { QString data = mimeData->data(QStringLiteral("text/x-plasmoidservicename")); const QStringList appletNames = data.split('\n', QString::SkipEmptyParts); foreach (const QString &appletName, appletNames) { if (appletName == name) return true; } } return false; } View::Effects *DockView::effects() const { return m_effects; } View::Positioner *DockView::positioner() const { return m_positioner; } VisibilityManager *DockView::visibility() const { return m_visibility; } bool DockView::event(QEvent *e) { if (!m_inDelete) { emit eventTriggered(e); switch (e->type()) { case QEvent::Leave: engine()->trimComponentCache(); break; case QEvent::PlatformSurface: if (auto pe = dynamic_cast(e)) { switch (pe->surfaceEventType()) { case QPlatformSurfaceEvent::SurfaceCreated: setupWaylandIntegration(); if (m_shellSurface) { m_positioner->syncGeometry(); if (m_effects->drawShadows()) { PanelShadows::self()->addWindow(this, m_effects->enabledBorders()); } } break; case QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed: if (m_shellSurface) { delete m_shellSurface; m_shellSurface = nullptr; qDebug() << "WAYLAND dock window surface was deleted..."; PanelShadows::self()->removeWindow(this); } break; } } break; default: break; } } return ContainmentView::event(e);; } QList DockView::freeEdges() const { if (!m_managedLayout) { const QList emptyEdges; return emptyEdges; } const auto edges = m_managedLayout->freeEdges(screen()); QList edgesInt; foreach (Plasma::Types::Location edge, edges) { edgesInt.append(static_cast(edge)); } return edgesInt; } void DockView::deactivateApplets() { if (!containment()) { return; } foreach (auto applet, containment()->applets()) { PlasmaQuick::AppletQuickItem *ai = applet->property("_plasma_graphicObject").value(); if (ai) { ai->setExpanded(false); } } } void DockView::toggleAppletExpanded(const int id) { if (!containment()) { return; } foreach (auto applet, containment()->applets()) { if (applet->id() == id) { PlasmaQuick::AppletQuickItem *ai = applet->property("_plasma_graphicObject").value(); if (ai) { if (!ai->isActivationTogglesExpanded()) { ai->setActivationTogglesExpanded(true); } emit applet->activated(); } } } } QVariantList DockView::containmentActions() { QVariantList actions; /*if (containment()->corona()->immutability() != Plasma::Types::Mutable) { return actions; }*/ //FIXME: the trigger string it should be better to be supported this way //const QString trigger = Plasma::ContainmentActions::eventToString(event); const QString trigger = "RightButton;NoModifier"; Plasma::ContainmentActions *plugin = this->containment()->containmentActions().value(trigger); if (!plugin) { return actions; } if (plugin->containment() != this->containment()) { plugin->setContainment(this->containment()); // now configure it KConfigGroup cfg(this->containment()->corona()->config(), "ActionPlugins"); cfg = KConfigGroup(&cfg, QString::number(this->containment()->containmentType())); KConfigGroup pluginConfig = KConfigGroup(&cfg, trigger); plugin->restore(pluginConfig); } foreach (QAction *ac, plugin->contextualActions()) { actions << QVariant::fromValue(ac); } return actions; } void DockView::disableGrabItemBehavior() { setMouseGrabEnabled(false); } void DockView::restoreGrabItemBehavior() { setMouseGrabEnabled(true); if (mouseGrabberItem()) { mouseGrabberItem()->ungrabMouse(); } } //!BEGIN overriding context menus behavior void DockView::mousePressEvent(QMouseEvent *event) { bool result = m_menuManager->mousePressEvent(event); emit contextMenuIsShownChanged(); if (result) { PlasmaQuick::ContainmentView::mousePressEvent(event); } } //!END overriding context menus behavior //!BEGIN configuration functions void DockView::saveConfig() { if (!this->containment()) return; auto config = this->containment()->config(); config.writeEntry("onPrimary", onPrimary()); config.writeEntry("dockWindowBehavior", dockWinBehavior()); config.writeEntry("isPreferredForShortcuts", isPreferredForShortcuts()); config.sync(); } void DockView::restoreConfig() { if (!this->containment()) return; auto config = this->containment()->config(); m_onPrimary = config.readEntry("onPrimary", true); m_dockWinBehavior = config.readEntry("dockWindowBehavior", true); m_isPreferredForShortcuts = config.readEntry("isPreferredForShortcuts", false); //! Send changed signals at the end in order to be sure that saveConfig //! wont rewrite default/invalid values emit onPrimaryChanged(); emit dockWinBehaviorChanged(); } //!END configuration functions } //!END namespace diff --git a/app/dock/dockview.h b/app/dock/dockview.h index 84233812..aeecb677 100644 --- a/app/dock/dockview.h +++ b/app/dock/dockview.h @@ -1,313 +1,304 @@ /* * Copyright 2016 Smith AR * Michail Vourlakos * * 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 . */ #ifndef DOCKVIEW_H #define DOCKVIEW_H #include "dockconfigview.h" #include "effects.h" #include "positioner.h" #include "visibilitymanager.h" #include "../layout.h" #include "../plasmaquick/containmentview.h" #include "../plasmaquick/configview.h" #include "../../liblattedock/dock.h" #include #include #include #include #include #include #include #include -#include - namespace Plasma { class Types; class Corona; class Containment; } namespace KWayland { namespace Client { class PlasmaShellSurface; } } namespace Latte { class DockMenuManager; class Layout; } namespace Latte { class DockView : public PlasmaQuick::ContainmentView { Q_OBJECT Q_PROPERTY(bool alternativesIsShown READ alternativesIsShown NOTIFY alternativesIsShownChanged) Q_PROPERTY(bool behaveAsPlasmaPanel READ behaveAsPlasmaPanel WRITE setBehaveAsPlasmaPanel NOTIFY behaveAsPlasmaPanelChanged) Q_PROPERTY(bool contextMenuIsShown READ contextMenuIsShown NOTIFY contextMenuIsShownChanged) Q_PROPERTY(bool dockWinBehavior READ dockWinBehavior WRITE setDockWinBehavior NOTIFY dockWinBehaviorChanged) //! Because Latte uses animations, changing to edit mode it may be different than //! when the isUserConfiguring changes value Q_PROPERTY(bool inEditMode READ inEditMode WRITE setInEditMode NOTIFY inEditModeChanged) Q_PROPERTY(bool isPreferredForShortcuts READ isPreferredForShortcuts WRITE setIsPreferredForShortcuts NOTIFY isPreferredForShortcutsChanged) - Q_PROPERTY(bool themeHasShadow READ themeHasShadow NOTIFY themeHasShadowChanged) Q_PROPERTY(bool onPrimary READ onPrimary WRITE setOnPrimary NOTIFY onPrimaryChanged) Q_PROPERTY(int alignment READ alignment WRITE setAlignment NOTIFY alignmentChanged) Q_PROPERTY(int docksCount READ docksCount NOTIFY docksCountChanged) Q_PROPERTY(int fontPixelSize READ fontPixelSize WRITE setFontPixelSize NOTIFY fontPixelSizeChanged) Q_PROPERTY(int totalDocksCount READ totalDocksCount NOTIFY totalDocksCountChanged) Q_PROPERTY(int x READ x NOTIFY xChanged) Q_PROPERTY(int y READ y NOTIFY yChanged) Q_PROPERTY(int width READ width NOTIFY widthChanged) Q_PROPERTY(int height READ height NOTIFY heightChanged) Q_PROPERTY(int maxThickness READ maxThickness WRITE setMaxThickness NOTIFY maxThicknessChanged) Q_PROPERTY(int normalThickness READ normalThickness WRITE setNormalThickness NOTIFY normalThicknessChanged) Q_PROPERTY(int offset READ offset WRITE setOffset NOTIFY offsetChanged) Q_PROPERTY(QString currentScreen READ currentScreen NOTIFY currentScreenChanged) Q_PROPERTY(float maxLength READ maxLength WRITE setMaxLength NOTIFY maxLengthChanged) Q_PROPERTY(Latte::View::Effects *effects READ effects NOTIFY effectsChanged) Q_PROPERTY(Layout *managedLayout READ managedLayout WRITE setManagedLayout NOTIFY managedLayoutChanged) Q_PROPERTY(Latte::View::Positioner *positioner READ positioner NOTIFY positionerChanged) Q_PROPERTY(VisibilityManager *visibility READ visibility NOTIFY visibilityChanged) Q_PROPERTY(QQmlListProperty screens READ screens) Q_PROPERTY(QRect absoluteGeometry READ absGeometry NOTIFY absGeometryChanged) Q_PROPERTY(QRect localGeometry READ localGeometry WRITE setLocalGeometry NOTIFY localGeometryChanged) Q_PROPERTY(QRect screenGeometry READ screenGeometry NOTIFY screenGeometryChanged) public: DockView(Plasma::Corona *corona, QScreen *targetScreen = nullptr, bool dockWindowBehavior = false); virtual ~DockView(); void init(); bool alternativesIsShown() const; void setAlternativesIsShown(bool show); bool inDelete() const; bool onPrimary() const; void setOnPrimary(bool flag); int currentThickness() const; int docksCount() const; int totalDocksCount() const; bool behaveAsPlasmaPanel() const; void setBehaveAsPlasmaPanel(bool behavior); bool contextMenuIsShown() const; bool dockWinBehavior() const; void setDockWinBehavior(bool dock); bool inEditMode() const; void setInEditMode(bool edit); bool isPreferredForShortcuts() const; void setIsPreferredForShortcuts(bool preferred); - bool themeHasShadow() const; - float maxLength() const; void setMaxLength(float length); int fontPixelSize() const; void setFontPixelSize(int size); int maxThickness() const; void setMaxThickness(int thickness); int normalThickness() const; void setNormalThickness(int thickness); int offset() const; void setOffset(int offset); int alignment() const; void setAlignment(int alignment); QRect absGeometry() const; QRect screenGeometry() const; QString currentScreen() const; QRect localGeometry() const; void setLocalGeometry(const QRect &geometry); bool settingsWindowIsShown(); void showSettingsWindow(); View::Effects *effects() const; View::Positioner *positioner() const; VisibilityManager *visibility() const; Layout *managedLayout() const; void setManagedLayout(Layout *layout); KWayland::Client::PlasmaShellSurface *surface(); void reconsiderScreen(); QQmlListProperty screens(); //! is needed by screens() static int countScreens(QQmlListProperty *property); //! is needed by screens() static QScreen *atScreens(QQmlListProperty *property, int index); //! these are signals that create crashes, such a example is the availableScreenRectChanged from corona //! when its containment is destroyed void disconnectSensitiveSignals(); public slots: Q_INVOKABLE void addNewDock(); Q_INVOKABLE void removeDock(); Q_INVOKABLE void copyDock(); Q_INVOKABLE QList freeEdges() const; Q_INVOKABLE QVariantList containmentActions(); Q_INVOKABLE void deactivateApplets(); Q_INVOKABLE void moveToLayout(QString layoutName); Q_INVOKABLE void removeTasksPlasmoid(); Q_INVOKABLE void setBlockHiding(bool block); Q_INVOKABLE void toggleAppletExpanded(const int id); Q_INVOKABLE int docksWithTasks(); Q_INVOKABLE bool mimeContainsPlasmoid(QMimeData *mimeData, QString name); Q_INVOKABLE bool tasksPresent(); Q_INVOKABLE bool latteTasksPresent(); void updateAbsDockGeometry(bool bypassChecks = false); Q_INVOKABLE void disableGrabItemBehavior(); Q_INVOKABLE void restoreGrabItemBehavior(); protected slots: void showConfigurationInterface(Plasma::Applet *applet) override; protected: bool event(QEvent *ev) override; void mousePressEvent(QMouseEvent *event) override; signals: void addInternalViewSplitter(); void removeInternalViewSplitter(); void eventTriggered(QEvent *ev); void activitiesChanged(); void alternativesIsShownChanged(); void alignmentChanged(); void behaveAsPlasmaPanelChanged(); void contextMenuIsShownChanged(); void currentScreenChanged(); void dockLocationChanged(); void docksCountChanged(); void dockWinBehaviorChanged(); void effectsChanged(); void fontPixelSizeChanged(); void widthChanged(); void heightChanged(); void inEditModeChanged(); void isPreferredForShortcutsChanged(); void localGeometryChanged(); void managedLayoutChanged(); void maxLengthChanged(); void maxThicknessChanged(); void normalThicknessChanged(); void offsetChanged(); void onPrimaryChanged(); void visibilityChanged(); void positionerChanged(); void screenGeometryChanged(); - void themeChanged(); - void themeHasShadowChanged(); void totalDocksCountChanged(); void xChanged(); void yChanged(); void absGeometryChanged(const QRect &geometry); private slots: void availableScreenRectChanged(); void hideWindowsForSlidingOut(); void preferredViewForShortcutsChangedSlot(DockView *view); void statusChanged(Plasma::Types::ItemStatus); void restoreConfig(); void saveConfig(); private: void applyActivitiesToWindows(); void initSignalingForLocationChangeSliding(); void setupWaylandIntegration(); void updateAppletContainsMethod(); private: Plasma::Containment *containmentById(uint id); bool m_alternativesIsShown{false}; bool m_behaveAsPlasmaPanel{false}; bool m_dockWinBehavior{true}; bool m_inDelete{false}; bool m_inEditMode{false}; bool m_isPreferredForShortcuts{false}; bool m_onPrimary{true}; int m_fontPixelSize{ -1}; int m_maxThickness{24}; int m_normalThickness{24}; int m_offset{0}; float m_maxLength{1}; Dock::Alignment m_alignment{Dock::Center}; QRect m_localGeometry; QRect m_absGeometry; Layout *m_managedLayout{nullptr}; QPointer m_configView; QPointer m_menuManager; QPointer m_effects; QPointer m_positioner; QPointer m_visibility; //! Connections to release and bound for the managed layout std::array connectionsManagedLayout; - Plasma::Theme m_theme; - KWayland::Client::PlasmaShellSurface *m_shellSurface{nullptr}; }; } #endif diff --git a/app/plasmathemeextended.cpp b/app/plasmathemeextended.cpp index d87be8e9..2b9aff0b 100644 --- a/app/plasmathemeextended.cpp +++ b/app/plasmathemeextended.cpp @@ -1,340 +1,348 @@ /* * Copyright 2018 Michail Vourlakos * * 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 . * */ #include "plasmathemeextended.h" #include "commontools.h" #include "dockcorona.h" #include "schemecolors.h" +#include "dock/panelshadows_p.h" #include #include #include #include #include #define REVERSEDCOLORSCHEME "reversed.colors" namespace Latte { PlasmaThemeExtended::PlasmaThemeExtended(KSharedConfig::Ptr config, QObject *parent) : QObject(parent), m_themeGroup(KConfigGroup(config, QStringLiteral("PlasmaThemeExtended"))) { m_corona = qobject_cast(parent); loadConfig(); + connect(&m_theme, &Plasma::Theme::themeChanged, this, &PlasmaThemeExtended::hasShadowChanged); connect(&m_theme, &Plasma::Theme::themeChanged, this, &PlasmaThemeExtended::load); + connect(&m_theme, &Plasma::Theme::themeChanged, this, &PlasmaThemeExtended::themeChanged); } void PlasmaThemeExtended::load() { loadThemePaths(); loadRoundness(); } PlasmaThemeExtended::~PlasmaThemeExtended() { saveConfig(); m_normalScheme->deleteLater(); m_reversedScheme->deleteLater(); } +bool PlasmaThemeExtended::hasShadow() const +{ + return PanelShadows::self()->enabled(); +} + int PlasmaThemeExtended::bottomEdgeRoundness() const { return (themeHasExtendedInfo() ? m_bottomEdgeRoundness : userThemeRoundness()); } int PlasmaThemeExtended::leftEdgeRoundness() const { return (themeHasExtendedInfo() ? m_leftEdgeRoundness : userThemeRoundness()); } int PlasmaThemeExtended::topEdgeRoundness() const { return (themeHasExtendedInfo() ? m_topEdgeRoundness : userThemeRoundness()); } int PlasmaThemeExtended::rightEdgeRoundness() const { return (themeHasExtendedInfo() ? m_rightEdgeRoundness : userThemeRoundness()); } int PlasmaThemeExtended::userThemeRoundness() const { return m_userRoundness; } void PlasmaThemeExtended::setUserThemeRoundness(int roundness) { if (m_userRoundness == roundness) { return; } m_userRoundness = roundness; if (!themeHasExtendedInfo()) { emit roundnessChanged(); } saveConfig(); } bool PlasmaThemeExtended::themeHasExtendedInfo() const { return m_themeHasExtendedInfo; } SchemeColors *PlasmaThemeExtended::lightTheme() const { return m_isLightTheme ? m_normalScheme : m_reversedScheme; } SchemeColors *PlasmaThemeExtended::darkTheme() const { return !m_isLightTheme ? m_normalScheme : m_reversedScheme; } void PlasmaThemeExtended::setNormalSchemeFile(const QString &file) { if (m_normalSchemePath == file) { return; } m_normalSchemePath = file; if (m_normalScheme) { disconnect(m_normalScheme, &SchemeColors::colorsChanged, this, &PlasmaThemeExtended::loadThemeLightness); m_normalScheme->deleteLater(); } m_normalScheme = new SchemeColors(this, m_normalSchemePath, true); connect(m_normalScheme, &SchemeColors::colorsChanged, this, &PlasmaThemeExtended::loadThemeLightness); qDebug() << "plasma theme normal colors ::: " << m_normalSchemePath; updateReversedScheme(); loadThemeLightness(); - emit themesChanged(); + emit themeChanged(); } void PlasmaThemeExtended::updateReversedScheme() { QString reversedFilePath = m_extendedThemeDir.path() + "/" + REVERSEDCOLORSCHEME; QFile(m_normalSchemePath).copy(reversedFilePath); m_reversedSchemePath = reversedFilePath; updateReversedSchemeValues(); if (m_reversedScheme) { m_reversedScheme->deleteLater(); } m_reversedScheme = new SchemeColors(this, m_reversedSchemePath, true); qDebug() << "plasma theme reversed colors ::: " << m_reversedSchemePath; } void PlasmaThemeExtended::updateReversedSchemeValues() { //! reverse values based on original scheme KSharedConfigPtr normalPtr = KSharedConfig::openConfig(m_normalSchemePath); KSharedConfigPtr reversedPtr = KSharedConfig::openConfig(m_reversedSchemePath); if (normalPtr && reversedPtr) { foreach (auto groupName, reversedPtr->groupList()) { if (groupName != "Colors:Button") { KConfigGroup reversedGroup(reversedPtr, groupName); if (reversedGroup.keyList().contains("BackgroundNormal") && reversedGroup.keyList().contains("ForegroundNormal")) { //! reverse usual text/background values KConfigGroup normalGroup(normalPtr, groupName); reversedGroup.writeEntry("BackgroundNormal", normalGroup.readEntry("ForegroundNormal", QColor())); reversedGroup.writeEntry("ForegroundNormal", normalGroup.readEntry("BackgroundNormal", QColor())); reversedGroup.sync(); } } } //! update WM group KConfigGroup reversedGroup(reversedPtr, "WM"); if (reversedGroup.keyList().contains("activeBackground") && reversedGroup.keyList().contains("activeForeground") && reversedGroup.keyList().contains("inactiveBackground") && reversedGroup.keyList().contains("inactiveForeground")) { //! reverse usual wm titlebar values KConfigGroup normalGroup(normalPtr, "WM"); reversedGroup.writeEntry("activeBackground", normalGroup.readEntry("activeForeground", QColor())); reversedGroup.writeEntry("activeForeground", normalGroup.readEntry("activeBackground", QColor())); reversedGroup.writeEntry("inactiveBackground", normalGroup.readEntry("inactiveForeground", QColor())); reversedGroup.writeEntry("inactiveForeground", normalGroup.readEntry("inactiveBackground", QColor())); reversedGroup.sync(); } if (reversedGroup.keyList().contains("activeBlend") && reversedGroup.keyList().contains("inactiveBlend")) { KConfigGroup normalGroup(normalPtr, "WM"); reversedGroup.writeEntry("activeBlend", normalGroup.readEntry("inactiveBlend", QColor())); reversedGroup.writeEntry("inactiveBlend", normalGroup.readEntry("activeBlend", QColor())); reversedGroup.sync(); } //! update scheme name QString normalSchemeName = SchemeColors::schemeName(m_normalSchemePath); KConfigGroup generalGroup(reversedPtr, "General"); generalGroup.writeEntry("Name", normalSchemeName + "_reversed"); generalGroup.sync(); } } void PlasmaThemeExtended::loadRoundness() { if (!m_corona) { return; } QString extendedInfoFilePath = m_corona->kPackage().filePath("themesExtendedInfo"); KSharedConfigPtr extInfoPtr = KSharedConfig::openConfig(extendedInfoFilePath); KConfigGroup roundGroup(extInfoPtr, "Roundness"); m_themeHasExtendedInfo = false; foreach (auto key, roundGroup.keyList()) { if (m_theme.themeName().toUpper().startsWith(key.toUpper())) { QStringList rs = roundGroup.readEntry(key, QStringList()); qDebug() << "roundness ::: " << rs; if (rs.size() > 0) { m_themeHasExtendedInfo = true; if (rs.size() <= 3) { //assign same roundness for all edges m_bottomEdgeRoundness = rs[0].toInt(); m_leftEdgeRoundness = m_bottomEdgeRoundness; m_topEdgeRoundness = m_bottomEdgeRoundness; m_rightEdgeRoundness = m_bottomEdgeRoundness; } else if (rs.size() >= 4) { m_bottomEdgeRoundness = rs[0].toInt(); m_leftEdgeRoundness = rs[1].toInt(); m_topEdgeRoundness = rs[2].toInt(); m_rightEdgeRoundness = rs[3].toInt(); } } break; } } emit roundnessChanged(); } void PlasmaThemeExtended::loadThemePaths() { m_themePath = ""; QString localD = QDir::homePath() + "/.local/share/plasma/desktoptheme/" + m_theme.themeName(); QString globalD = "/usr/share/plasma/desktoptheme/" + m_theme.themeName(); if (QDir(localD).exists()) { m_themePath = localD; } else if (QDir(globalD).exists()) { m_themePath = globalD; } qDebug() << "current plasma theme ::: " << m_theme.themeName(); qDebug() << "theme path ::: " << m_themePath; //! clear kde connections for (auto &c : m_kdeConnections) { disconnect(c); } //! assign color schemes QString themeColorScheme = m_themePath + "/colors"; if (QFileInfo(themeColorScheme).exists()) { setNormalSchemeFile(themeColorScheme); } else { //! when plasma theme uses the kde colors //! we track when kde color scheme is changing QString kdeSettingsFile = QDir::homePath() + "/.config/kdeglobals"; KDirWatch::self()->addFile(kdeSettingsFile); m_kdeConnections[0] = connect(KDirWatch::self(), &KDirWatch::dirty, this, [ &, kdeSettingsFile](const QString & path) { if (path == kdeSettingsFile) { this->setNormalSchemeFile(SchemeColors::possibleSchemeFile("kdeglobals")); } }); m_kdeConnections[1] = connect(KDirWatch::self(), &KDirWatch::created, this, [ &, kdeSettingsFile](const QString & path) { if (path == kdeSettingsFile) { this->setNormalSchemeFile(SchemeColors::possibleSchemeFile("kdeglobals")); } }); setNormalSchemeFile(SchemeColors::possibleSchemeFile("kdeglobals")); } } void PlasmaThemeExtended::loadThemeLightness() { float textColorLum = Latte::colorLumina(m_normalScheme->textColor()); float backColorLum = Latte::colorLumina(m_normalScheme->backgroundColor()); if (backColorLum > textColorLum) { m_isLightTheme = true; } else { m_isLightTheme = false; } if (m_isLightTheme) { qDebug() << "Plasma theme is light..."; } else { qDebug() << "Plasma theme is dark..."; } } void PlasmaThemeExtended::loadConfig() { m_userRoundness = m_themeGroup.readEntry("userSetPlasmaThemeRoundness", 0); } void PlasmaThemeExtended::saveConfig() { m_themeGroup.writeEntry("userSetPlasmaThemeRoundness", m_userRoundness); m_themeGroup.sync(); } } diff --git a/app/plasmathemeextended.h b/app/plasmathemeextended.h index eaf6edae..356cdb49 100644 --- a/app/plasmathemeextended.h +++ b/app/plasmathemeextended.h @@ -1,115 +1,120 @@ /* * Copyright 2018 Michail Vourlakos * * 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 . * */ #ifndef PLASMATHEMEEXTENDED_H #define PLASMATHEMEEXTENDED_H #include #include #include #include #include #include #include namespace Latte { class DockCorona; class PlasmaThemeExtended: public QObject { Q_OBJECT + Q_PROPERTY(bool hasShadow READ hasShadow NOTIFY hasShadowChanged) + Q_PROPERTY(int bottomEdgeRoundness READ bottomEdgeRoundness NOTIFY roundnessChanged) Q_PROPERTY(int leftEdgeRoundness READ leftEdgeRoundness NOTIFY roundnessChanged) Q_PROPERTY(int topEdgeRoundness READ topEdgeRoundness NOTIFY roundnessChanged) Q_PROPERTY(int rightEdgeRoundness READ rightEdgeRoundness NOTIFY roundnessChanged) - Q_PROPERTY(SchemeColors *lightTheme READ lightTheme NOTIFY themesChanged) - Q_PROPERTY(SchemeColors *darkTheme READ darkTheme NOTIFY themesChanged) + Q_PROPERTY(SchemeColors *lightTheme READ lightTheme NOTIFY themeChanged) + Q_PROPERTY(SchemeColors *darkTheme READ darkTheme NOTIFY themeChanged) public: PlasmaThemeExtended(KSharedConfig::Ptr config, QObject *parent); ~PlasmaThemeExtended() override;; + bool hasShadow() const; + int bottomEdgeRoundness() const; int leftEdgeRoundness() const; int topEdgeRoundness() const; int rightEdgeRoundness() const; int userThemeRoundness() const; void setUserThemeRoundness(int roundness); SchemeColors *lightTheme() const; SchemeColors *darkTheme() const; void load(); signals: + void hasShadowChanged(); void roundnessChanged(); - void themesChanged(); + void themeChanged(); private slots: void loadConfig(); void saveConfig(); void loadThemeLightness(); private: void loadThemePaths(); void loadRoundness(); void setNormalSchemeFile(const QString &file); void updateReversedScheme(); void updateReversedSchemeValues(); bool themeHasExtendedInfo() const; private: bool m_isLightTheme{false}; bool m_themeHasExtendedInfo{false}; int m_bottomEdgeRoundness{0}; int m_leftEdgeRoundness{0}; int m_topEdgeRoundness{0}; int m_rightEdgeRoundness{0}; int m_userRoundness{0}; QString m_themePath; QString m_normalSchemePath; QString m_reversedSchemePath; std::array m_kdeConnections; QTemporaryDir m_extendedThemeDir; KConfigGroup m_themeGroup; Plasma::Theme m_theme; DockCorona *m_corona{nullptr}; SchemeColors *m_normalScheme{nullptr}; SchemeColors *m_reversedScheme{nullptr}; }; } #endif diff --git a/app/universalsettings.h b/app/universalsettings.h index 18746112..f5bf0efb 100644 --- a/app/universalsettings.h +++ b/app/universalsettings.h @@ -1,187 +1,187 @@ /* * Copyright 2017 Smith AR * Michail Vourlakos * * 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 . */ #ifndef UNIVERSALSETTINGS_H #define UNIVERSALSETTINGS_H #include "dockcorona.h" #include #include #include #include #include #include "../liblattedock/dock.h" class SortedActivitiesModel; namespace Latte { class LayoutManager; //! This class holds all the settings that are universally available //! independent of layouts class UniversalSettings : public QObject { Q_OBJECT Q_PROPERTY(bool autostart READ autostart WRITE setAutostart NOTIFY autostartChanged) Q_PROPERTY(bool showInfoWindow READ showInfoWindow WRITE setShowInfoWindow NOTIFY showInfoWindowChanged) Q_PROPERTY(QString currentLayoutName READ currentLayoutName WRITE setCurrentLayoutName NOTIFY currentLayoutNameChanged) Q_PROPERTY(QStringList badgesForActivate READ badgesForActivate NOTIFY badgesForActivateChanged) Q_PROPERTY(QStringList launchers READ launchers WRITE setLaunchers NOTIFY launchersChanged) Q_PROPERTY(Latte::Dock::MouseSensitivity mouseSensitivity READ mouseSensitivity WRITE setMouseSensitivity NOTIFY mouseSensitivityChanged) Q_PROPERTY(QAbstractItemModel *runningActivitiesModel READ runningActivitiesModel NOTIFY runningActivitiesModelChanged) public: UniversalSettings(KSharedConfig::Ptr config, QObject *parent = nullptr); ~UniversalSettings() override; void load(); bool autostart() const; void setAutostart(bool state); bool canDisableBorders() const; void setCanDisableBorders(bool enable); bool metaForwardedToLatte() const; void forwardMetaToLatte(bool forward); bool showInfoWindow() const; void setShowInfoWindow(bool show); int version() const; void setVersion(int ver); int screenTrackerInterval() const; void setScreenTrackerInterval(int duration); QString currentLayoutName() const; void setCurrentLayoutName(QString layoutName); QString lastNonAssignedLayoutName() const; void setLastNonAssignedLayoutName(QString layoutName); QSize downloadWindowSize() const; void setDownloadWindowSize(QSize size); QSize layoutsWindowSize() const; void setLayoutsWindowSize(QSize size); QStringList badgesForActivate() const; QStringList layoutsColumnWidths() const; void setLayoutsColumnWidths(QStringList widths); QStringList launchers() const; void setLaunchers(QStringList launcherList); Dock::MouseSensitivity mouseSensitivity() const; void setMouseSensitivity(Dock::MouseSensitivity sensitivity); QAbstractItemModel *runningActivitiesModel() const; void setRunningActivitiesModel(SortedActivitiesModel *model); public slots: Q_INVOKABLE QString splitterIconPath(); Q_INVOKABLE QString trademarkIconPath(); Q_INVOKABLE float luminasFromFile(QString imageFile, int edge); signals: void autostartChanged(); void badgesForActivateChanged(); void canDisableBordersChanged(); void currentLayoutNameChanged(); void downloadWindowSizeChanged(); void lastNonAssignedLayoutNameChanged(); void layoutsColumnWidthsChanged(); void layoutsWindowSizeChanged(); void launchersChanged(); void layoutsMemoryUsageChanged(); void mouseSensitivityChanged(); void runningActivitiesModelChanged(); void screenTrackerIntervalChanged(); void showInfoWindowChanged(); void versionChanged(); private slots: void loadConfig(); void saveConfig(); void reconsiderActivitiesModel(); void shortcutsFileChanged(const QString &file); private: void cleanupSettings(); void enableActivitiesModel(); void disableActivitiesModel(); void initGlobalShortcutsWatcher(); //! access user set global shortcuts for activate entries void parseGlobalShortcuts(); bool kwin_metaForwardedToLatte() const; void kwin_forwardMetaToLatte(bool forward); Dock::LayoutsMemoryUsage layoutsMemoryUsage() const; void setLayoutsMemoryUsage(Dock::LayoutsMemoryUsage layoutsMemoryUsage); private: bool m_canDisableBorders{false}; bool m_showInfoWindow{true}; //when there isnt a version it is an old universal file int m_version{1}; int m_screenTrackerInterval{2500}; QString m_currentLayoutName; QString m_lastNonAssignedLayoutName; QSize m_downloadWindowSize{800, 550}; QSize m_layoutsWindowSize{700, 450}; QStringList m_badgesForActivate{"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "z", "x", "c", "v", "b", "n", "m", ",", "."}; QStringList m_layoutsColumnWidths; QStringList m_launchers; Dock::LayoutsMemoryUsage m_memoryUsage; Dock::MouseSensitivity m_mouseSensitivity{Dock::HighSensitivity}; - KConfigGroup m_universalGroup; - KSharedConfig::Ptr m_config; - KSharedConfig::Ptr m_shortcutsConfigPtr; - SortedActivitiesModel *m_runningActivitiesModel{nullptr}; QPointer m_corona; + KConfigGroup m_universalGroup; + KSharedConfig::Ptr m_config; + KSharedConfig::Ptr m_shortcutsConfigPtr; + friend class LayoutManager; friend class DockCorona; }; } #endif //UNIVERSALSETTINGS_H diff --git a/containment/package/contents/ui/PanelBox.qml b/containment/package/contents/ui/PanelBox.qml index 3b91bba8..cffd88a1 100644 --- a/containment/package/contents/ui/PanelBox.qml +++ b/containment/package/contents/ui/PanelBox.qml @@ -1,753 +1,753 @@ /* * Copyright 2016 Smith AR * Michail Vourlakos * * 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 . */ import QtQuick 2.1 import QtQuick.Layouts 1.1 import QtQuick.Window 2.2 import org.kde.plasma.plasmoid 2.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.kquickcontrolsaddons 2.0 import "colorizer" as Colorizer import org.kde.latte 0.1 as Latte Item{ id:barLine width: root.isHorizontal ? panelWidth : smallSize height: root.isVertical ? panelHeight : smallSize opacity: root.useThemePanel ? 1 : 0 property int animationTime: 6*root.durationTime*units.shortDuration property int lengthMargins: { return root.isVertical ? shadowsSvgItem.marginsHeight : shadowsSvgItem.marginsWidth } property int panelWidth: { if (root.behaveAsPlasmaPanel && !root.editMode) { return root.width; } else { if ((root.panelAlignment === Latte.Dock.Justify) && root.isHorizontal) { return root.maxLength; } else { return layoutsContainer.mainLayout.width + spacing; } } } property int panelHeight: { if (root.behaveAsPlasmaPanel && !root.editMode) { return root.height; } else { if ((root.panelAlignment === Latte.Dock.Justify) && root.isVertical) { return root.maxLength; } else { return layoutsContainer.mainLayout.height + spacing; } } } property int spacing: { if (!Latte.WindowSystem.compositingActive) { return 0; } else if (root.panelAlignment === Latte.Dock.Justify && plasmoid.configuration.maxLength === 100) { return 0; } else if (root.panelAlignment === Latte.Dock.Center || root.panelAlignment === Latte.Dock.Justify || root.offset!==0) { return root.panelEdgeSpacing/2; } else { return root.panelEdgeSpacing/4; } } property int smallSize: Math.max(3.7*root.statesLineSize, 16) Behavior on opacity{ enabled: Latte.WindowSystem.compositingActive NumberAnimation { duration: barLine.animationTime } } Behavior on opacity{ enabled: !Latte.WindowSystem.compositingActive NumberAnimation { duration: 0 } } Binding { target: root property: "realPanelLength" value: root.isVertical ? barLine.height : barLine.width } Binding { target: root property: "totalPanelEdgeSpacing" value: spacing } onXChanged: solidBackground.updateEffectsArea(); onYChanged: solidBackground.updateEffectsArea(); /// plasmoid's default panel /* BorderImage{ anchors.fill:parent source: "../images/panel-west.png" border { left:8; right:8; top:8; bottom:8 } opacity: (!root.useThemePanel) ? 1 : 0 visible: (opacity == 0) ? false : true horizontalTileMode: BorderImage.Stretch verticalTileMode: BorderImage.Stretch Behavior on opacity{ NumberAnimation { duration: 200 } } }*/ /// the current theme's panel PlasmaCore.FrameSvgItem{ id: shadowsSvgItem width: root.isVertical ? panelSize + marginsWidth - (solidBackground.leftIncreaser + solidBackground.rightIncreaser) : Math.min(parent.width + marginsWidth, root.width - marginsWidth) height: root.isVertical ? Math.min(parent.height + marginsHeight, root.height - marginsHeight) : panelSize + marginsHeight - (solidBackground.topIncreaser + solidBackground.bottomIncreaser) imagePath: root.behaveAsPlasmaPanel || !Latte.WindowSystem.compositingActive || !root.panelShadowsActive || !themeHasShadow ? "" : "widgets/panel-background" prefix: root.behaveAsPlasmaPanel || !Latte.WindowSystem.compositingActive || !root.panelShadowsActive || !themeHasShadow ? "" : "shadow" visible: (opacity == 0) ? false : true opacity: { if (root.forceTransparentPanel || !root.useThemePanel) return 0; else return 1; } enabledBorders: dock && dock.effects ? dock.effects.enabledBorders : PlasmaCore.FrameSvg.NoBorder - property bool themeHasShadow: dock ? dock.themeHasShadow : false + property bool themeHasShadow: themeExtended ? themeExtended.hasShadow : false Behavior on opacity { enabled: Latte.WindowSystem.compositingActive NumberAnimation { duration: barLine.animationTime } } Behavior on opacity{ enabled: !Latte.WindowSystem.compositingActive NumberAnimation { duration: 0 } } property int marginsWidth: { if (imagePath === "") { return 0; } else { if (root.panelAlignment === Latte.Dock.Left && root.offset===0) return margins.right; else if (root.panelAlignment === Latte.Dock.Right && root.offset===0) return margins.left; else return margins.left+margins.right; } } property int marginsHeight: { if (imagePath === "") { return 0; } else { if (root.panelAlignment === Latte.Dock.Top && root.offset===0) return margins.bottom; else if (root.panelAlignment === Latte.Dock.Bottom && root.offset===0) return margins.top; else return margins.top + margins.bottom; } } property int panelSize: automaticPanelSize property int automaticPanelSize: { if (root.behaveAsPlasmaPanel) { return root.statesLineSize + root.iconSize + root.thickMargin; } else { var icons = root.statesLineSize + root.iconSize + root.thickMargin + 1; var panels = root.themePanelSize + root.panelMargin; root.realPanelThickness = icons; if (icons > panels) { return panels; } else { return icons; } } } property int shadowsSize: 0 Binding{ target: shadowsSvgItem property: "shadowsSize" value:{ if (shadowsSvgItem && !root.behaveAsPlasmaPanel && root.useThemePanel && root.panelShadowsActive){ if (root.isVertical){ if (plasmoid.location === PlasmaCore.Types.LeftEdge) return shadowsSvgItem.margins.right; else if (plasmoid.location === PlasmaCore.Types.RightEdge) return shadowsSvgItem.margins.left; } else { if (plasmoid.location === PlasmaCore.Types.BottomEdge) return shadowsSvgItem.margins.top; else if (plasmoid.location === PlasmaCore.Types.TopEdge) return shadowsSvgItem.margins.bottom; } } else { return 0; } } } Behavior on opacity{ enabled: Latte.WindowSystem.compositingActive NumberAnimation { duration: barLine.animationTime } } Behavior on opacity{ enabled: !Latte.WindowSystem.compositingActive NumberAnimation { duration: 0 } } Binding { target: root property: "panelShadow" when: shadowsSvgItem value: shadowsSvgItem.shadowsSize } Binding { target: root property: "realPanelSize" when: shadowsSvgItem value: shadowsSvgItem.panelSize } Binding { target: root property: "panelMarginLength" when: shadowsSvgItem value: root.isVertical ? shadowsSvgItem.marginsHeight : shadowsSvgItem.marginsWidth } //! This is used to provide real solidness without any transparency from the plasma theme Rectangle{ id: solidBackgroundRectangle anchors.fill: solidBackground color: theme.backgroundColor opacity: behaveAsPlasmaPanel && solidBackground.forceSolidness && plasmoid.configuration.maxLength === 100 ? 1 : 0 Behavior on opacity{ enabled: Latte.WindowSystem.compositingActive NumberAnimation { duration: 2 * barLine.animationTime } } Behavior on opacity{ enabled: !Latte.WindowSystem.compositingActive NumberAnimation { duration: 0 } } } PlasmaCore.FrameSvgItem{ id: solidBackground anchors.leftMargin: Latte.WindowSystem.compositingActive ? shadowsSvgItem.margins.left - leftIncreaser : 0 anchors.rightMargin: Latte.WindowSystem.compositingActive ? shadowsSvgItem.margins.right - rightIncreaser : 0 anchors.topMargin: Latte.WindowSystem.compositingActive ? shadowsSvgItem.margins.top - topIncreaser : 0 anchors.bottomMargin: Latte.WindowSystem.compositingActive ? shadowsSvgItem.margins.bottom - bottomIncreaser : 0 anchors.fill:parent opacity: { if (forceSolidness) { return 1; } else if (!plasmoid.configuration.useThemePanel && plasmoid.configuration.solidBackgroundForMaximized) { return 0; } else { return plasmoid.configuration.panelTransparency / 100; } } readonly property bool forceSolidness: (root.solidPanel && !plasmoid.configuration.solidBackgroundForMaximized) || root.forceSolidPanel || !Latte.WindowSystem.compositingActive property rect efGeometry: Qt.rect(-1,-1,0,0) imagePath: root.solidPanel ? "opaque/dialogs/background" : "widgets/panel-background" onWidthChanged: updateEffectsArea(); onHeightChanged: updateEffectsArea(); Component.onCompleted: { root.updateEffectsArea.connect(updateEffectsArea); adjustPrefix(); } Component.onDestruction: { root.updateEffectsArea.disconnect(updateEffectsArea); } Binding{ target: root property: "currentPanelTransparency" value: solidBackground.opacity * 100 } Connections{ target: root onEditModeChanged: { if (!root.editMode){ solidBackground.updateEffectsArea(); } } onSolidPanelChanged: { adjustPrefix(); } } //! Fix for FrameSvgItem QML version not updating its margins after a theme change //! with this hack we enforce such update. I could use the repaintNeeded signal but //! it is called more often than the themeChanged one. Connections{ - target: dock + target: themeExtended onThemeChanged: { solidBackground.adjustPrefix(); plasmoid.configuration.panelShadows = !plasmoid.configuration.panelShadows; plasmoid.configuration.panelShadows = !plasmoid.configuration.panelShadows; updateEffectsArea(); } } Connections{ target: plasmoid onLocationChanged: solidBackground.adjustPrefix(); } function updateEffectsArea(){ if (!dock || root.editMode) return; var rootGeometry = mapToItem(root, 0, 0); efGeometry.x = rootGeometry.x; efGeometry.y = rootGeometry.y; efGeometry.width = width; efGeometry.height = height; dock.effects.rect = efGeometry; if (!Latte.WindowSystem.compositingActive) { visibilityManager.updateMaskArea(); } } //! the increases used when the user forces a solid background and the background //! must be increased in order to look ok in the corners property int rightIncreaser: { if (!(root.solidPanel && root.isVertical && plasmoid.location === PlasmaCore.Types.LeftEdge) || !Latte.WindowSystem.compositingActive) return 0; else return hiddenPanelBackground.margins.right; } property int leftIncreaser: { if (!(root.solidPanel && root.isVertical && plasmoid.location === PlasmaCore.Types.RightEdge) || !Latte.WindowSystem.compositingActive) return 0; else return hiddenPanelBackground.margins.left; } property int topIncreaser: { if (!(root.solidPanel && root.isVertical && plasmoid.location === PlasmaCore.Types.BottomEdge) || !Latte.WindowSystem.compositingActive) return 0; else return hiddenPanelBackground.margins.top; } property int bottomIncreaser: { if (!(root.solidPanel && root.isVertical && plasmoid.location === PlasmaCore.Types.TopEdge) || !Latte.WindowSystem.compositingActive) return 0; else return hiddenPanelBackground.margins.bottom; } Binding { target: root property: "panelMargin" value: { if (root.useThemePanel){ if (root.isVertical){ if (plasmoid.location === PlasmaCore.Types.LeftEdge) return solidBackground.margins.right; else if (plasmoid.location === PlasmaCore.Types.RightEdge) return solidBackground.margins.left; } else { if (plasmoid.location === PlasmaCore.Types.BottomEdge) return solidBackground.margins.top; else if (plasmoid.location === PlasmaCore.Types.TopEdge) return solidBackground.margins.bottom; } } } } onRepaintNeeded: { if (root.behaveAsPlasmaPanel) adjustPrefix(); } enabledBorders: dock && dock.effects ? dock.effects.enabledBorders : PlasmaCore.FrameSvg.NoBorder Behavior on opacity{ enabled: Latte.WindowSystem.compositingActive NumberAnimation { duration: barLine.animationTime } } Behavior on opacity{ enabled: !Latte.WindowSystem.compositingActive NumberAnimation { duration: 0 } } function adjustPrefix() { if (!plasmoid) { return ""; } var pre; switch (plasmoid.location) { case PlasmaCore.Types.LeftEdge: pre = "west"; break; case PlasmaCore.Types.TopEdge: pre = "north"; break; case PlasmaCore.Types.RightEdge: pre = "east"; break; case PlasmaCore.Types.BottomEdge: pre = "south"; break; default: prefix = ""; } prefix = [pre, ""]; } } Colorizer.CustomBackground { anchors.fill: solidBackground opacity: root.forceColorizeFromActiveWindowScheme ? solidBackground.opacity : 0 backgroundColor: root.forceColorizeFromActiveWindowScheme ? dock.visibility.touchingWindowScheme.backgroundColor : "transparent" roundness: { if (themeExtended) { switch(plasmoid.location) { case PlasmaCore.Types.BottomEdge: return themeExtended.bottomEdgeRoundness; case PlasmaCore.Types.LeftEdge: return themeExtended.leftEdgeRoundness; case PlasmaCore.Types.TopEdge: return themeExtended.topEdgeRoundness; case PlasmaCore.Types.RightEdge: return themeExtended.rightEdgeRoundness; default: return 0; } } return 0; } } PlasmaCore.FrameSvgItem{ id: hiddenPanelBackground imagePath: "widgets/panel-background" visible: false } } transitions: Transition { enabled: editModeVisual.plasmaEditMode AnchorAnimation { duration: 0.8 * root.animationTime easing.type: Easing.OutCubic } } //BEGIN states //user set Panel Positions //0-Center, 1-Left, 2-Right, 3-Top, 4-Bottom states: [ ///Left State { name: "leftCenterOrJustify" when: (plasmoid.location === PlasmaCore.Types.LeftEdge)&&(root.panelAlignment === Latte.Dock.Center || root.panelAlignment === Latte.Dock.Justify) AnchorChanges { target: barLine anchors{ top:undefined; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:parent.verticalCenter} } AnchorChanges { target: shadowsSvgItem anchors{ top:undefined; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:parent.verticalCenter} } PropertyChanges{ target: barLine anchors.leftMargin: 0; anchors.rightMargin:0; anchors.topMargin:0; anchors.bottomMargin:0; anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: (root.panelAlignment === Latte.Dock.Center ? root.offset : 0); } }, ///Left State { name: "leftTop" when: (plasmoid.location === PlasmaCore.Types.LeftEdge)&&(root.panelAlignment === Latte.Dock.Top) AnchorChanges { target: barLine anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined} } AnchorChanges { target: shadowsSvgItem anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined} } PropertyChanges{ target: barLine anchors.leftMargin: 0; anchors.rightMargin:0; anchors.topMargin:root.offset; anchors.bottomMargin:0; anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: 0; } }, ///Left State { name: "leftBottom" when: (plasmoid.location === PlasmaCore.Types.LeftEdge)&&(root.panelAlignment === Latte.Dock.Bottom) AnchorChanges { target: barLine anchors{ top:undefined; bottom:parent.bottom; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined} } AnchorChanges { target: shadowsSvgItem anchors{ top:undefined; bottom:parent.bottom; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined} } PropertyChanges{ target: barLine anchors.leftMargin: 0; anchors.rightMargin:0; anchors.topMargin:0; anchors.bottomMargin:root.offset; anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: 0; } }, ///Right State { name: "rightCenterOrJustify" when: (plasmoid.location === PlasmaCore.Types.RightEdge)&&(root.panelAlignment === Latte.Dock.Center || root.panelAlignment === Latte.Dock.Justify) AnchorChanges { target: barLine anchors{ top:undefined; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:parent.verticalCenter} } AnchorChanges { target: shadowsSvgItem anchors{ top:undefined; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:parent.verticalCenter} } PropertyChanges{ target: barLine anchors.leftMargin: 0; anchors.rightMargin:0; anchors.topMargin:0; anchors.bottomMargin:0; anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: (root.panelAlignment === Latte.Dock.Center ? root.offset : 0); } }, State { name: "rightTop" when: (plasmoid.location === PlasmaCore.Types.RightEdge)&&(root.panelAlignment === Latte.Dock.Top) AnchorChanges { target: barLine anchors{ top:parent.top; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined} } AnchorChanges { target: shadowsSvgItem anchors{ top:parent.top; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined} } PropertyChanges{ target: barLine anchors.leftMargin: 0; anchors.rightMargin:0; anchors.topMargin:root.offset; anchors.bottomMargin:0; anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: 0; } }, State { name: "rightBottom" when: (plasmoid.location === PlasmaCore.Types.RightEdge)&&(root.panelAlignment === Latte.Dock.Bottom) AnchorChanges { target: barLine anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined } } AnchorChanges { target: shadowsSvgItem anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined} } PropertyChanges{ target: barLine anchors.leftMargin: 0; anchors.rightMargin:0; anchors.topMargin:0; anchors.bottomMargin:root.offset; anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: 0; } }, ///Bottom State { name: "bottomCenterOrJustify" when: (plasmoid.location === PlasmaCore.Types.BottomEdge)&&(root.panelAlignment === Latte.Dock.Center || root.panelAlignment === Latte.Dock.Justify) AnchorChanges { target: barLine anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined} } AnchorChanges { target: shadowsSvgItem anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined} } PropertyChanges{ target: barLine anchors.leftMargin: 0; anchors.rightMargin:0; anchors.topMargin:0; anchors.bottomMargin:0; anchors.horizontalCenterOffset: (root.panelAlignment === Latte.Dock.Center ? root.offset : 0); anchors.verticalCenterOffset: 0; } }, State { name: "bottomLeft" when: (plasmoid.location === PlasmaCore.Types.BottomEdge) &&(((root.panelAlignment === Latte.Dock.Left)&&(Qt.application.layoutDirection !== Qt.RightToLeft)) || ((root.panelAlignment === Latte.Dock.Right)&&(Qt.application.layoutDirection === Qt.RightToLeft))) AnchorChanges { target: barLine anchors{ top:undefined; bottom:parent.bottom; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined} } AnchorChanges { target: shadowsSvgItem anchors{ top:undefined; bottom:parent.bottom; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined} } PropertyChanges{ target: barLine anchors.leftMargin: root.offset; anchors.rightMargin:0; anchors.topMargin:0; anchors.bottomMargin:0; anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: 0; } }, State { name: "bottomRight" when: (plasmoid.location === PlasmaCore.Types.BottomEdge) &&(((root.panelAlignment === Latte.Dock.Right)&&(Qt.application.layoutDirection !== Qt.RightToLeft)) ||((root.panelAlignment === Latte.Dock.Left)&&(Qt.application.layoutDirection === Qt.RightToLeft))) AnchorChanges { target: barLine anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined} } AnchorChanges { target: shadowsSvgItem anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined} } PropertyChanges{ target: barLine anchors.leftMargin: 0; anchors.rightMargin:root.offset; anchors.topMargin:0; anchors.bottomMargin:0; anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: 0; } }, ///Top State { name: "topCenterOrJustify" when: (plasmoid.location === PlasmaCore.Types.TopEdge)&&(root.panelAlignment === Latte.Dock.Center || root.panelAlignment === Latte.Dock.Justify) AnchorChanges { target: barLine anchors{ top:parent.top; bottom:undefined; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined} } AnchorChanges { target: shadowsSvgItem anchors{ top:parent.top; bottom:undefined; left:undefined; right:undefined; horizontalCenter:parent.horizontalCenter; verticalCenter:undefined} } PropertyChanges{ target: barLine anchors.leftMargin: 0; anchors.rightMargin:0; anchors.topMargin:0; anchors.bottomMargin:0; anchors.horizontalCenterOffset: (root.panelAlignment === Latte.Dock.Center ? root.offset : 0); anchors.verticalCenterOffset: 0; } }, State { name: "topLeft" when: (plasmoid.location === PlasmaCore.Types.TopEdge) &&(((root.panelAlignment === Latte.Dock.Left)&&(Qt.application.layoutDirection !== Qt.RightToLeft)) || ((root.panelAlignment === Latte.Dock.Right)&&(Qt.application.layoutDirection === Qt.RightToLeft))) AnchorChanges { target: barLine anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined} } AnchorChanges { target: shadowsSvgItem anchors{ top:parent.top; bottom:undefined; left:parent.left; right:undefined; horizontalCenter:undefined; verticalCenter:undefined} } PropertyChanges{ target: barLine anchors.leftMargin: root.offset; anchors.rightMargin:0; anchors.topMargin:0; anchors.bottomMargin:0; anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: 0; } }, State { name: "topRight" when: (plasmoid.location === PlasmaCore.Types.TopEdge) &&(((root.panelAlignment === Latte.Dock.Right)&&(Qt.application.layoutDirection !== Qt.RightToLeft)) ||((root.panelAlignment === Latte.Dock.Left)&&(Qt.application.layoutDirection === Qt.RightToLeft))) AnchorChanges { target: barLine anchors{ top:parent.top; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined} } AnchorChanges { target: shadowsSvgItem anchors{ top:parent.top; bottom:undefined; left:undefined; right:parent.right; horizontalCenter:undefined; verticalCenter:undefined} } PropertyChanges{ target: barLine anchors.leftMargin: 0; anchors.rightMargin:root.offset; anchors.topMargin:0; anchors.bottomMargin:0; anchors.horizontalCenterOffset: 0; anchors.verticalCenterOffset: 0; } } ] //END states }