From 746f32050d334dee92f18a31e18d2880926eadd1 Mon Sep 17 00:00:00 2001 From: Michail Vourlakos Date: Thu, 24 Dec 2020 19:27:11 +0200 Subject: [PATCH] adjust mouse events relevant to view paddings --- app/view/positioner.cpp | 5 + app/view/positioner.h | 2 + app/view/view.cpp | 168 ++++++++++++++++-- app/view/view.h | 3 + .../package/contents/ui/VisibilityManager.qml | 30 ++++ 5 files changed, 192 insertions(+), 16 deletions(-) diff --git a/app/view/positioner.cpp b/app/view/positioner.cpp index e20f05c26..3363974d1 100644 --- a/app/view/positioner.cpp +++ b/app/view/positioner.cpp @@ -988,6 +988,11 @@ void Positioner::setInSlideAnimation(bool active) emit inSlideAnimationChanged(); } +bool Positioner::isCursorInsideView() const +{ + return m_view->geometry().contains(QCursor::pos(m_screenToFollow)); +} + bool Positioner::isStickedOnTopEdge() const { return m_isStickedOnTopEdge; diff --git a/app/view/positioner.h b/app/view/positioner.h index 7958cdb7b..d0f2ee983 100644 --- a/app/view/positioner.h +++ b/app/view/positioner.h @@ -75,6 +75,8 @@ public: bool inSlideAnimation() const; void setInSlideAnimation(bool active); + bool isCursorInsideView() const; + bool isStickedOnTopEdge() const; void setIsStickedOnTopEdge(bool sticked); diff --git a/app/view/view.cpp b/app/view/view.cpp index 4ee84bfb2..31920d64e 100644 --- a/app/view/view.cpp +++ b/app/view/view.cpp @@ -43,6 +43,9 @@ // Qt #include +#include +#include +#include #include #include #include @@ -356,9 +359,9 @@ void View::init(Plasma::Containment *plasma_containment) void View::reloadSource() { if (m_layout && containment()) { - // if (settingsWindowIsShown()) { - // m_configView->deleteLater(); - // } + // if (settingsWindowIsShown()) { + // m_configView->deleteLater(); + // } engine()->clearComponentCache(); m_layout->recreateView(containment(), settingsWindowIsShown()); @@ -513,7 +516,7 @@ void View::showConfigurationInterface(Plasma::Applet *applet) if (c && containment() && c->isContainment() && c->id() == containment()->id()) { m_primaryConfigView = m_corona->viewSettingsFactory()->primaryConfigView(this); applyActivitiesToWindows(); - } else { + } else { m_appletConfigView = new PlasmaQuick::ConfigView(applet); m_appletConfigView.data()->init(); m_appletConfigView->show(); @@ -1349,26 +1352,111 @@ bool View::event(QEvent *e) case QEvent::DragEnter: setContainsDrag(true); + + if (auto de = static_cast(e)) { + //! adjust event by taking into account paddings + if (m_padding && !m_padding->isEmpty() && !containmentContainsPosition(de->pos())) { + auto de2 = new QDragEnterEvent(positionAdjustedForContainment(de->pos()).toPoint(), + de->possibleActions(), de->mimeData(), de->mouseButtons(), de->keyboardModifiers()); + + QCoreApplication::postEvent(this, de2); + return true; + } + } break; case QEvent::DragLeave: - case QEvent::Drop: setContainsDrag(false); break; + case QEvent::DragMove: + if (auto de = static_cast(e)) { + //! adjust event by taking into account paddings + if (m_padding && !m_padding->isEmpty() && !containmentContainsPosition(de->pos())) { + auto de2 = new QDragMoveEvent(positionAdjustedForContainment(de->pos()).toPoint(), + de->possibleActions(), de->mimeData(), de->mouseButtons(), de->keyboardModifiers()); + + QCoreApplication::postEvent(this, de2); + return true; + } + } + break; + + case QEvent::Drop: + setContainsDrag(false); + + if (auto de = static_cast(e)) { + //! adjust event by taking into account paddings + if (m_padding && !m_padding->isEmpty() && !containmentContainsPosition(de->pos())) { + auto de2 = new QDropEvent(positionAdjustedForContainment(de->pos()).toPoint(), + de->possibleActions(), de->mimeData(), de->mouseButtons(), de->keyboardModifiers()); + + QCoreApplication::postEvent(this, de2); + return true; + } + } + + break; + + case QEvent::MouseMove: + if (auto me = dynamic_cast(e)) { + + //! adjust event by taking into account paddings + if (m_padding && !m_padding->isEmpty() + && m_positioner && m_positioner->isCursorInsideView() /*dont break drags when cursor is outside*/ + && !containmentContainsPosition(me->windowPos())) { + auto me2 = new QMouseEvent(me->type(), + positionAdjustedForContainment(me->windowPos()), + positionAdjustedForContainment(me->windowPos()), + positionAdjustedForContainment(me->windowPos()) + position(), + me->button(), me->buttons(), me->modifiers()); + + QCoreApplication::postEvent(this, me2); + return true; + } + } + break; + case QEvent::MouseButtonPress: - if (auto mouseEvent = dynamic_cast(e)) { - emit mousePressed(mouseEvent->pos(), mouseEvent->button()); + if (auto me = dynamic_cast(e)) { + emit mousePressed(me->pos(), me->button()); + + //! adjust event by taking into account paddings + if (m_padding && !m_padding->isEmpty() + && m_positioner && m_positioner->isCursorInsideView() /*dont break drags when cursor is outside*/ + && !containmentContainsPosition(me->windowPos())) { + auto me2 = new QMouseEvent(me->type(), + positionAdjustedForContainment(me->windowPos()), + positionAdjustedForContainment(me->windowPos()), + positionAdjustedForContainment(me->windowPos()) + position(), + me->button(), me->buttons(), me->modifiers()); + + QCoreApplication::postEvent(this, me2); + return true; + } } break; + case QEvent::MouseButtonRelease: - if (auto mouseEvent = dynamic_cast(e)) { - emit mouseReleased(mouseEvent->pos(), mouseEvent->button()); + if (auto me = dynamic_cast(e)) { + emit mouseReleased(me->pos(), me->button()); + + //! adjust event by taking into account paddings + if (m_padding && !m_padding->isEmpty() + && m_positioner && m_positioner->isCursorInsideView() /*dont break drags when cursor is outside*/ + && !containmentContainsPosition(me->windowPos())) { + auto me2 = new QMouseEvent(me->type(), + positionAdjustedForContainment(me->windowPos()), + positionAdjustedForContainment(me->windowPos()), + positionAdjustedForContainment(me->windowPos()) + position(), + me->button(), me->buttons(), me->modifiers()); + + QCoreApplication::postEvent(this, me2); + return true; + } } break; - /* case QEvent::DragMove: - qDebug() << "DRAG MOVING>>>>>>"; - break;*/ + case QEvent::PlatformSurface: if (auto pe = dynamic_cast(e)) { switch (pe->surfaceEventType()) { @@ -1404,13 +1492,24 @@ bool View::event(QEvent *e) break; case QEvent::Wheel: - if (auto wheelEvent = dynamic_cast(e)) { + if (auto we = dynamic_cast(e)) { #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) - QPoint position = QPoint(wheelEvent->x(), wheelEvent->y()); + QPoint pos = QPoint(we->x(), we->y()); #else - QPoint position = wheelEvent->position().toPoint(); + QPoint pos = we->position().toPoint(); #endif - emit wheelScrolled(position, wheelEvent->angleDelta(), wheelEvent->buttons()); + emit wheelScrolled(pos, we->angleDelta(), we->buttons()); + + //! adjust event by taking into account paddings + if (m_padding && !m_padding->isEmpty() && !containmentContainsPosition(pos)) { + auto we2 = new QWheelEvent(positionAdjustedForContainment(pos), + positionAdjustedForContainment(pos) + position(), + we->pixelDelta(), we->angleDelta(), we->angleDelta().y(), + we->orientation(), we->buttons(), we->modifiers(), we->phase()); + + QCoreApplication::postEvent(this, we2); + return true; + } } break; default: @@ -1421,6 +1520,43 @@ bool View::event(QEvent *e) return ContainmentView::event(e); } +bool View::containmentContainsPosition(const QPointF &point) const +{ + if (!m_padding) { + return false; + } + + QQuickItem *containmentItem = containment()->property("_plasma_graphicObject").value(); + + if (!containmentItem) { + return false; + } + + return QRectF( + containmentItem->mapToScene(QPoint(m_padding->left(),m_padding->top())), + QSizeF(containmentItem->width()-m_padding->left()-m_padding->right(), + containmentItem->height()-m_padding->top()-m_padding->bottom())).contains(point); +} + +QPointF View::positionAdjustedForContainment(const QPointF &point) const +{ + if (!m_padding) { + return point; + } + + QQuickItem *containmentItem = containment()->property("_plasma_graphicObject").value(); + + if (!containmentItem) { + return point; + } + + QRectF containmentRect(containmentItem->mapToScene(QPoint(0,0)), QSizeF(containmentItem->width(), containmentItem->height())); + + return QPointF(qBound(containmentRect.left() + m_padding->left(), point.x(), containmentRect.right() - m_padding->right()), + qBound(containmentRect.top() + m_padding->top(), point.y(), containmentRect.bottom() - m_padding->bottom())); +} + + void View::releaseConfigView() { m_primaryConfigView = nullptr; diff --git a/app/view/view.h b/app/view/view.h index feca47a91..43daa131b 100644 --- a/app/view/view.h +++ b/app/view/view.h @@ -374,6 +374,9 @@ private: void setContainsDrag(bool contains); + bool containmentContainsPosition(const QPointF &point) const; + QPointF positionAdjustedForContainment(const QPointF &point) const; + private: Plasma::Containment *containmentById(uint id); diff --git a/containment/package/contents/ui/VisibilityManager.qml b/containment/package/contents/ui/VisibilityManager.qml index 00b9084d6..a5d65bd1a 100644 --- a/containment/package/contents/ui/VisibilityManager.qml +++ b/containment/package/contents/ui/VisibilityManager.qml @@ -214,6 +214,36 @@ Item{ value: colorizerManager } + + //! View Paddings + Binding{ + target: latteView.padding + property: "top" + when: latteView + value: plasmoid.location === PlasmaCore.Types.TopEdge ? metrics.margin.screenEdge : 0 + } + + Binding{ + target: latteView.padding + property: "bottom" + when: latteView + value: plasmoid.location === PlasmaCore.Types.BottomEdge ? metrics.margin.screenEdge : 0 + } + + Binding{ + target: latteView.padding + property: "left" + when: latteView + value: plasmoid.location === PlasmaCore.Types.LeftEdge ? metrics.margin.screenEdge : 0 + } + + Binding{ + target: latteView.padding + property: "right" + when: latteView + value: plasmoid.location === PlasmaCore.Types.RightEdge ? metrics.margin.screenEdge : 0 + } + //! View::Effects bindings Binding{ target: latteView && latteView.effects ? latteView.effects : null