File indexing completed on 2024-04-28 11:43:47

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2009 Marco Martin <notmart@gmail.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #ifndef KSTATUSNOTIFIERITEMPRIVATE_H
0009 #define KSTATUSNOTIFIERITEMPRIVATE_H
0010 
0011 #include <QEventLoopLocker>
0012 #include <QMovie>
0013 #include <QObject>
0014 #include <QString>
0015 #include <QSystemTrayIcon>
0016 #include <QWheelEvent>
0017 
0018 #include "kstatusnotifieritem.h"
0019 
0020 #ifdef QT_DBUS_LIB
0021 #include "kstatusnotifieritemdbus_p.h"
0022 
0023 #include "notifications_interface.h"
0024 #include "statusnotifierwatcher_interface.h"
0025 #endif
0026 
0027 class KSystemTrayIcon;
0028 class QMenu;
0029 class QAction;
0030 
0031 // this class is needed because we can't just put an event filter on it:
0032 // the events that are passed to QSystemTrayIcon are done so in a way that
0033 // bypasses the usual event filtering mechanisms *sigh*
0034 class KStatusNotifierLegacyIcon : public QSystemTrayIcon
0035 {
0036     Q_OBJECT
0037 
0038 public:
0039     KStatusNotifierLegacyIcon(QObject *parent)
0040         : QSystemTrayIcon(parent)
0041     {
0042     }
0043 
0044     bool event(QEvent *e) override
0045     {
0046         if (e->type() == QEvent::Wheel) {
0047             QWheelEvent *wheelEvent = static_cast<QWheelEvent *>(e);
0048             Q_EMIT wheel(wheelEvent->angleDelta().y());
0049         }
0050 
0051         return false;
0052     }
0053 
0054     void setMovie(QMovie *movie)
0055     {
0056         if (m_movie.data() == movie) {
0057             return;
0058         }
0059 
0060         delete m_movie.data();
0061         m_movie = movie;
0062 
0063         if (!movie) {
0064             return;
0065         }
0066 
0067         movie->setParent(this);
0068         movie->setCacheMode(QMovie::CacheAll);
0069         connect(movie, &QMovie::frameChanged, this, &KStatusNotifierLegacyIcon::slotNewFrame);
0070     }
0071 
0072     void setIconWithMask(QIcon &icon, bool isMask)
0073     {
0074         icon.setIsMask(isMask);
0075         QSystemTrayIcon::setIcon(icon);
0076     }
0077 
0078 Q_SIGNALS:
0079     void wheel(int);
0080 
0081 private Q_SLOTS:
0082     void slotNewFrame()
0083     {
0084         if (m_movie) {
0085             setIcon(QIcon(m_movie.data()->currentPixmap()));
0086         }
0087     }
0088 
0089 private:
0090     QPointer<QMovie> m_movie;
0091 };
0092 
0093 class KStatusNotifierItemPrivate
0094 {
0095 public:
0096     KStatusNotifierItemPrivate(KStatusNotifierItem *item);
0097 
0098     void init(const QString &extraId);
0099     void registerToDaemon();
0100     void serviceChange(const QString &name, const QString &oldOwner, const QString &newOwner);
0101     void setLegacySystemTrayEnabled(bool enabled);
0102     void syncLegacySystemTrayIcon();
0103     void contextMenuAboutToShow();
0104     void maybeQuit();
0105     void minimizeRestore();
0106     void minimizeRestore(bool show);
0107     void hideMenu();
0108     void setLegacyMode(bool legacy);
0109     void checkForRegisteredHosts();
0110     void legacyWheelEvent(int delta);
0111     void legacyActivated(QSystemTrayIcon::ActivationReason reason);
0112 
0113     bool checkVisibility(QPoint pos, bool perform = true);
0114 
0115     static const int s_protocolVersion;
0116 
0117     KStatusNotifierItem *q;
0118 
0119 #ifdef QT_DBUS_LIB
0120     KDbusImageStruct imageToStruct(const QImage &image);
0121     KDbusImageVector iconToVector(const QIcon &icon);
0122 
0123     KDbusImageVector serializedIcon;
0124     KDbusImageVector serializedAttentionIcon;
0125     KDbusImageVector serializedOverlayIcon;
0126     KDbusImageVector serializedToolTipIcon;
0127 
0128     org::kde::StatusNotifierWatcher *statusNotifierWatcher = nullptr;
0129     org::freedesktop::Notifications *notificationsClient = nullptr;
0130 
0131     KStatusNotifierItemDBus *statusNotifierItemDBus;
0132 #endif
0133 
0134     KStatusNotifierItem::ItemCategory category;
0135     QString id;
0136     QString title;
0137     KStatusNotifierItem::ItemStatus status;
0138 
0139     QString iconName;
0140     QIcon icon;
0141 
0142     QString overlayIconName;
0143     QIcon overlayIcon;
0144 
0145     QString attentionIconName;
0146     QIcon attentionIcon;
0147     QString movieName;
0148     QPointer<QMovie> movie;
0149 
0150     QString toolTipIconName;
0151     QIcon toolTipIcon;
0152     QString toolTipTitle;
0153     QString toolTipSubTitle;
0154     QString iconThemePath;
0155     QString menuObjectPath;
0156     KStatusNotifierLegacyIcon *systemTrayIcon;
0157 
0158     QMenu *menu;
0159     QHash<QString, QAction *> actionCollection;
0160     QWidget *associatedWidget;
0161     QPoint associatedWidgetPos;
0162     QAction *titleAction;
0163 
0164     // Ensure that closing the last KMainWindow doesn't exit the application
0165     // if a system tray icon is still present.
0166     QEventLoopLocker eventLoopLocker;
0167 
0168     bool hasQuit : 1;
0169     bool onAllDesktops : 1;
0170     bool standardActionsEnabled : 1;
0171 };
0172 
0173 #endif