diff --git a/app/view/visibilitymanager.cpp b/app/view/visibilitymanager.cpp index 6cdf00a7..71ec7a9c 100644 --- a/app/view/visibilitymanager.cpp +++ b/app/view/visibilitymanager.cpp @@ -1,773 +1,762 @@ /* * 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 "visibilitymanager.h" // local #include "positioner.h" #include "screenedgeghostwindow.h" #include "view.h" #include "../lattecorona.h" #include "../layoutmanager.h" #include "../screenpool.h" #include "../wm/windowinfowrap.h" #include "../../liblatte2/extras.h" // Qt #include // KDE #include #include namespace Latte { namespace ViewPart { //! BEGIN: VisiblityManager implementation VisibilityManager::VisibilityManager(PlasmaQuick::ContainmentView *view) : QObject(view) { qDebug() << "VisibilityManager creating..."; m_latteView = qobject_cast(view); m_corona = qobject_cast(view->corona()); wm = m_corona->wm(); if (m_latteView) { connect(m_latteView, &Latte::View::absGeometryChanged, this, &VisibilityManager::setViewGeometry); connect(m_latteView, &Latte::View::eventTriggered, this, &VisibilityManager::viewEventManager); } if (m_corona) { connect(this, &VisibilityManager::modeChanged, m_corona, &Plasma::Corona::availableScreenRectChanged); } m_timerStartUp.setInterval(5000); m_timerStartUp.setSingleShot(true); m_timerShow.setSingleShot(true); m_timerHide.setSingleShot(true); connect(&m_timerShow, &QTimer::timeout, this, [&]() { if (m_isHidden) { // qDebug() << "must be shown"; emit mustBeShown(); } }); connect(&m_timerHide, &QTimer::timeout, this, [&]() { if (!m_blockHiding && !m_isHidden && !dragEnter) { // qDebug() << "must be hide"; emit mustBeHide(); } }); wm->setViewExtraFlags(*m_latteView); wm->addView(m_latteView->winId()); restoreConfig(); } VisibilityManager::~VisibilityManager() { qDebug() << "VisibilityManager deleting..."; wm->removeViewStruts(*m_latteView); wm->removeView(m_latteView->winId()); if (edgeGhostWindow) { edgeGhostWindow->deleteLater(); } } Types::Visibility VisibilityManager::mode() const { return m_mode; } void VisibilityManager::setMode(Latte::Types::Visibility mode) { if (m_mode == mode) return; Q_ASSERT_X(m_mode != Types::None, staticMetaObject.className(), "set visibility to Types::None"); // clear mode for (auto &c : connections) { disconnect(c); } if (m_mode == Types::AlwaysVisible) { wm->removeViewStruts(*m_latteView); } else { connections[3] = connect(wm, &WindowSystem::currentDesktopChanged , this, [&] { if (raiseOnDesktopChange) raiseViewTemporarily(); }); connections[4] = connect(wm, &WindowSystem::currentActivityChanged , this, [&]() { if (raiseOnActivityChange) raiseViewTemporarily(); else updateHiddenState(); }); } m_timerShow.stop(); m_timerHide.stop(); m_mode = mode; switch (m_mode) { case Types::AlwaysVisible: { //set wayland visibility mode if (m_latteView->surface()) { m_latteView->surface()->setPanelBehavior(KWayland::Client::PlasmaShellSurface::PanelBehavior::WindowsGoBelow); } - if (m_latteView->containment() && !m_latteView->inEditMode() && m_latteView->screen()) { + if (m_latteView->containment() && m_latteView->screen()) { updateStrutsBasedOnLayoutsAndActivities(); } - connections[0] = connect(m_latteView->containment(), &Plasma::Containment::locationChanged - , this, [&]() { - if (m_latteView->inEditMode()) - wm->removeViewStruts(*m_latteView); - }); - connections[1] = connect(m_latteView, &Latte::View::inEditModeChanged - , this, [&]() { - if (!m_latteView->inEditMode() && !m_latteView->positioner()->inLocationChangeAnimation() && m_latteView->screen()) - wm->setViewStruts(*m_latteView, m_viewGeometry, m_latteView->containment()->location()); - }); - if (m_corona && m_corona->layoutManager()->memoryUsage() == Types::MultipleLayouts) { - connections[2] = connect(m_corona->activitiesConsumer(), &KActivities::Consumer::currentActivityChanged, this, [&]() { + connections[0] = connect(m_corona->activitiesConsumer(), &KActivities::Consumer::currentActivityChanged, this, [&]() { updateStrutsBasedOnLayoutsAndActivities(); }); - connections[3] = connect(m_latteView, &Latte::View::activitiesChanged, this, [&]() { + connections[1] = connect(m_latteView, &Latte::View::activitiesChanged, this, [&]() { updateStrutsBasedOnLayoutsAndActivities(); }); } raiseView(true); } break; case Types::AutoHide: { //set wayland visibility mode if (m_latteView->surface()) { m_latteView->surface()->setPanelBehavior(KWayland::Client::PlasmaShellSurface::PanelBehavior::AutoHide); } raiseView(m_containsMouse); } break; case Types::DodgeActive: { //set wayland visibility mode if (m_latteView->surface()) { m_latteView->surface()->setPanelBehavior(KWayland::Client::PlasmaShellSurface::PanelBehavior::AutoHide); } connections[0] = connect(wm, &WindowSystem::activeWindowChanged , this, &VisibilityManager::dodgeActive); connections[1] = connect(wm, &WindowSystem::windowChanged , this, &VisibilityManager::dodgeActive); dodgeActive(wm->activeWindow()); } break; case Types::DodgeMaximized: { //set wayland visibility mode if (m_latteView->surface()) { m_latteView->surface()->setPanelBehavior(KWayland::Client::PlasmaShellSurface::PanelBehavior::AutoHide); } connections[0] = connect(wm, &WindowSystem::activeWindowChanged , this, &VisibilityManager::dodgeMaximized); connections[1] = connect(wm, &WindowSystem::windowChanged , this, &VisibilityManager::dodgeMaximized); dodgeMaximized(wm->activeWindow()); } break; case Types::DodgeAllWindows: { //set wayland visibility mode if (m_latteView->surface()) { m_latteView->surface()->setPanelBehavior(KWayland::Client::PlasmaShellSurface::PanelBehavior::AutoHide); } connections[0] = connect(this, &VisibilityManager::containsMouseChanged , this, &VisibilityManager::dodgeAllWindows); connections[1] = connect(m_latteView->windowsTracker(), &WindowsTracker::existsWindowTouchingChanged , this, &VisibilityManager::dodgeAllWindows); } break; case Types::WindowsGoBelow: //set wayland visibility mode if (m_latteView->surface()) { m_latteView->surface()->setPanelBehavior(KWayland::Client::PlasmaShellSurface::PanelBehavior::WindowsGoBelow); } break; default: break; } m_latteView->containment()->config().writeEntry("visibility", static_cast(m_mode)); updateKWinEdgesSupport(); emit modeChanged(); } void VisibilityManager::updateStrutsBasedOnLayoutsAndActivities() { bool multipleLayoutsAndCurrent = (m_corona->layoutManager()->memoryUsage() == Types::MultipleLayouts && m_latteView->managedLayout() && !m_latteView->positioner()->inLocationChangeAnimation() && m_latteView->managedLayout()->isCurrent()); if (m_corona->layoutManager()->memoryUsage() == Types::SingleLayout || multipleLayoutsAndCurrent) { wm->setViewStruts(*m_latteView, m_viewGeometry, m_latteView->location()); } else { wm->removeViewStruts(*m_latteView); } } bool VisibilityManager::raiseOnDesktop() const { return raiseOnDesktopChange; } void VisibilityManager::setRaiseOnDesktop(bool enable) { if (enable == raiseOnDesktopChange) return; raiseOnDesktopChange = enable; emit raiseOnDesktopChanged(); } bool VisibilityManager::raiseOnActivity() const { return raiseOnActivityChange; } void VisibilityManager::setRaiseOnActivity(bool enable) { if (enable == raiseOnActivityChange) return; raiseOnActivityChange = enable; emit raiseOnActivityChanged(); } bool VisibilityManager::isHidden() const { return m_isHidden; } void VisibilityManager::setIsHidden(bool isHidden) { if (m_isHidden == isHidden) return; if (m_blockHiding && isHidden) { qWarning() << "isHidden property is blocked, ignoring update"; return; } m_isHidden = isHidden; updateGhostWindowState(); emit isHiddenChanged(); } bool VisibilityManager::blockHiding() const { return m_blockHiding; } void VisibilityManager::setBlockHiding(bool blockHiding) { if (m_blockHiding == blockHiding) { return; } m_blockHiding = blockHiding; // qDebug() << "blockHiding:" << blockHiding; if (m_blockHiding) { m_timerHide.stop(); if (m_isHidden) { emit mustBeShown(); } } else { updateHiddenState(); } emit blockHidingChanged(); } int VisibilityManager::timerShow() const { return m_timerShow.interval(); } void VisibilityManager::setTimerShow(int msec) { m_timerShow.setInterval(msec); emit timerShowChanged(); } int VisibilityManager::timerHide() const { return m_timerHide.interval(); } void VisibilityManager::setTimerHide(int msec) { m_timerHide.setInterval(msec); emit timerHideChanged(); } bool VisibilityManager::supportsKWinEdges() const { return (edgeGhostWindow != nullptr); } void VisibilityManager::updateGhostWindowState() { if (supportsKWinEdges()) { bool inCurrentLayout = (m_corona->layoutManager()->memoryUsage() == Types::SingleLayout || (m_corona->layoutManager()->memoryUsage() == Types::MultipleLayouts && m_latteView->managedLayout() && !m_latteView->positioner()->inLocationChangeAnimation() && m_latteView->managedLayout()->name() == m_corona->layoutManager()->currentLayoutName())); if (inCurrentLayout) { wm->setEdgeStateFor(edgeGhostWindow, m_isHidden); } else { wm->setEdgeStateFor(edgeGhostWindow, false); } } } void VisibilityManager::raiseView(bool raise) { if (m_blockHiding) return; if (raise) { m_timerHide.stop(); if (!m_timerShow.isActive()) { m_timerShow.start(); } } else if (!dragEnter) { m_timerShow.stop(); if (hideNow) { hideNow = false; emit mustBeHide(); } else if (!m_timerHide.isActive()) { m_timerHide.start(); } } } void VisibilityManager::raiseViewTemporarily() { if (raiseTemporarily) return; raiseTemporarily = true; m_timerHide.stop(); m_timerShow.stop(); if (m_isHidden) emit mustBeShown(); QTimer::singleShot(qBound(1800, 2 * m_timerHide.interval(), 3000), this, [&]() { raiseTemporarily = false; hideNow = true; updateHiddenState(); }); } void VisibilityManager::updateHiddenState() { if (dragEnter) return; switch (m_mode) { case Types::AutoHide: raiseView(m_containsMouse); break; case Types::DodgeActive: dodgeActive(wm->activeWindow()); break; case Types::DodgeMaximized: dodgeMaximized(wm->activeWindow()); break; case Types::DodgeAllWindows: dodgeAllWindows(); break; default: break; } } void VisibilityManager::setViewGeometry(const QRect &geometry) { - if (!m_latteView->containment()) + if (!m_latteView->containment() || m_viewGeometry == geometry) return; m_viewGeometry = geometry; - if (m_mode == Types::AlwaysVisible && !m_latteView->inEditMode() && m_latteView->screen()) { + if (m_mode == Types::AlwaysVisible && m_latteView->screen()) { updateStrutsBasedOnLayoutsAndActivities(); } } void VisibilityManager::applyActivitiesToHiddenWindows(const QStringList &activities) { if (edgeGhostWindow) { wm->setWindowOnActivities(*edgeGhostWindow, activities); } } void VisibilityManager::activeWindowDraggingStarted() { setContainsMouse(false); updateHiddenState(); } void VisibilityManager::dodgeActive(WindowId wid) { if (raiseTemporarily) return; //!don't send false raiseView signal when containing mouse if (m_containsMouse) { raiseView(true); return; } auto winfo = wm->requestInfo(wid); if (!winfo.isValid() || !winfo.isActive()) { winfo = wm->requestInfo(wm->activeWindow()); if (!winfo.isValid()) { //! very rare case that window manager doesn't have any active window at all raiseView(true); return; } } //! don't send false raiseView signal when containing mouse, // Johan comment //! I don't know why that wasn't winfo.wid() //active window, but just wid//the window that made the call if (wm->isOnCurrentDesktop(winfo.wid()) && wm->isOnCurrentActivity(winfo.wid())) { bool overlaps{intersects(winfo)}; raiseView(!overlaps); } } void VisibilityManager::dodgeMaximized(WindowId wid) { if (raiseTemporarily) return; //!don't send false raiseView signal when containing mouse if (m_containsMouse) { raiseView(true); return; } auto winfo = wm->requestInfo(wid); if (!winfo.isValid() || !winfo.isActive()) { winfo = wm->requestInfo(wm->activeWindow()); if (!winfo.isValid()) { //! very rare case that window manager doesn't have any active window at all raiseView(true); return; } } auto intersectsMaxVert = [&]() noexcept -> bool { return ((winfo.isMaxVert() || (m_latteView->screen() && m_latteView->screen()->availableSize().height() <= winfo.geometry().height())) && intersects(winfo)); }; auto intersectsMaxHoriz = [&]() noexcept -> bool { return ((winfo.isMaxHoriz() || (m_latteView->screen() && m_latteView->screen()->availableSize().width() <= winfo.geometry().width())) && intersects(winfo)); }; //! don't send false raiseView signal when containing mouse, // Johan comment //! I don't know why that wasn't winfo.wid() //active window, but just wid//the window that made the call if (wm->isOnCurrentDesktop(winfo.wid()) && wm->isOnCurrentActivity(winfo.wid())) { bool overlapsMaximized{m_latteView->formFactor() == Plasma::Types::Vertical ? intersectsMaxHoriz() : intersectsMaxVert()}; raiseView(!overlapsMaximized); } } void VisibilityManager::dodgeAllWindows() { if (raiseTemporarily) return; if (m_containsMouse) { raiseView(true); } bool windowIntersects{m_latteView->windowsTracker()->activeWindowTouching() || m_latteView->windowsTracker()->existsWindowTouching()}; raiseView(!windowIntersects); } bool VisibilityManager::intersects(const WindowInfoWrap &winfo) { return (!winfo.isMinimized() && wm->isOnCurrentDesktop(winfo.wid()) && wm->isOnCurrentActivity(winfo.wid()) && winfo.geometry().intersects(m_viewGeometry) && !winfo.isShaded()); } void VisibilityManager::saveConfig() { if (!m_latteView->containment()) return; auto config = m_latteView->containment()->config(); config.writeEntry("enableKWinEdges", enableKWinEdgesFromUser); config.writeEntry("timerShow", m_timerShow.interval()); config.writeEntry("timerHide", m_timerHide.interval()); config.writeEntry("raiseOnDesktopChange", raiseOnDesktopChange); config.writeEntry("raiseOnActivityChange", raiseOnActivityChange); m_latteView->containment()->configNeedsSaving(); } void VisibilityManager::restoreConfig() { if (!m_latteView || !m_latteView->containment()){ return; } auto config = m_latteView->containment()->config(); m_timerShow.setInterval(config.readEntry("timerShow", 0)); m_timerHide.setInterval(config.readEntry("timerHide", 700)); emit timerShowChanged(); emit timerHideChanged(); enableKWinEdgesFromUser = config.readEntry("enableKWinEdges", true); emit enableKWinEdgesChanged(); setRaiseOnDesktop(config.readEntry("raiseOnDesktopChange", false)); setRaiseOnActivity(config.readEntry("raiseOnActivityChange", false)); auto storedMode = static_cast(m_latteView->containment()->config().readEntry("visibility", static_cast(Types::DodgeActive))); if (storedMode == Types::AlwaysVisible) { qDebug() << "Loading visibility mode: Always Visible , on startup..."; setMode(Types::AlwaysVisible); } else { connect(&m_timerStartUp, &QTimer::timeout, this, [&]() { auto fMode = static_cast(m_latteView->containment()->config().readEntry("visibility", static_cast(Types::DodgeActive))); qDebug() << "Loading visibility mode:" << fMode << " on startup..."; setMode(fMode); }); connect(m_latteView->containment(), &Plasma::Containment::userConfiguringChanged , this, [&](bool configuring) { if (configuring && m_timerStartUp.isActive()) m_timerStartUp.start(100); }); m_timerStartUp.start(); } connect(m_latteView->containment(), &Plasma::Containment::userConfiguringChanged , this, [&](bool configuring) { if (!configuring) { saveConfig(); } }); } bool VisibilityManager::containsMouse() const { return m_containsMouse; } void VisibilityManager::setContainsMouse(bool contains) { if (m_containsMouse == contains) { return; } m_containsMouse = contains; emit containsMouseChanged(); if (contains && m_mode != Types::AlwaysVisible) { raiseView(true); } } void VisibilityManager::viewEventManager(QEvent *ev) { switch (ev->type()) { case QEvent::Enter: setContainsMouse(true); break; case QEvent::Leave: setContainsMouse(false); updateHiddenState(); break; case QEvent::DragEnter: dragEnter = true; if (m_isHidden) emit mustBeShown(); break; case QEvent::DragLeave: case QEvent::Drop: dragEnter = false; updateHiddenState(); break; case QEvent::Show: wm->setViewExtraFlags(*m_latteView); break; default: break; } } //! KWin Edges Support functions bool VisibilityManager::enableKWinEdges() const { return enableKWinEdgesFromUser; } void VisibilityManager::setEnableKWinEdges(bool enable) { if (enableKWinEdgesFromUser == enable) { return; } enableKWinEdgesFromUser = enable; emit enableKWinEdgesChanged(); updateKWinEdgesSupport(); } void VisibilityManager::updateKWinEdgesSupport() { if (m_mode == Types::AutoHide || m_mode == Types::DodgeActive || m_mode == Types::DodgeAllWindows || m_mode == Types::DodgeMaximized) { if (enableKWinEdgesFromUser) { createEdgeGhostWindow(); } else if (!enableKWinEdgesFromUser) { deleteEdgeGhostWindow(); } } else if (m_mode == Types::AlwaysVisible || m_mode == Types::WindowsGoBelow) { deleteEdgeGhostWindow(); } } void VisibilityManager::createEdgeGhostWindow() { if (!edgeGhostWindow) { edgeGhostWindow = new ScreenEdgeGhostWindow(m_latteView); wm->setViewExtraFlags(*edgeGhostWindow); connect(edgeGhostWindow, &ScreenEdgeGhostWindow::containsMouseChanged, this, [ = ](bool contains) { if (contains) { raiseView(true); } else { m_timerShow.stop(); updateGhostWindowState(); } }); connectionsKWinEdges[0] = connect(wm, &WindowSystem::currentActivityChanged, this, [&]() { bool inCurrentLayout = (m_corona->layoutManager()->memoryUsage() == Types::SingleLayout || (m_corona->layoutManager()->memoryUsage() == Types::MultipleLayouts && m_latteView->managedLayout() && !m_latteView->positioner()->inLocationChangeAnimation() && m_latteView->managedLayout()->name() == m_corona->layoutManager()->currentLayoutName())); if (edgeGhostWindow) { if (inCurrentLayout) { wm->setEdgeStateFor(edgeGhostWindow, m_isHidden); } else { wm->setEdgeStateFor(edgeGhostWindow, false); } } }); emit supportsKWinEdgesChanged(); } } void VisibilityManager::deleteEdgeGhostWindow() { if (edgeGhostWindow) { edgeGhostWindow->deleteLater(); edgeGhostWindow = nullptr; for (auto &c : connectionsKWinEdges) { disconnect(c); } emit supportsKWinEdgesChanged(); } } //! END: VisibilityManager implementation } } diff --git a/containment/package/contents/ui/VisibilityManager.qml b/containment/package/contents/ui/VisibilityManager.qml index 53e9a0c8..2a08b35c 100644 --- a/containment/package/contents/ui/VisibilityManager.qml +++ b/containment/package/contents/ui/VisibilityManager.qml @@ -1,716 +1,719 @@ /* * 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.Window 2.2 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.plasmoid 2.0 import org.kde.latte 0.2 as Latte Item{ id: manager anchors.fill: parent property QtObject window property bool debugMagager: Qt.application.arguments.indexOf("--mask") >= 0 property bool blockUpdateMask: false property bool inForceHiding: false //is used when the docks are forced in hiding e.g. when changing layouts property bool normalState : false // this is being set from updateMaskArea property bool previousNormalState : false // this is only for debugging purposes property bool panelIsBiggerFromIconSize: root.useThemePanel && (root.themePanelThickness >= (root.iconSize + root.thickMargin)) property int animationSpeed: Latte.WindowSystem.compositingActive ? root.appliedDurationTime * 1.2 * units.longDuration : 0 property bool inSlidingIn: false //necessary because of its init structure property alias inSlidingOut: slidingAnimationAutoHiddenOut.running property bool inTempHiding: false property int length: root.isVertical ? Screen.height : Screen.width //screenGeometry.height : screenGeometry.width property int slidingOutToPos: ((plasmoid.location===PlasmaCore.Types.LeftEdge)||(plasmoid.location===PlasmaCore.Types.TopEdge)) ? -thicknessNormal : thicknessNormal; property int thicknessAutoHidden: Latte.WindowSystem.compositingActive ? 2 : 1 property int thicknessMid: (1 + (0.65 * (root.maxZoomFactor-1)))*(root.iconSize+root.thickMargins+extraThickMask) //needed in some animations property int thicknessNormal: Math.max(root.iconSize + root.thickMargins + extraThickMask + 1, root.realPanelSize + root.panelShadow) property int thicknessZoom: ((root.iconSize+root.thickMargins+extraThickMask) * root.maxZoomFactor) + 2 //it is used to keep thickness solid e.g. when iconSize changes from auto functions property int thicknessMidOriginal: Math.max(thicknessNormalOriginal,extraThickMask + (1 + (0.65 * (root.maxZoomFactor-1)))*(root.maxIconSize+root.maxThickMargin)) //needed in some animations property int thicknessNormalOriginal: root.thickMargins + root.iconSize //this way we always have the same thickness published at all states /*property int thicknessNormalOriginal: !root.behaveAsPlasmaPanel || root.editMode ? thicknessNormalOriginalValue : root.realPanelSize + root.panelShadow*/ property int thicknessNormalOriginalValue: root.maxIconSize + (root.maxThickMargin * 2) + extraThickMask + 1 property int thicknessZoomOriginal: Math.max( ((root.maxIconSize+(root.maxThickMargin * 2)) * root.maxZoomFactor) + extraThickMask + 2, root.realPanelSize + root.panelShadow, (Latte.WindowSystem.compositingActive ? thicknessEditMode + root.editShadow : thicknessEditMode)) //! is used from Panel in edit mode in order to provide correct masking property int thicknessEditMode: thicknessNormalOriginalValue + editModeVisual.settingsThickness //! is used to increase the mask thickness readonly property int marginBetweenContentsAndRuler: 10 property int extraThickMask: marginBetweenContentsAndRuler + Math.max(indicatorsExtraThickMask, shadowsExtraThickMask) //! this is set from indicators when they need extra thickness mask size readonly property int indicatorsExtraThickMask: indicators.info.extraMaskThickness property int shadowsExtraThickMask: { var shadowMaxNeededMargin = 0.15 * root.maxIconSize; //! give some more space when items shadows are enabled and extremely big if (root.enableShadows && (plasmoid.configuration.shadowSize > 60 && plasmoid.configuration.shadowOpacity > 40)) { if (root.maxThickMargin < shadowMaxNeededMargin) { return shadowMaxNeededMargin - root.maxThickMargin; } } return 0; } Binding{ target: latteView property:"maxThickness" //! prevents updating window geometry during closing window in wayland and such fixes a crash when: latteView && !inTempHiding && !inForceHiding value: thicknessZoomOriginal } Binding{ target: latteView property:"normalThickness" when: latteView value: thicknessNormalOriginal } Binding{ target: latteView property:"editThickness" when: latteView value: thicknessEditMode } Binding{ target: latteView property: "type" when: latteView value: root.viewType } Binding{ target: latteView property: "behaveAsPlasmaPanel" when: latteView value: root.editMode ? false : root.behaveAsPlasmaPanel } Binding{ target: latteView property: "fontPixelSize" when: theme value: theme.defaultFont.pixelSize } Binding{ target: latteView property:"inEditMode" when: latteView value: root.editMode } Binding{ target: latteView property:"latteTasksArePresent" when: latteView value: latteApplet !== null } Binding{ target: latteView property: "maxLength" when: latteView value: root.editMode ? 1 : plasmoid.configuration.maxLength/100 } Binding{ target: latteView property: "offset" when: latteView value: plasmoid.configuration.offset } Binding{ target: latteView property: "alignment" when: latteView value: root.panelAlignment } Binding{ target: latteView && latteView.effects ? latteView.effects : null property: "backgroundOpacity" when: latteView && latteView.effects value: root.currentPanelTransparency } Binding{ target: latteView && latteView.effects ? latteView.effects : null property: "drawEffects" when: latteView && latteView.effects value: Latte.WindowSystem.compositingActive && (((root.blurEnabled && root.useThemePanel) || (root.blurEnabled && root.forceSolidPanel && Latte.WindowSystem.compositingActive)) && (!root.inStartup || inForceHiding || inTempHiding)) } Binding{ target: latteView && latteView.effects ? latteView.effects : null property: "drawShadows" when: latteView && latteView.effects value: root.drawShadowsExternal && (!root.inStartup || inForceHiding || inTempHiding) } Binding{ target: latteView && latteView.effects ? latteView.effects : null property:"editShadow" when: latteView && latteView.effects value: root.editShadow } Binding{ target: latteView && latteView.effects ? latteView.effects : null property:"innerShadow" when: latteView && latteView.effects value: { if (editModeVisual.editAnimationEnded && !root.behaveAsPlasmaPanel) { return root.editShadow; } else { return root.panelShadow; } } } Binding{ target: latteView && latteView.effects ? latteView.effects : null property: "settingsMaskSubtracted" when: latteView && latteView.effects value: { if (Latte.WindowSystem.compositingActive && root.editMode && editModeVisual.editAnimationEnded && (root.animationsNeedBothAxis === 0 || root.zoomFactor===1) ) { return true; } else { return false; } } } Binding{ target: latteView && latteView.windowsTracker ? latteView.windowsTracker : null property: "enabled" when: latteView && latteView.windowsTracker value: (latteView && latteView.visibility && latteView.visibility.mode === Latte.Types.DodgeAllWindows) || ((root.backgroundOnlyOnMaximized || plasmoid.configuration.solidBackgroundForMaximized || root.disablePanelShadowMaximized || root.windowColors !== Latte.Types.NoneWindowColors) && Latte.WindowSystem.compositingActive) } Connections{ target:root onPanelShadowChanged: updateMaskArea(); onPanelThickMarginHighChanged: updateMaskArea(); } Connections{ target: universalLayoutManager onCurrentLayoutIsSwitching: { if (Latte.WindowSystem.compositingActive && latteView && latteView.managedLayout && latteView.managedLayout.name === layoutName) { manager.inTempHiding = true; manager.inForceHiding = true; root.clearZoom(); manager.slotMustBeHide(); } } } onNormalStateChanged: { if (normalState) { root.updateAutomaticIconSize(); root.updateSizeForAppletsInFill(); } } onThicknessZoomOriginalChanged: { updateMaskArea(); } function slotContainsMouseChanged() { if(latteView.visibility.containsMouse) { updateMaskArea(); } } function slotMustBeShown() { // console.log("show..."); if (!slidingAnimationAutoHiddenIn.running && !inTempHiding && !inForceHiding){ slidingAnimationAutoHiddenIn.init(); } } function slotMustBeHide() { //! prevent sliding-in on startup if the dodge modes have sent a hide signal if (inStartupTimer.running && root.inStartup) { root.inStartup = false; } // console.log("hide...."); if((!slidingAnimationAutoHiddenOut.running && !latteView.visibility.blockHiding && !latteView.visibility.containsMouse) || inForceHiding) { slidingAnimationAutoHiddenOut.init(); } } //! functions used for sliding out/in during location/screen changes function slotHideDockDuringLocationChange() { inTempHiding = true; blockUpdateMask = true; slotMustBeHide(); } function slotShowDockAfterLocationChange() { slidingAnimationAutoHiddenIn.init(); } function sendHideDockDuringLocationChangeFinished(){ blockUpdateMask = false; latteView.positioner.hideDockDuringLocationChangeFinished(); } ///test maskArea function updateMaskArea() { if (!latteView || blockUpdateMask) { return; } var localX = 0; var localY = 0; normalState = ((root.animationsNeedBothAxis === 0) && (root.animationsNeedLength === 0)) || (latteView.visibility.isHidden && !latteView.visibility.containsMouse && root.animationsNeedThickness == 0); + // debug maskArea criteria if (debugMagager) { console.log(root.animationsNeedBothAxis + ", " + root.animationsNeedLength + ", " + root.animationsNeedThickness + ", " + latteView.visibility.isHidden); if (previousNormalState !== normalState) { console.log("normal state changed to:" + normalState); previousNormalState = normalState; } } var tempLength = root.isHorizontal ? width : height; var tempThickness = root.isHorizontal ? height : width; var space = 0; if (Latte.WindowSystem.compositingActive) { if (root.useThemePanel){ space = root.totalPanelEdgeSpacing + root.panelMarginLength + 1; } else { space = root.totalPanelEdgeSpacing + 1; } } else { space = root.totalPanelEdgeSpacing + root.panelMarginLength; } var noCompositingEdit = !Latte.WindowSystem.compositingActive && root.editMode; if (Latte.WindowSystem.compositingActive || noCompositingEdit) { if (normalState) { //console.log("entered normal state..."); //count panel length //used when !compositing and in editMode if (noCompositingEdit) { tempLength = root.isHorizontal ? root.width : root.height; } else { if(root.isHorizontal) { tempLength = plasmoid.configuration.panelPosition === Latte.Types.Justify ? layoutsContainer.width + space : layoutsContainer.mainLayout.width + space; } else { tempLength = plasmoid.configuration.panelPosition === Latte.Types.Justify ? layoutsContainer.height + space : layoutsContainer.mainLayout.height + space; } } tempThickness = thicknessNormal; if (root.animationsNeedThickness > 0) { tempThickness = Latte.WindowSystem.compositingActive ? thicknessZoom : thicknessNormal; } if (latteView.visibility.isHidden && !slidingAnimationAutoHiddenOut.running ) { tempThickness = thicknessAutoHidden; } //configure x,y based on plasmoid position and root.panelAlignment(Alignment) if ((plasmoid.location === PlasmaCore.Types.BottomEdge) || (plasmoid.location === PlasmaCore.Types.TopEdge)) { if (plasmoid.location === PlasmaCore.Types.BottomEdge) { localY = latteView.visibility.isHidden && latteView.visibility.supportsKWinEdges ? latteView.height + tempThickness : latteView.height - tempThickness; } else if (plasmoid.location === PlasmaCore.Types.TopEdge) { localY = latteView.visibility.isHidden && latteView.visibility.supportsKWinEdges ? -tempThickness : 0; } if (noCompositingEdit) { localX = 0; } else if (plasmoid.configuration.panelPosition === Latte.Types.Justify) { localX = (latteView.width/2) - tempLength/2 + root.offset; } else if (root.panelAlignment === Latte.Types.Left) { localX = root.offset; } else if (root.panelAlignment === Latte.Types.Center) { localX = (latteView.width/2) - tempLength/2 + root.offset; } else if (root.panelAlignment === Latte.Types.Right) { localX = latteView.width - layoutsContainer.mainLayout.width - space - root.offset; } } else if ((plasmoid.location === PlasmaCore.Types.LeftEdge) || (plasmoid.location === PlasmaCore.Types.RightEdge)){ if (plasmoid.location === PlasmaCore.Types.LeftEdge) { localX = latteView.visibility.isHidden && latteView.visibility.supportsKWinEdges ? -tempThickness : 0; } else if (plasmoid.location === PlasmaCore.Types.RightEdge) { localX = latteView.visibility.isHidden && latteView.visibility.supportsKWinEdges ? latteView.width + tempThickness : latteView.width - tempThickness; } if (noCompositingEdit) { localY = 0; } else if (plasmoid.configuration.panelPosition === Latte.Types.Justify) { localY = (latteView.height/2) - tempLength/2 + root.offset; } else if (root.panelAlignment === Latte.Types.Top) { localY = root.offset; } else if (root.panelAlignment === Latte.Types.Center) { localY = (latteView.height/2) - tempLength/2 + root.offset; } else if (root.panelAlignment === Latte.Types.Bottom) { localY = latteView.height - layoutsContainer.mainLayout.height - space - root.offset; } } } else { if(root.isHorizontal) tempLength = Screen.width; //screenGeometry.width; else tempLength = Screen.height; //screenGeometry.height; //grow only on length and not thickness if(root.animationsNeedLength>0 && root.animationsNeedBothAxis === 0) { //this is used to fix a bug with shadow showing when the animation of edit mode //is triggered tempThickness = editModeVisual.editAnimationEnded ? thicknessEditMode + root.editShadow : thicknessEditMode if (latteView.visibility.isHidden && !slidingAnimationAutoHiddenOut.running ) { tempThickness = thicknessAutoHidden; } else if (root.animationsNeedThickness > 0) { tempThickness = thicknessZoomOriginal; } } else{ //use all thickness space if (latteView.visibility.isHidden && !slidingAnimationAutoHiddenOut.running ) { tempThickness = Latte.WindowSystem.compositingActive ? thicknessAutoHidden : thicknessNormalOriginal; } else { tempThickness = thicknessZoomOriginal; } } //configure the x,y position based on thickness if(plasmoid.location === PlasmaCore.Types.RightEdge) localX = Math.max(0,latteView.width - tempThickness); else if(plasmoid.location === PlasmaCore.Types.BottomEdge) localY = Math.max(0,latteView.height - tempThickness); } } // end of compositing calculations var maskArea = latteView.effects.mask; if (Latte.WindowSystem.compositingActive) { var maskLength = maskArea.width; //in Horizontal if (root.isVertical) { maskLength = maskArea.height; } var maskThickness = maskArea.height; //in Horizontal if (root.isVertical) { maskThickness = maskArea.width; } } else if (!noCompositingEdit){ //! no compositing case if (!latteView.visibility.isHidden || !latteView.visibility.supportsKWinEdges) { localX = latteView.effects.rect.x; localY = latteView.effects.rect.y; } else { if (plasmoid.location === PlasmaCore.Types.BottomEdge) { localX = latteView.effects.rect.x; localY = latteView.effects.rect.y+latteView.effects.rect.height+thicknessAutoHidden; } else if (plasmoid.location === PlasmaCore.Types.TopEdge) { localX = latteView.effects.rect.x; localY = latteView.effects.rect.y - thicknessAutoHidden; } else if (plasmoid.location === PlasmaCore.Types.LeftEdge) { localX = latteView.effects.rect.x - thicknessAutoHidden; localY = latteView.effects.rect.y; } else if (plasmoid.location === PlasmaCore.Types.RightEdge) { localX = latteView.effects.rect.x + latteView.effects.rect.width + 1; localY = latteView.effects.rect.y; } } if (root.isHorizontal) { tempThickness = latteView.effects.rect.height; tempLength = latteView.effects.rect.width; } else { tempThickness = latteView.effects.rect.width; tempLength = latteView.effects.rect.height; } } // console.log("Not updating mask..."); if( maskArea.x !== localX || maskArea.y !== localY || maskLength !== tempLength || maskThickness !== tempThickness) { // console.log("Updating mask..."); var newMaskArea = Qt.rect(-1,-1,0,0); newMaskArea.x = localX; newMaskArea.y = localY; if (isHorizontal) { newMaskArea.width = tempLength; newMaskArea.height = tempThickness; } else { newMaskArea.width = tempThickness; newMaskArea.height = tempLength; } if (!Latte.WindowSystem.compositingActive) { latteView.effects.mask = newMaskArea; } else { if (latteView.behaveAsPlasmaPanel && !root.editMode) { latteView.effects.mask = Qt.rect(0,0,root.width,root.height); } else { latteView.effects.mask = newMaskArea; } } } + var validIconSize = (root.iconSize===root.maxIconSize || root.iconSize === root.automaticIconSizeBasedSize); + //console.log("reached updating geometry ::: "+dock.maskArea); - if(normalState){ + if((normalState && validIconSize) || (root.editMode && validIconSize)){ var tempGeometry = Qt.rect(latteView.effects.mask.x, latteView.effects.mask.y, latteView.effects.mask.width, latteView.effects.mask.height); //the shadows size must be removed from the maskArea //before updating the localDockGeometry if ((!latteView.behaveAsPlasmaPanel || root.editMode) && Latte.WindowSystem.compositingActive) { var fixedThickness = root.editMode ? root.iconSize + root.thickMargins : root.realPanelThickness; if (plasmoid.formFactor === PlasmaCore.Types.Vertical) { tempGeometry.width = fixedThickness; } else { tempGeometry.height = fixedThickness; } if (plasmoid.location === PlasmaCore.Types.BottomEdge) { tempGeometry.y = latteView.height - fixedThickness; } else if (plasmoid.location === PlasmaCore.Types.RightEdge) { tempGeometry.x = latteView.width - fixedThickness; } //set the boundaries for latteView local geometry //qBound = qMax(min, qMin(value, max)). tempGeometry.x = Math.max(0, Math.min(tempGeometry.x, latteView.width)); tempGeometry.y = Math.max(0, Math.min(tempGeometry.y, latteView.height)); tempGeometry.width = Math.min(tempGeometry.width, latteView.width); tempGeometry.height = Math.min(tempGeometry.height, latteView.height); } //console.log("update geometry ::: "+tempGeometry); if (!Latte.WindowSystem.compositingActive) { latteView.localGeometry = latteView.effects.rect; } else { latteView.localGeometry = tempGeometry; } } } Loader{ anchors.fill: parent active: root.debugMode sourceComponent: Item{ anchors.fill:parent Rectangle{ id: windowBackground anchors.fill: parent border.color: "red" border.width: 1 color: "transparent" } Rectangle{ x: latteView ? latteView.effects.mask.x : -1 y: latteView ? latteView.effects.mask.y : -1 height: latteView ? latteView.effects.mask.height : 0 width: latteView ? latteView.effects.mask.width : 0 border.color: "green" border.width: 1 color: "transparent" } } } /***Hiding/Showing Animations*****/ //////////////// Animations - Slide In - Out SequentialAnimation{ id: slidingAnimationAutoHiddenOut ScriptAction{ script: { root.isHalfShown = true; } } PropertyAnimation { target: layoutsContainer property: root.isVertical ? "x" : "y" to: { if (Latte.WindowSystem.compositingActive) { return slidingOutToPos; } else { if ((plasmoid.location===PlasmaCore.Types.LeftEdge)||(plasmoid.location===PlasmaCore.Types.TopEdge)) { return slidingOutToPos + 1; } else { return slidingOutToPos - 1; } } } duration: manager.animationSpeed easing.type: Easing.InQuad } ScriptAction{ script: { latteView.visibility.isHidden = true; } } onStarted: { if (manager.debugMagager) { console.log("hiding animation started..."); } } onStopped: { latteView.visibility.isHidden = true; if (manager.debugMagager) { console.log("hiding animation ended..."); } if (!manager.inTempHiding) { updateMaskArea(); } else { sendHideDockDuringLocationChangeFinished(); } } function init() { if (!latteView.visibility.blockHiding) start(); } } SequentialAnimation{ id: slidingAnimationAutoHiddenIn PauseAnimation{ duration: manager.inTempHiding && animationsEnabled ? 500 : 0 } PropertyAnimation { target: layoutsContainer property: root.isVertical ? "x" : "y" to: 0 duration: manager.animationSpeed easing.type: Easing.OutQuad } ScriptAction{ script: { root.isHalfShown = false; root.inStartup = false; } } onStarted: { if (manager.debugMagager) { console.log("showing animation started..."); } } onStopped: { inSlidingIn = false; if (manager.inTempHiding) { manager.inTempHiding = false; updateAutomaticIconSize(); } manager.inTempHiding = false; updateAutomaticIconSize(); if (manager.debugMagager) { console.log("showing animation ended..."); } } function init() { // if (!latteView.visibility.blockHiding) inSlidingIn = true; if (slidingAnimationAutoHiddenOut.running) { slidingAnimationAutoHiddenOut.stop(); } latteView.visibility.isHidden = false; updateMaskArea(); start(); } } }