From d3538eeec3154b8660093812455b2def4b6d6ca5 Mon Sep 17 00:00:00 2001 From: Michail Vourlakos Date: Sun, 22 May 2022 20:30:14 +0300 Subject: [PATCH] view:remove viewpart contextmenu class --- app/view/CMakeLists.txt | 1 - app/view/contextmenu.cpp | 605 ------------------------- app/view/contextmenu.h | 81 ---- app/view/settings/canvasconfigview.cpp | 1 - 4 files changed, 688 deletions(-) delete mode 100644 app/view/contextmenu.cpp delete mode 100644 app/view/contextmenu.h diff --git a/app/view/CMakeLists.txt b/app/view/CMakeLists.txt index 8b786c0e5..d37a7360f 100644 --- a/app/view/CMakeLists.txt +++ b/app/view/CMakeLists.txt @@ -2,7 +2,6 @@ set(lattedock-app_SRCS ${lattedock-app_SRCS} ${CMAKE_CURRENT_SOURCE_DIR}/clonedview.cpp ${CMAKE_CURRENT_SOURCE_DIR}/containmentinterface.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/contextmenu.cpp ${CMAKE_CURRENT_SOURCE_DIR}/effects.cpp ${CMAKE_CURRENT_SOURCE_DIR}/eventssink.cpp ${CMAKE_CURRENT_SOURCE_DIR}/panelshadows.cpp diff --git a/app/view/contextmenu.cpp b/app/view/contextmenu.cpp deleted file mode 100644 index 216783750..000000000 --- a/app/view/contextmenu.cpp +++ /dev/null @@ -1,605 +0,0 @@ -/* - SPDX-FileCopyrightText: 2018 Michail Vourlakos - SPDX-License-Identifier: GPL-2.0-or-later -*/ - -#include "contextmenu.h" - -// local -#include "view.h" -#include "visibilitymanager.h" -#include "../lattecorona.h" -#include "../layouts/storage.h" - -// Qt -#include -#include -#include - -// KDE -#include -#include -#include -#include - -// Plasma -#include -#include -#include -#include -#include - -#define BLOCKHIDINGTYPE "View::contextMenu()" - -namespace Latte { -namespace ViewPart { - -ContextMenu::ContextMenu(Latte::View *view) : - QObject(view), - m_latteView(view) -{ -} - -ContextMenu::~ContextMenu() -{ -} - -QMenu *ContextMenu::menu() -{ - return m_contextMenu; -} - -void ContextMenu::onMenuAboutToHide() -{ - if (!m_latteView) { - return; - } - - m_latteView->containment()->setStatus(m_lastContainmentStatus); - m_contextMenu = 0; - - emit menuChanged(); -} - -QPoint ContextMenu::popUpRelevantToParent(const QRect &parentItem, const QRect popUpRect) -{ - QPoint resultPoint; - - if (m_latteView->location() == Plasma::Types::TopEdge) { - resultPoint.setX(parentItem.left()); - resultPoint.setY(parentItem.bottom()); - } else if (m_latteView->location() == Plasma::Types::BottomEdge) { - resultPoint.setX(parentItem.left()); - resultPoint.setY(parentItem.top() - popUpRect.height() - 1); - } else if (m_latteView->location() == Plasma::Types::LeftEdge) { - resultPoint.setX(parentItem.right()); - resultPoint.setY(parentItem.top()); - } else if (m_latteView->location() == Plasma::Types::RightEdge) { - resultPoint.setX(parentItem.left() - popUpRect.width()); - resultPoint.setY(parentItem.top()); - } - - return resultPoint; -} - -QPoint ContextMenu::popUpRelevantToGlobalPoint(const QRect &parentItem, const QRect popUpRect) -{ - QPoint resultPoint; - - if (m_latteView->location() == Plasma::Types::TopEdge) { - resultPoint.setX(popUpRect.x()); - resultPoint.setY(popUpRect.y() + 1); - } else if (m_latteView->location() == Plasma::Types::BottomEdge) { - resultPoint.setX(popUpRect.x()); - resultPoint.setY(popUpRect.y() - popUpRect.height() - 1); - } else if (m_latteView->location() == Plasma::Types::LeftEdge) { - resultPoint.setX(popUpRect.x() + 1); - resultPoint.setY(popUpRect.y()); - } else if (m_latteView->location() == Plasma::Types::RightEdge) { - resultPoint.setX(popUpRect.x() - popUpRect.width() - 1); - resultPoint.setY(popUpRect.y()); - } - - return resultPoint; -} - -QPoint ContextMenu::popUpTopLeft(Plasma::Applet *applet, const QRect popUpRect) -{ - PlasmaQuick::AppletQuickItem *ai = applet->property("_plasma_graphicObject").value(); - - QRect globalItemRect = m_latteView->absoluteGeometry(); - - if (ai && applet != m_latteView->containment()) { - QPointF appletGlobalTopLeft = ai->mapToGlobal(QPointF(ai->x(), ai->y())); - globalItemRect = QRect(appletGlobalTopLeft.x(), appletGlobalTopLeft.y(), ai->width(), ai->height()); - } - - int itemLength = (m_latteView->formFactor() == Plasma::Types::Horizontal ? globalItemRect.width() : globalItemRect.height()); - int menuLength = (m_latteView->formFactor() == Plasma::Types::Horizontal ? popUpRect.width() : popUpRect.height()); - - if ((itemLength > menuLength) - || (applet == m_latteView->containment()) - || (m_latteView && Layouts::Storage::self()->isSubContainment(m_latteView->corona(), applet)) ) { - return popUpRelevantToGlobalPoint(globalItemRect, popUpRect); - } else { - return popUpRelevantToParent(globalItemRect, popUpRect); - } -} - -bool ContextMenu::mousePressEventForContainmentMenu(QQuickView *view, QMouseEvent *event) -{ - if (!event || !view || !m_latteView->containment()) { - return false; - } - - if (m_contextMenu) { - m_contextMenu->close(); - m_contextMenu = 0; - return false; - } - - QString trigger = Plasma::ContainmentActions::eventToString(event); - - if (trigger == QLatin1String("RightButton;NoModifier")) { - Plasma::ContainmentActions *plugin = m_latteView->containment()->containmentActions().value(trigger); - - if (!plugin || plugin->contextualActions().isEmpty()) { - event->setAccepted(false); - return false; - } - - if (m_latteView->containment()) { - QMenu *desktopMenu = new QMenu; - desktopMenu->setAttribute(Qt::WA_TranslucentBackground); - - if (desktopMenu->winId()) { - desktopMenu->windowHandle()->setTransientParent(m_latteView); - } - - desktopMenu->windowHandle()->setTransientParent(m_latteView); - - desktopMenu->setAttribute(Qt::WA_DeleteOnClose); - m_contextMenu = desktopMenu; - emit menuChanged(); - - auto ungrabMouseHack = [this]() { - if (m_latteView->mouseGrabberItem()) { - m_latteView->mouseGrabberItem()->ungrabMouse(); - } - }; - - QTimer::singleShot(0, this, ungrabMouseHack); - - emit m_latteView->containment()->contextualActionsAboutToShow(); - addContainmentActions(desktopMenu, event); - - desktopMenu->setAttribute(Qt::WA_TranslucentBackground); - - QPoint globalPos = event->globalPos(); - desktopMenu->adjustSize(); - - QRect popUpRect(globalPos.x(), globalPos.y(), desktopMenu->width(), desktopMenu->height()); - - globalPos = popUpRelevantToGlobalPoint(QRect(0,0,0,0), popUpRect); - - if (desktopMenu->isEmpty()) { - delete desktopMenu; - event->accept(); - return false; - } - - m_lastContainmentStatus = m_latteView->containment()->status(); - m_latteView->containment()->setStatus(Plasma::Types::RequiresAttentionStatus); - - connect(desktopMenu, SIGNAL(aboutToHide()), this, SLOT(onMenuAboutToHide())); - - for (auto action : desktopMenu->actions()) { - if (action->menu()) { - connect(action->menu(), &QMenu::aboutToShow, desktopMenu, [action, desktopMenu] { - if (action->menu()->windowHandle()) { - // Need to add the transient parent otherwise Qt will create a new toplevel - action->menu()->windowHandle()->setTransientParent(desktopMenu->windowHandle()); - } - }); - } - } - - desktopMenu->popup(globalPos); - event->setAccepted(true); - return false; - } - } - - return true; -} - - -bool ContextMenu::mousePressEvent(QMouseEvent *event) -{ - //qDebug() << "Step -1 ..."; - - if (!event || !m_latteView->containment()) { - return false; - } - - //qDebug() << "Step 0..."; - - //even if the menu is executed synchronously, other events may be processed - //by the qml incubator when plasma is loading, so we need to guard there - if (m_contextMenu) { - //qDebug() << "Step 0.5 ..."; - m_contextMenu->close(); - m_contextMenu = 0; - return false; - } - - //qDebug() << "1 ..."; - const QString trigger = Plasma::ContainmentActions::eventToString(event); - Plasma::ContainmentActions *plugin = m_latteView->containment()->containmentActions().value(trigger); - - if (!plugin || plugin->contextualActions().isEmpty()) { - event->setAccepted(false); - return false; - } - - // the plugin can be a single action or a context menu - // Don't have an action list? execute as single action - // and set the event position as action data - if (plugin->contextualActions().length() == 1) { - QAction *action = plugin->contextualActions().at(0); - action->setData(event->pos()); - action->trigger(); - event->accept(); - return false; - } - - //qDebug() << "2 ..."; - //the plugin can be a single action or a context menu - //Don't have an action list? execute as single action - //and set the event position as action data - /*if (plugin->contextualActions().length() == 1) { - QAction *action = plugin->contextualActions().at(0); - action->setData(event->pos()); - action->trigger(); - event->accept(); - return; - }*/ - //FIXME: very inefficient appletAt() implementation - Plasma::Applet *applet = 0; - bool inSystray = false; - - //! initialize the appletContainsMethod on the first right click - if (!m_appletContainsMethod.isValid()) { - updateAppletContainsMethod(); - } - - for (const Plasma::Applet *appletTemp : m_latteView->containment()->applets()) { - PlasmaQuick::AppletQuickItem *ai = appletTemp->property("_plasma_graphicObject").value(); - - bool appletContainsMouse = false; - - if (m_appletContainsMethod.isValid()) { - QVariant retVal; - m_appletContainsMethod.invoke(m_appletContainsMethodItem, Qt::DirectConnection, Q_RETURN_ARG(QVariant, retVal) - , Q_ARG(QVariant, appletTemp->id()), Q_ARG(QVariant, event->pos())); - appletContainsMouse = retVal.toBool(); - } else { - appletContainsMouse = ai->contains(ai->mapFromItem(m_latteView->contentItem(), event->pos())); - } - - if (ai && ai->isVisible() && appletContainsMouse) { - applet = ai->applet(); - - if (m_latteView && Layouts::Storage::self()->isSubContainment(m_latteView->corona(), applet)) { - Plasma::Containment *subContainment = Layouts::Storage::self()->subContainmentOf(m_latteView->corona(), applet); - - if (subContainment) { - Plasma::Applet *internalApplet{nullptr}; - - for (const Plasma::Applet *appletCont : subContainment->applets()) { - PlasmaQuick::AppletQuickItem *ai2 = appletCont->property("_plasma_graphicObject").value(); - - if (ai2 && ai2->isVisible() && ai2->contains(ai2->mapFromItem(m_latteView->contentItem(), event->pos()))) { - internalApplet = ai2->applet(); - break; - } - } - - if (!internalApplet) { - return true; - } else { - applet = internalApplet; - } - } - - break; - } else { - ai = 0; - } - } - } - - if (!applet && !inSystray) { - applet = m_latteView->containment(); - } - - //qDebug() << "3 ..."; - - if (applet) { - //qDebug() << "4..."; - QMenu *desktopMenu = new QMenu; - - //this is a workaround where Qt now creates the menu widget - //in .exec before oxygen can polish it and set the following attribute - desktopMenu->setAttribute(Qt::WA_TranslucentBackground); - //end workaround - - if (desktopMenu->winId()) { - desktopMenu->windowHandle()->setTransientParent(m_latteView); - } - desktopMenu->windowHandle()->setTransientParent(m_latteView); - - desktopMenu->setAttribute(Qt::WA_DeleteOnClose); - m_contextMenu = desktopMenu; - emit menuChanged(); - - //! deprecated old code that can be removed if the following plasma approach doesn't - //! create any issues with context menu creation in Latte - /*if (m_latteView->mouseGrabberItem()) { - //workaround, this fixes for me most of the right click menu behavior - m_latteView->mouseGrabberItem()->ungrabMouse(); - return; - }*/ - - //!plasma official code - //this is a workaround where Qt will fail to realize a mouse has been released - - // this happens if a window which does not accept focus spawns a new window that takes focus and X grab - // whilst the mouse is depressed - // https://bugreports.qt.io/browse/QTBUG-59044 - // this causes the next click to go missing - - //by releasing manually we avoid that situation - auto ungrabMouseHack = [this]() { - if (m_latteView->mouseGrabberItem()) { - m_latteView->mouseGrabberItem()->ungrabMouse(); - } - }; - - //post 5.8.0 QQuickWindow code is sendEvent(item, mouseEvent); item->grabMouse() - QTimer::singleShot(0, this, ungrabMouseHack); - - //end workaround - //!end of plasma official code(workaround) - - //qDebug() << "5 ..."; - - if (applet && applet != m_latteView->containment()) { - //qDebug() << "5.3 ..."; - emit applet->contextualActionsAboutToShow(); - addAppletActions(desktopMenu, applet, event); - } else { - //qDebug() << "5.6 ..."; - emit m_latteView->containment()->contextualActionsAboutToShow(); - addContainmentActions(desktopMenu, event); - } - - //this is a workaround where Qt now creates the menu widget - //in .exec before oxygen can polish it and set the following attribute - desktopMenu->setAttribute(Qt::WA_TranslucentBackground); - //end workaround - QPoint globalPos = event->globalPos(); - desktopMenu->adjustSize(); - - QRect popUpRect(globalPos.x(), globalPos.y(), desktopMenu->width(), desktopMenu->height()); - - if (applet) { - globalPos = popUpTopLeft(applet, popUpRect); - } else { - globalPos = popUpRelevantToGlobalPoint(QRect(0,0,0,0), popUpRect); - } - - //qDebug() << "7..."; - - if (desktopMenu->isEmpty()) { - //qDebug() << "7.5 ..."; - delete desktopMenu; - event->accept(); - return true; - } - - connect(desktopMenu, SIGNAL(aboutToHide()), this, SLOT(onMenuAboutToHide())); - - for (auto action : desktopMenu->actions()) { - if (action->menu()) { - connect(action->menu(), &QMenu::aboutToShow, desktopMenu, [action, desktopMenu] { - if (action->menu()->windowHandle()) { - // Need to add the transient parent otherwise Qt will create a new toplevel - action->menu()->windowHandle()->setTransientParent(desktopMenu->windowHandle()); - } - }); - } - } - - desktopMenu->popup(globalPos); - event->setAccepted(true); - return false; - //qDebug() << "8 ..."; - } - - //qDebug() << "10 ..."; - return true; -} - -//! update the appletContainsPos method from Panel view -void ContextMenu::updateAppletContainsMethod() -{ - for (QQuickItem *item : m_latteView->contentItem()->childItems()) { - if (auto *metaObject = item->metaObject()) { - // not using QMetaObject::invokeMethod to avoid warnings when calling - // this on applets that don't have it or other child items since this - // is pretty much trial and error. - // Also, "var" arguments are treated as QVariant in QMetaObject - - int methodIndex = metaObject->indexOfMethod("appletContainsPos(QVariant,QVariant)"); - - if (methodIndex == -1) { - continue; - } - - m_appletContainsMethod = metaObject->method(methodIndex); - m_appletContainsMethodItem = item; - } - } -} - -void ContextMenu::addAppletActions(QMenu *desktopMenu, Plasma::Applet *applet, QEvent *event) -{ - if (!m_latteView->containment()) { - return; - } - - desktopMenu->addSection(applet->pluginMetaData().name()); - - for (QAction *action : applet->contextualActions()) { - if (action) { - desktopMenu->addAction(action); - } - } - - if (!applet->failedToLaunch()) { - QAction *runAssociatedApplication = applet->actions()->action(QStringLiteral("run associated application")); - - if (runAssociatedApplication && runAssociatedApplication->isEnabled()) { - desktopMenu->addAction(runAssociatedApplication); - } - - QAction *configureApplet = applet->actions()->action(QStringLiteral("configure")); - - if (configureApplet && configureApplet->isEnabled()) { - desktopMenu->addAction(configureApplet); - } - - QAction *appletAlternatives = applet->actions()->action(QStringLiteral("alternatives")); - - if (appletAlternatives && appletAlternatives->isEnabled() && m_latteView->containment()->isUserConfiguring()) { - desktopMenu->addAction(appletAlternatives); - } - } - - QAction *containmentAction = desktopMenu->menuAction(); - containmentAction->setText(i18nc("%1 is the name of the containment", "%1 Options", m_latteView->containment()->title())); - - if (desktopMenu->actions().count()>1) { /*take into account the Applet Name Section*/ - addContainmentActions(containmentAction->menu(), event); - } - - if (!containmentAction->menu()->isEmpty()) { - int enabled = 0; - //count number of real actions - QListIterator actionsIt(containmentAction->menu()->actions()); - - while (enabled < 3 && actionsIt.hasNext()) { - QAction *action = actionsIt.next(); - - if (action->isVisible() && !action->isSeparator()) { - ++enabled; - } - } - - desktopMenu->addSeparator(); - - if (enabled) { - //if there is only one, don't create a submenu - // if (enabled < 2) { - for (QAction *action : containmentAction->menu()->actions()) { - if (action && action->isVisible()) { - desktopMenu->addAction(action); - } - } - - // } else { - // desktopMenu->addMenu(containmentMenu); - // } - } - } - - if (m_latteView->containment()->immutability() == Plasma::Types::Mutable && - (m_latteView->containment()->containmentType() != Plasma::Types::PanelContainment || m_latteView->containment()->isUserConfiguring())) { - QAction *closeApplet = applet->actions()->action(QStringLiteral("remove")); - - //qDebug() << "checking for removal" << closeApplet; - if (closeApplet) { - if (!desktopMenu->isEmpty()) { - desktopMenu->addSeparator(); - } - - //qDebug() << "adding close action" << closeApplet->isEnabled() << closeApplet->isVisible(); - desktopMenu->addAction(closeApplet); - } - } -} - -void ContextMenu::addContainmentActions(QMenu *desktopMenu, QEvent *event) -{ - if (!m_latteView->containment()) { - return; - } - - if (m_latteView->containment()->corona()->immutability() != Plasma::Types::Mutable && - !KAuthorized::authorizeAction(QStringLiteral("plasma/containment_actions"))) { - //qDebug() << "immutability"; - return; - } - - //this is what ContainmentPrivate::prepareContainmentActions was - const QString trigger = Plasma::ContainmentActions::eventToString(event); - //"RightButton;NoModifier" - Plasma::ContainmentActions *plugin = m_latteView->containment()->containmentActions().value(trigger); - - if (!plugin) { - return; - } - - if (plugin->containment() != m_latteView->containment()) { - plugin->setContainment(m_latteView->containment()); - // now configure it - KConfigGroup cfg(m_latteView->containment()->corona()->config(), "ActionPlugins"); - cfg = KConfigGroup(&cfg, QString::number(m_latteView->containment()->containmentType())); - KConfigGroup pluginConfig = KConfigGroup(&cfg, trigger); - plugin->restore(pluginConfig); - } - - QList actions = plugin->contextualActions(); - - for (const QAction *act : actions) { - if (act->menu()) { - //this is a workaround where Qt now creates the menu widget - //in .exec before oxygen can polish it and set the following attribute - act->menu()->setAttribute(Qt::WA_TranslucentBackground); - //end workaround - - if (act->menu()->winId()) { - act->menu()->windowHandle()->setTransientParent(m_latteView); - } - } - } - - desktopMenu->addActions(actions); - - return; -} - -Plasma::Containment *ContextMenu::containmentById(uint id) -{ - for (const auto containment : m_latteView->corona()->containments()) { - if (id == containment->id()) { - return containment; - } - } - - return 0; -} - -} -} diff --git a/app/view/contextmenu.h b/app/view/contextmenu.h deleted file mode 100644 index 2e4c867da..000000000 --- a/app/view/contextmenu.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - SPDX-FileCopyrightText: 2018 Michail Vourlakos - SPDX-License-Identifier: GPL-2.0-or-later -*/ - -#ifndef CONTEXTMENU_H -#define CONTEXTMENU_H - -// Qt -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace Plasma { -class Applet; -class Containment; -class Types; -} - -namespace Latte { -class View; -} - -namespace Latte { -namespace ViewPart { - -class ContextMenu : public QObject -{ - Q_OBJECT - -public: - ContextMenu(Latte::View *view); - ~ContextMenu() override; - - QMenu *menu(); - - bool mousePressEvent(QMouseEvent *event); - bool mousePressEventForContainmentMenu(QQuickView *view, QMouseEvent *event); - -signals: - void menuChanged(); - -private slots: - void onMenuAboutToHide(); - -private: - void addAppletActions(QMenu *desktopMenu, Plasma::Applet *applet, QEvent *event); - void addContainmentActions(QMenu *desktopMenu, QEvent *event); - void updateAppletContainsMethod(); - - QPoint popUpRelevantToParent(const QRect &parentItem, const QRect popUpRect); - QPoint popUpRelevantToGlobalPoint(const QRect &parentItem, const QRect popUpRect); - - QPoint popUpTopLeft(Plasma::Applet *applet, const QRect popUpRect); - - Plasma::Containment *containmentById(uint id); - - -private: - Plasma::Types::ItemStatus m_lastContainmentStatus; - - QPointer m_contextMenu; - QMetaMethod m_appletContainsMethod; - QQuickItem *m_appletContainsMethodItem{nullptr}; - - Latte::View *m_latteView; - - friend class Latte::View; -}; - -} -} - -#endif // DOCKMENUMANAGER_H diff --git a/app/view/settings/canvasconfigview.cpp b/app/view/settings/canvasconfigview.cpp index cc228da98..34b92b485 100644 --- a/app/view/settings/canvasconfigview.cpp +++ b/app/view/settings/canvasconfigview.cpp @@ -7,7 +7,6 @@ // local #include "primaryconfigview.h" -#include "../contextmenu.h" #include "../panelshadows_p.h" #include "../view.h" #include "../../lattecorona.h"