From cc0c125479d4731d12467ef2b7dcde78652a65ce Mon Sep 17 00:00:00 2001 From: Kai Uwe Broulik Date: Fri, 27 Sep 2019 10:58:57 +0200 Subject: [PATCH] [Notifications] Dodge Plasma dialogs The notification popup typically gets in the way of the system tray popup. In case it would cover a Plasma dialog, hide the notification popup. It doesn't specifically check for System Tray but then it will also get out of the way of your calendar and other widgets you might have placed in the respective corner. Differential Revision: https://phabricator.kde.org/D24208 --- applets/notifications/CMakeLists.txt | 1 + applets/notifications/notificationapplet.cpp | 10 ++++++++++ applets/notifications/notificationapplet.h | 5 +++++ .../package/contents/ui/global/Globals.qml | 16 +++++++++++++--- 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/applets/notifications/CMakeLists.txt b/applets/notifications/CMakeLists.txt index 9bae73713..19decdef3 100644 --- a/applets/notifications/CMakeLists.txt +++ b/applets/notifications/CMakeLists.txt @@ -15,6 +15,7 @@ target_link_libraries(plasma_applet_notifications Qt5::Quick # for QQmlParserStatus KF5::I18n KF5::Plasma + KF5::PlasmaQuick KF5::KIOWidgets # for PreviewJob ) diff --git a/applets/notifications/notificationapplet.cpp b/applets/notifications/notificationapplet.cpp index 69d990203..b21c1ce67 100644 --- a/applets/notifications/notificationapplet.cpp +++ b/applets/notifications/notificationapplet.cpp @@ -23,12 +23,15 @@ #include #include +#include #include #include #include #include #include +#include + #include "filemenu.h" #include "thumbnailer.h" @@ -43,6 +46,8 @@ NotificationApplet::NotificationApplet(QObject *parent, const QVariantList &data qmlProtectModule(uri, 2); s_typesRegistered = true; } + + connect(qApp, &QGuiApplication::focusWindowChanged, this, &NotificationApplet::focussedPlasmaDialogChanged); } NotificationApplet::~NotificationApplet() = default; @@ -105,6 +110,11 @@ void NotificationApplet::doDrag(QQuickItem *item, const QUrl &url, const QPixmap emit dragActiveChanged(); } +QWindow *NotificationApplet::focussedPlasmaDialog() const +{ + return qobject_cast(qApp->focusWindow()); +} + void NotificationApplet::setSelectionClipboardText(const QString &text) { // FIXME KDeclarative Clipboard item uses QClipboard::Mode for "mode" diff --git a/applets/notifications/notificationapplet.h b/applets/notifications/notificationapplet.h index 1a54dd23c..5756a7f58 100644 --- a/applets/notifications/notificationapplet.h +++ b/applets/notifications/notificationapplet.h @@ -33,6 +33,8 @@ class NotificationApplet : public Plasma::Applet Q_PROPERTY(bool dragActive READ dragActive NOTIFY dragActiveChanged) + Q_PROPERTY(QWindow *focussedPlasmaDialog READ focussedPlasmaDialog NOTIFY focussedPlasmaDialogChanged) + public: explicit NotificationApplet(QObject *parent, const QVariantList &data); ~NotificationApplet() override; @@ -44,12 +46,15 @@ public: Q_INVOKABLE bool isDrag(int oldX, int oldY, int newX, int newY) const; Q_INVOKABLE void startDrag(QQuickItem *item, const QUrl &url, const QPixmap &pixmap); + QWindow *focussedPlasmaDialog() const; + Q_INVOKABLE void setSelectionClipboardText(const QString &text); Q_INVOKABLE bool isPrimaryScreen(const QRect &rect) const; signals: void dragActiveChanged(); + void focussedPlasmaDialogChanged(); private slots: void doDrag(QQuickItem *item, const QUrl &url, const QPixmap &pixmap); diff --git a/applets/notifications/package/contents/ui/global/Globals.qml b/applets/notifications/package/contents/ui/global/Globals.qml index 6a355f210..6b40011d3 100644 --- a/applets/notifications/package/contents/ui/global/Globals.qml +++ b/applets/notifications/package/contents/ui/global/Globals.qml @@ -238,7 +238,7 @@ QtObject { } for (var i = 0; i < popupInstantiator.count; ++i) { - var popup = popupInstantiator.objectAt(i); + let popup = popupInstantiator.objectAt(i); // Popup width is fixed, so don't rely on the actual window size var popupEffectiveWidth = popupWidth + popup.margins.left + popup.margins.right; @@ -273,8 +273,18 @@ QtObject { } } - // TODO would be nice to hide popups when systray or panel controller is open - popup.visible = visible; + popup.visible = Qt.binding(function() { + const dialog = plasmoid.nativeInterface.focussedPlasmaDialog; + if (dialog && dialog.visible && dialog !== popup) { + // If the notification obscures any other Plasma dialog, hide it + // No rect intersects in JS... + if (dialog.x < popup.x + popup.width && popup.x < dialog.x + dialog.width && dialog.y < popup.y + popup.height && popup.y < dialog.y + dialog.height) { + return false; + } + } + + return visible; + }); } }