From 736d068a44aa3e336fbccaaff7bd158f3a41c77f Mon Sep 17 00:00:00 2001 From: Michail Vourlakos Date: Fri, 8 Mar 2019 23:43:08 +0200 Subject: [PATCH] improve masking for config windows --now config windows are masked properly in order to accessible to all of their areas. By design the config windows are trying to be below the main view, this is why masking is needed in order to work properly and not having areas that can not be clicked/accessed because of the top Latte View --- app/view/effects.cpp | 87 +++++++++++++++++-- app/view/effects.h | 12 +++ app/view/settings/primaryconfigview.cpp | 4 +- app/view/settings/primaryconfigview.h | 2 +- app/view/view.cpp | 5 ++ app/view/view.h | 3 + .../package/contents/ui/VisibilityManager.qml | 15 ++++ containment/package/contents/ui/main.qml | 2 +- 8 files changed, 122 insertions(+), 8 deletions(-) diff --git a/app/view/effects.cpp b/app/view/effects.cpp index bcd3bc3cb..4d8ec46f2 100644 --- a/app/view/effects.cpp +++ b/app/view/effects.cpp @@ -22,6 +22,7 @@ // local #include "panelshadows_p.h" #include "view.h" +#include "settings/primaryconfigview.h" #include "../../liblatte2/types.h" // Qt @@ -50,6 +51,7 @@ void Effects::init() connect(this, &Effects::backgroundOpacityChanged, this, &Effects::updateEffects); connect(this, &Effects::drawEffectsChanged, this, &Effects::updateEffects); connect(this, &Effects::rectChanged, this, &Effects::updateEffects); + connect(this, &Effects::settingsMaskSubtractedChanged, this, &Effects::updateMask); connect(this, &Effects::drawShadowsChanged, this, [&]() { if (m_view->behaveAsPlasmaPanel()) { @@ -60,6 +62,7 @@ void Effects::init() connect(m_view, &Latte::View::alignmentChanged, this, &Effects::updateEnabledBorders); connect(m_view, &Latte::View::behaveAsPlasmaPanelChanged, this, &Effects::updateEffects); connect(m_view, &Latte::View::behaveAsPlasmaPanelChanged, this, &Effects::updateShadows); + connect(m_view, &Latte::View::configWindowGeometryChanged, this, &Effects::updateMask); connect(this, SIGNAL(innerShadowChanged()), m_view->corona(), SIGNAL(availableScreenRectChanged())); } @@ -161,6 +164,76 @@ void Effects::setInnerShadow(int shadow) emit innerShadowChanged(); } +bool Effects::settingsMaskSubtracted() const +{ + return m_settingsMaskSubtracted; +} + +void Effects::setSettingsMaskSubtracted(bool enabled) +{ + if (m_settingsMaskSubtracted == enabled) { + return; + } + + m_settingsMaskSubtracted = enabled; + emit settingsMaskSubtractedChanged(); +} + +QRegion Effects::subtrackedMaskFromWindow(QRegion initialRegion, QQuickView *window) +{ + QRegion subtractedMask = initialRegion; + + if (m_settingsMaskSubtracted && window) { + QRect windowMask; + //! we need to subtrack the mask areas that overlap with underlying window + switch (m_view->location()) { + case Plasma::Types::TopEdge: + windowMask.setTopLeft(QPoint(window->x() - m_view->x(), m_mask.y() - m_innerShadow)); + windowMask.setSize(QSize(window->width(), m_innerShadow)); + break; + + case Plasma::Types::LeftEdge: + windowMask.setTopLeft(QPoint(m_mask.right() - m_innerShadow, window->y() - m_view->y())); + windowMask.setSize(QSize(m_innerShadow, window->height())); + break; + + case Plasma::Types::RightEdge: + windowMask.setTopLeft(QPoint(m_mask.x(), window->y() - m_view->y())); + windowMask.setSize(QSize(m_innerShadow, window->height())); + break; + + case Plasma::Types::BottomEdge: + windowMask.setTopLeft(QPoint(window->x() - m_view->x(), m_mask.y())); + windowMask.setSize(QSize(window->width(), m_innerShadow)); + break; + + default: + break; + } + + subtractedMask = subtractedMask.subtracted(windowMask); + } + + return subtractedMask; +} + +QRegion Effects::subtractedMask() +{ + QRegion subMask = m_mask; + + if (m_settingsMaskSubtracted && m_view->configView()) { + subMask = subtrackedMaskFromWindow(subMask, m_view->configView()); + + ViewPart::PrimaryConfigView *primaryConfig = qobject_cast(m_view->configView()); + + if (primaryConfig && primaryConfig->secondaryWindow()) { + subMask = subtrackedMaskFromWindow(subMask, primaryConfig->secondaryWindow()); + } + } + + return subMask; +} + QRect Effects::rect() const { return m_rect; @@ -198,12 +271,19 @@ void Effects::setMask(QRect area) return; m_mask = area; + updateMask(); + // qDebug() << "dock mask set:" << m_mask; + emit maskChanged(); +} + +void Effects::updateMask() +{ if (KWindowSystem::compositingActive()) { if (m_view->behaveAsPlasmaPanel()) { m_view->setMask(QRect()); } else { - m_view->setMask(m_mask); + m_view->setMask(subtractedMask()); } } else { //! this is used when compositing is disabled and provides @@ -220,7 +300,7 @@ void Effects::setMask(QRect area) } m_background->setEnabledBorders(m_enabledBorders); - m_background->resizeFrame(area.size()); + m_background->resizeFrame(m_mask.size()); QRegion fixedMask = m_background->mask(); fixedMask.translate(m_mask.x(), m_mask.y()); @@ -231,9 +311,6 @@ void Effects::setMask(QRect area) m_view->setMask(fixedMask); } - - // qDebug() << "dock mask set:" << m_mask; - emit maskChanged(); } void Effects::clearShadows() diff --git a/app/view/effects.h b/app/view/effects.h index e67e6c927..43496e15d 100644 --- a/app/view/effects.h +++ b/app/view/effects.h @@ -23,6 +23,7 @@ // Qt #include #include +#include #include // Plasma @@ -42,6 +43,7 @@ class Effects: public QObject Q_PROPERTY(bool animationsBlocked READ animationsBlocked NOTIFY animationsBlockedChanged) Q_PROPERTY(bool drawShadows READ drawShadows WRITE setDrawShadows NOTIFY drawShadowsChanged) Q_PROPERTY(bool drawEffects READ drawEffects WRITE setDrawEffects NOTIFY drawEffectsChanged) + Q_PROPERTY(bool settingsMaskSubtracted READ settingsMaskSubtracted WRITE setSettingsMaskSubtracted NOTIFY settingsMaskSubtractedChanged) //! thickness shadow size when is drawn inside the window from qml Q_PROPERTY(int backgroundOpacity READ backgroundOpacity WRITE setBackgroundOpacity NOTIFY backgroundOpacityChanged) @@ -68,6 +70,9 @@ public: bool forceDrawCenteredBorders() const; void setForceDrawCenteredBorders(bool draw); + bool settingsMaskSubtracted() const; + void setSettingsMaskSubtracted(bool enabled); + int backgroundOpacity() const; void setBackgroundOpacity(int opacity); @@ -97,15 +102,22 @@ signals: void maskChanged(); void innerShadowChanged(); void rectChanged(); + void settingsMaskSubtractedChanged(); private slots: void init(); + void updateMask(); + +private: + QRegion subtractedMask(); + QRegion subtrackedMaskFromWindow(QRegion initialRegion, QQuickView *window); private: bool m_animationsBlocked{false}; bool m_drawShadows{true}; bool m_drawEffects{false}; bool m_forceDrawCenteredBorders{false}; + bool m_settingsMaskSubtracted{false}; int m_backgroundOpacity{100}; int m_innerShadow{0}; diff --git a/app/view/settings/primaryconfigview.cpp b/app/view/settings/primaryconfigview.cpp index 0c70abfa7..f3f417948 100644 --- a/app/view/settings/primaryconfigview.cpp +++ b/app/view/settings/primaryconfigview.cpp @@ -155,7 +155,7 @@ inline Qt::WindowFlags PrimaryConfigView::wFlags() const return (flags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint) & ~Qt::WindowDoesNotAcceptFocus; } -QWindow *PrimaryConfigView::secondaryWindow() +QQuickView *PrimaryConfigView::secondaryWindow() { return m_secConfigView; } @@ -246,7 +246,9 @@ void PrimaryConfigView::syncGeometry() } updateShowInlineProperties(); + m_latteView->raise(); + emit m_latteView->configWindowGeometryChanged(); } void PrimaryConfigView::syncSlideEffect() diff --git a/app/view/settings/primaryconfigview.h b/app/view/settings/primaryconfigview.h index cda8044de..bb9225af3 100644 --- a/app/view/settings/primaryconfigview.h +++ b/app/view/settings/primaryconfigview.h @@ -96,7 +96,7 @@ public: Plasma::FrameSvg::EnabledBorders enabledBorders() const; - QWindow *secondaryWindow(); + QQuickView *secondaryWindow(); public slots: Q_INVOKABLE void hideConfigWindow(); diff --git a/app/view/view.cpp b/app/view/view.cpp index 6ca6b7d40..4b9b21200 100644 --- a/app/view/view.cpp +++ b/app/view/view.cpp @@ -323,6 +323,11 @@ void View::showSettingsWindow() } } +PlasmaQuick::ConfigView *View::configView() +{ + return m_configView; +} + void View::showConfigurationInterface(Plasma::Applet *applet) { if (!applet || !applet->containment()) diff --git a/app/view/view.h b/app/view/view.h index 6dd489456..e5713da6e 100644 --- a/app/view/view.h +++ b/app/view/view.h @@ -170,6 +170,8 @@ public: bool settingsWindowIsShown(); void showSettingsWindow(); + PlasmaQuick::ConfigView *configView(); + ViewPart::Effects *effects() const; ViewPart::Positioner *positioner() const; ViewPart::VisibilityManager *visibility() const; @@ -226,6 +228,7 @@ signals: void alignmentChanged(); void behaveAsPlasmaPanelChanged(); void byPassWMChanged(); + void configWindowGeometryChanged(); // is called from config windows void contextMenuIsShownChanged(); void dockLocationChanged(); void editThicknessChanged(); diff --git a/containment/package/contents/ui/VisibilityManager.qml b/containment/package/contents/ui/VisibilityManager.qml index 8ab1a5df7..15b96701d 100644 --- a/containment/package/contents/ui/VisibilityManager.qml +++ b/containment/package/contents/ui/VisibilityManager.qml @@ -183,6 +183,21 @@ Item{ } } + Binding{ + target: latteView && latteView.effects ? latteView.effects : null + property: "settingsMaskSubtracted" + when: latteView && latteView.effects + value: { + if (Latte.WindowSystem.compositingActive + && editModeVisual.editAnimationEnded + && !root.isHovered) { + return true; + } else { + return false; + } + } + } + Binding{ target: latteView && latteView.windowsTracker ? latteView.windowsTracker : null property: "enabled" diff --git a/containment/package/contents/ui/main.qml b/containment/package/contents/ui/main.qml index c9a1c82a3..91c3fcaf3 100644 --- a/containment/package/contents/ui/main.qml +++ b/containment/package/contents/ui/main.qml @@ -153,7 +153,7 @@ DragDrop.DropArea { property bool isHorizontal: plasmoid.formFactor === PlasmaCore.Types.Horizontal property bool isReady: !(dockIsHidden || inSlidingIn || inSlidingOut) property bool isVertical: !isHorizontal - property bool isHovered: latteApplet ? ((latteAppletHoveredIndex !== -1) && (layoutsContainer.hoveredIndex !== -1)) //|| wholeArea.containsMouse + property bool isHovered: latteApplet ? ((latteAppletHoveredIndex !== -1) || (layoutsContainer.hoveredIndex !== -1)) //|| wholeArea.containsMouse : (layoutsContainer.hoveredIndex !== -1) //|| wholeArea.containsMouse property bool mouseWheelActions: plasmoid.configuration.mouseWheelActions property bool normalState : false