File indexing completed on 2024-06-23 03:56:33
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 KSTATUSNOTIFIERITEM_H 0009 #define KSTATUSNOTIFIERITEM_H 0010 0011 #include <QObject> 0012 #include <QPoint> 0013 #include <QString> 0014 #include <QWindow> 0015 0016 #include <kstatusnotifieritem_export.h> 0017 0018 #include <memory> 0019 0020 class QAction; 0021 class QMenu; 0022 0023 class KStatusNotifierItemPrivate; 0024 0025 /** 0026 * @class KStatusNotifierItem kstatusnotifieritem.h KStatusNotifierItem 0027 * 0028 * \brief %KDE Status notifier Item protocol implementation 0029 * 0030 * This class implements the Status notifier Item D-Bus specification. 0031 * It provides an icon similar to the classical systemtray icons, 0032 * with some key differences: 0033 * 0034 * - the actual representation is done by the systemtray (or the app behaving 0035 * like it) itself, not by this app. Since 4.5 this also includes the menu, 0036 * which means you cannot use embed widgets in the menu. 0037 * 0038 * - there is communication between the systemtray and the icon owner, so the 0039 * system tray can know if the application is in a normal or in a requesting 0040 * attention state. 0041 * 0042 * - icons are divided in categories, so the systemtray can represent in a 0043 * different way the icons from normal applications and for instance the ones 0044 * about hardware status. 0045 * 0046 * Whenever possible you should prefer passing icon by name rather than by 0047 * pixmap because: 0048 * 0049 * - it is much lighter on D-Bus (no need to pass all image pixels). 0050 * 0051 * - it makes it possible for the systemtray to load an icon of the appropriate 0052 * size or to replace your icon with a systemtray specific icon which matches 0053 * with the desktop theme. 0054 * 0055 * - some implementations of the system tray do not support passing icons by 0056 * pixmap and will show a blank icon instead. 0057 * 0058 * @author Marco Martin <notmart@gmail.com> 0059 * @since 4.4 0060 */ 0061 class KSTATUSNOTIFIERITEM_EXPORT KStatusNotifierItem : public QObject 0062 { 0063 Q_OBJECT 0064 0065 Q_PROPERTY(ItemCategory category READ category WRITE setCategory) 0066 Q_PROPERTY(QString title READ title WRITE setTitle) 0067 Q_PROPERTY(ItemStatus status READ status WRITE setStatus) 0068 Q_PROPERTY(QString iconName READ iconName WRITE setIconByName) 0069 Q_PROPERTY(QString overlayIconName READ overlayIconName WRITE setOverlayIconByName) 0070 Q_PROPERTY(QString attentionIconName READ attentionIconName WRITE setAttentionIconByName) 0071 Q_PROPERTY(QString toolTipIconName READ toolTipIconName WRITE setToolTipIconByName) 0072 Q_PROPERTY(QString toolTipTitle READ toolTipTitle WRITE setToolTipTitle) 0073 Q_PROPERTY(QString toolTipSubTitle READ toolTipSubTitle WRITE setToolTipSubTitle) 0074 0075 friend class KStatusNotifierItemDBus; 0076 friend class KStatusNotifierItemPrivate; 0077 0078 public: 0079 /** 0080 * All the possible status this icon can have, depending on the 0081 * importance of the events that happens in the parent application 0082 */ 0083 enum ItemStatus { 0084 /// Nothing is happening in the application, so showing this icon is not required. This is the default value 0085 Passive = 1, 0086 /// The application is doing something, or it is important that the 0087 /// icon is always reachable from the user 0088 Active = 2, 0089 /// The application requests the attention of the user, for instance 0090 /// battery running out or a new IM message was received 0091 NeedsAttention = 3, 0092 }; 0093 Q_ENUM(ItemStatus) 0094 0095 /** 0096 * Different kinds of applications announce their type to the systemtray, 0097 * so can be drawn in a different way or in a different place 0098 */ 0099 enum ItemCategory { 0100 /// An icon for a normal application, can be seen as its taskbar entry. This is the default value 0101 ApplicationStatus = 1, 0102 /// This is a communication oriented application; this icon will be used 0103 /// for things such as the notification of a new message 0104 Communications = 2, 0105 /// This is a system service, it can show itself in the system tray if 0106 /// it requires interaction from the user or wants to inform him about 0107 /// something 0108 SystemServices = 3, 0109 /// This application shows hardware status or a means to control it 0110 Hardware = 4, 0111 Reserved = 129, 0112 }; 0113 Q_ENUM(ItemCategory) 0114 0115 /** 0116 * Construct a new status notifier item 0117 * 0118 * @param parent the parent object for this object. If the object passed in as 0119 * a parent is also a QWidget, it will be used as the main application window 0120 * represented by this icon and will be shown/hidden when an activation is requested. 0121 * @see associatedWindow 0122 **/ 0123 explicit KStatusNotifierItem(QObject *parent = nullptr); 0124 0125 /** 0126 * Construct a new status notifier item with a unique identifier. 0127 * If your application has more than one status notifier item and the user 0128 * should be able to manipulate them separately (e.g. mark them for hiding 0129 * in a user interface), the id can be used to differentiate between them. 0130 * 0131 * The id should remain consistent even between application restarts. 0132 * Status notifier items without ids default to the application's name for the id. 0133 * This id may be used, for instance, by hosts displaying status notifier items to 0134 * associate configuration information with this item in a way that can persist 0135 * between sessions or application restarts. 0136 * 0137 * @param id the unique id for this icon 0138 * @param parent the parent object for this object. If the object passed in as 0139 * a parent is also a QWidget, it will be used as the main application window 0140 * represented by this icon and will be shown/hidden when an activation is requested. 0141 * @see associatedWindow 0142 **/ 0143 explicit KStatusNotifierItem(const QString &id, QObject *parent = nullptr); 0144 0145 ~KStatusNotifierItem() override; 0146 0147 /** 0148 * @return The id which was specified in the constructor. This should be 0149 * guaranteed to be consistent between application starts and 0150 * untranslated, as host applications displaying items may use it for 0151 * storing configuration related to this item. 0152 */ 0153 QString id() const; 0154 0155 /** 0156 * Sets the category for this icon, usually it's needed to call this function only once 0157 * 0158 * @param category the new category for this icon 0159 */ 0160 void setCategory(const ItemCategory category); 0161 0162 /** 0163 * @return the application category 0164 */ 0165 ItemCategory category() const; 0166 0167 /** 0168 * Sets a title for this icon 0169 */ 0170 void setTitle(const QString &title); 0171 0172 /** 0173 * @return the title of this icon 0174 */ 0175 QString title() const; 0176 0177 /** 0178 * Sets a new status for this icon. 0179 */ 0180 void setStatus(const ItemStatus status); 0181 0182 /** 0183 * @return the current application status 0184 */ 0185 ItemStatus status() const; 0186 0187 // Main icon related functions 0188 /** 0189 * Sets a new main icon for the system tray 0190 * 0191 * @param name it must be a QIcon::fromTheme compatible name, this is 0192 * the preferred way to set an icon 0193 */ 0194 void setIconByName(const QString &name); 0195 0196 /** 0197 * @return the name of the main icon to be displayed 0198 * if image() is not empty this will always return an empty string 0199 */ 0200 QString iconName() const; 0201 0202 /** 0203 * Sets a new main icon for the system tray 0204 * 0205 * @param pixmap our icon, use setIcon(const QString) when possible 0206 */ 0207 void setIconByPixmap(const QIcon &icon); 0208 0209 /** 0210 * @return a pixmap of the icon 0211 */ 0212 QIcon iconPixmap() const; 0213 0214 /** 0215 * Sets an icon to be used as overlay for the main one 0216 * @param icon name, if name is and empty QString() 0217 * (and overlayIconPixmap() is empty too) the icon will be removed 0218 */ 0219 void setOverlayIconByName(const QString &name); 0220 0221 /** 0222 * @return the name of the icon to be used as overlay fr the main one 0223 */ 0224 QString overlayIconName() const; 0225 0226 /** 0227 * Sets an icon to be used as overlay for the main one 0228 * setOverlayIconByPixmap(QIcon()) will remove the overlay when 0229 * overlayIconName() is empty too. 0230 * 0231 * @param pixmap our overlay icon, use setOverlayIcon(const QString) when possible. 0232 */ 0233 void setOverlayIconByPixmap(const QIcon &icon); 0234 0235 /** 0236 * @return a pixmap of the icon 0237 */ 0238 QIcon overlayIconPixmap() const; 0239 0240 // Requesting attention icon 0241 0242 /** 0243 * Sets a new icon that should be used when the application 0244 * wants to request attention (usually the systemtray 0245 * will blink between this icon and the main one) 0246 * 0247 * @param name QIcon::fromTheme compatible name of icon to use 0248 */ 0249 void setAttentionIconByName(const QString &name); 0250 0251 /** 0252 * @return the name of the icon to be displayed when the application 0253 * is requesting the user's attention 0254 * if attentionImage() is not empty this will always return an empty string 0255 */ 0256 QString attentionIconName() const; 0257 0258 /** 0259 * Sets the pixmap of the requesting attention icon. 0260 * Use setAttentionIcon(const QString) instead when possible. 0261 * 0262 * @param icon QIcon to use for requesting attention. 0263 */ 0264 void setAttentionIconByPixmap(const QIcon &icon); 0265 0266 /** 0267 * @return a pixmap of the requesting attention icon 0268 */ 0269 QIcon attentionIconPixmap() const; 0270 0271 /** 0272 * Sets a movie as the requesting attention icon. 0273 * This overrides anything set in setAttentionIcon() 0274 */ 0275 void setAttentionMovieByName(const QString &name); 0276 0277 /** 0278 * @return the name of the movie to be displayed when the application is 0279 * requesting the user attention 0280 */ 0281 QString attentionMovieName() const; 0282 0283 // ToolTip handling 0284 /** 0285 * Sets a new toolTip or this icon, a toolTip is composed of an icon, 0286 * a title and a text, all fields are optional. 0287 * 0288 * @param iconName a QIcon::fromTheme compatible name for the tootip icon 0289 * @param title tootip title 0290 * @param subTitle subtitle for the toolTip 0291 */ 0292 void setToolTip(const QString &iconName, const QString &title, const QString &subTitle); 0293 0294 /** 0295 * Sets a new toolTip or this status notifier item. 0296 * This is an overloaded member provided for convenience 0297 */ 0298 void setToolTip(const QIcon &icon, const QString &title, const QString &subTitle); 0299 0300 /** 0301 * Set a new icon for the toolTip 0302 * 0303 * @param name the name for the icon 0304 */ 0305 void setToolTipIconByName(const QString &name); 0306 0307 /** 0308 * @return the name of the toolTip icon 0309 * if toolTipImage() is not empty this will always return an empty string 0310 */ 0311 QString toolTipIconName() const; 0312 0313 /** 0314 * Set a new icon for the toolTip. 0315 * 0316 * Use setToolTipIconByName(QString) if possible. 0317 * @param pixmap representing the icon 0318 */ 0319 void setToolTipIconByPixmap(const QIcon &icon); 0320 0321 /** 0322 * @return a serialization of the toolTip icon data 0323 */ 0324 QIcon toolTipIconPixmap() const; 0325 0326 /** 0327 * Sets a new title for the toolTip 0328 */ 0329 void setToolTipTitle(const QString &title); 0330 0331 /** 0332 * @return the title of the main icon toolTip 0333 */ 0334 QString toolTipTitle() const; 0335 0336 /** 0337 * Sets a new subtitle for the toolTip 0338 */ 0339 void setToolTipSubTitle(const QString &subTitle); 0340 0341 /** 0342 * @return the subtitle of the main icon toolTip 0343 */ 0344 QString toolTipSubTitle() const; 0345 0346 /** 0347 * Sets a new context menu for this StatusNotifierItem. 0348 * the menu will be shown with a contextMenu(int,int) 0349 * call by the systemtray over D-Bus 0350 * usually you don't need to call this unless you want to use 0351 * a custom QMenu subclass as context menu. 0352 * 0353 * The KStatusNotifierItem instance takes ownership of the menu, 0354 * and will delete it upon its destruction. 0355 */ 0356 void setContextMenu(QMenu *menu); 0357 0358 /** 0359 * Access the context menu associated to this status notifier item 0360 */ 0361 QMenu *contextMenu() const; 0362 0363 /** 0364 * Sets the main window associated with this StatusNotifierItem 0365 * 0366 * @param window The window to be used. 0367 * 0368 * @since 6.0 0369 */ 0370 void setAssociatedWindow(QWindow *window); 0371 0372 /** 0373 * Access the main window associated with this StatusNotifierItem 0374 * 0375 * @since 6.0 0376 */ 0377 QWindow *associatedWindow() const; 0378 0379 /** 0380 * All the actions present in the menu 0381 */ 0382 QList<QAction *> actionCollection() const; 0383 0384 /** 0385 * Adds an action to the actionCollection() 0386 * 0387 * @param name the name of the action 0388 * @param action the action we want to add 0389 */ 0390 void addAction(const QString &name, QAction *action); 0391 0392 /** 0393 * Removes an action from the collection 0394 * 0395 * @param name the name of the action 0396 */ 0397 void removeAction(const QString &name); 0398 0399 /** 0400 * Retrieves an action from the action collection 0401 * by the action name 0402 * 0403 * @param name the name of the action to retrieve 0404 * @since 5.12 0405 */ 0406 QAction *action(const QString &name) const; 0407 0408 /** 0409 * Sets whether to show the standard items in the menu, such as Quit 0410 */ 0411 void setStandardActionsEnabled(bool enabled); 0412 0413 /** 0414 * @return if the standard items in the menu, such as Quit 0415 */ 0416 bool standardActionsEnabled() const; 0417 0418 /** 0419 * Shows the user a notification. If possible use KNotify instead 0420 * 0421 * @param title message title 0422 * @param message the actual text shown to the user 0423 * @param icon icon to be shown to the user 0424 * @param timeout how much time will elaps before hiding the message 0425 */ 0426 void showMessage(const QString &title, const QString &message, const QString &icon, int timeout = 10000); 0427 0428 /** 0429 * @return the last provided token to be used with Wayland's xdg_activation_v1 0430 */ 0431 QString providedToken() const; 0432 0433 public Q_SLOTS: 0434 0435 /** 0436 * Shows the main window and try to position it on top 0437 * of the other windows, if the window is already visible, hide it. 0438 * 0439 * @param pos if it's a valid position it represents the mouse coordinates when the event was triggered 0440 */ 0441 virtual void activate(const QPoint &pos = QPoint()); 0442 0443 /** 0444 * Hides the main window, if not already hidden. 0445 * 0446 * Stores some information about the window which otherwise would be lost due to unmapping 0447 * from the window system. Use when toggling the main window via activate(const QPoint &) 0448 * is not wanted, but instead the hidden state should be reached in any case. 0449 * 0450 * @since 6.0 0451 */ 0452 void hideAssociatedWindow(); 0453 0454 Q_SIGNALS: 0455 /** 0456 * Inform the host application that the mouse wheel 0457 * (or another mean of scrolling that the visualization provides) has been used 0458 * 0459 * @param delta the amount of scrolling, can be either positive or negative 0460 * @param orientation direction of the scrolling, can be either horizontal or vertical 0461 */ 0462 void scrollRequested(int delta, Qt::Orientation orientation); 0463 0464 /** 0465 * Inform the host application that an activation has been requested, 0466 * for instance left mouse click, but this is not guaranteed since 0467 * it's dependent from the visualization 0468 * @param active if it's true the application asked for the activation 0469 * of the main window, if it's false it asked for hiding 0470 * @param pos the position in the screen where the user clicked to 0471 * trigger this signal, QPoint() if it's not the consequence of a mouse click. 0472 */ 0473 void activateRequested(bool active, const QPoint &pos); 0474 0475 /** 0476 * Alternate activate action, 0477 * for instance right mouse click, but this is not guaranteed since 0478 * it's dependent from the visualization 0479 * 0480 * @param pos the position in the screen where the user clicked to 0481 * trigger this signal, QPoint() if it's not the consequence of a mouse click. 0482 */ 0483 void secondaryActivateRequested(const QPoint &pos); 0484 0485 protected: 0486 bool eventFilter(QObject *watched, QEvent *event) override; 0487 0488 private: 0489 std::unique_ptr<KStatusNotifierItemPrivate> const d; 0490 0491 Q_PRIVATE_SLOT(d, void serviceChange(const QString &name, const QString &oldOwner, const QString &newOwner)) 0492 Q_PRIVATE_SLOT(d, void contextMenuAboutToShow()) 0493 Q_PRIVATE_SLOT(d, void maybeQuit()) 0494 Q_PRIVATE_SLOT(d, void minimizeRestore()) 0495 Q_PRIVATE_SLOT(d, void legacyWheelEvent(int)) 0496 Q_PRIVATE_SLOT(d, void legacyActivated(QSystemTrayIcon::ActivationReason)) 0497 }; 0498 0499 #endif