| /**************************************************************************** |
| ** |
| ** Copyright (C) 2017 The Qt Company Ltd. |
| ** Contact: http://www.qt.io/licensing/ |
| ** |
| ** This file is part of the Qt Labs Platform module of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:LGPL3$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see http://www.qt.io/terms-conditions. For further |
| ** information use the contact form at http://www.qt.io/contact-us. |
| ** |
| ** GNU Lesser General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU Lesser |
| ** General Public License version 3 as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.LGPLv3 included in the |
| ** packaging of this file. Please review the following information to |
| ** ensure the GNU Lesser General Public License version 3 requirements |
| ** will be met: https://www.gnu.org/licenses/lgpl.html. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU |
| ** General Public License version 2.0 or later as published by the Free |
| ** Software Foundation and appearing in the file LICENSE.GPL included in |
| ** the packaging of this file. Please review the following information to |
| ** ensure the GNU General Public License version 2.0 requirements will be |
| ** met: http://www.gnu.org/licenses/gpl-2.0.html. |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #include "qquickplatformsystemtrayicon_p.h" |
| #include "qquickplatformmenu_p.h" |
| #include "qquickplatformiconloader_p.h" |
| |
| #include <QtCore/qloggingcategory.h> |
| #include <QtGui/qpa/qplatformtheme.h> |
| #include <QtGui/private/qguiapplication_p.h> |
| |
| #include "widgets/qwidgetplatform_p.h" |
| |
| QT_BEGIN_NAMESPACE |
| |
| /*! |
| \qmltype SystemTrayIcon |
| \inherits QtObject |
| //! \instantiates QQuickPlatformSystemTrayIcon |
| \inqmlmodule Qt.labs.platform |
| \since 5.8 |
| \brief A system tray icon. |
| |
| The SystemTrayIcon type provides an icon for an application in the system tray. |
| |
| Many desktop platforms provide a special system tray or notification area, |
| where applications can display icons and notification messages. |
| |
| \image qtlabsplatform-systemtrayicon.png |
| |
| The following example shows how to create a system tray icon, and how to make |
| use of the \l activated() signal: |
| |
| \code |
| SystemTrayIcon { |
| visible: true |
| icon.source: "qrc:/images/tray-icon.png" |
| |
| onActivated: { |
| window.show() |
| window.raise() |
| window.requestActivate() |
| } |
| } |
| \endcode |
| |
| \section2 Tray menu |
| |
| SystemTrayIcon can have a menu that opens when the icon is activated. |
| |
| \image qtlabsplatform-systemtrayicon-menu.png |
| |
| The following example illustrates how to assign a \l Menu to a system tray icon: |
| |
| \code |
| SystemTrayIcon { |
| visible: true |
| icon.source: "qrc:/images/tray-icon.png" |
| |
| menu: Menu { |
| MenuItem { |
| text: qsTr("Quit") |
| onTriggered: Qt.quit() |
| } |
| } |
| } |
| \endcode |
| |
| \section2 Notification messages |
| |
| SystemTrayIcon can display notification messages. |
| |
| \image qtlabsplatform-systemtrayicon-message.png |
| |
| The following example presents how to show a notification message using |
| \l showMessage(), and how to make use of the \l messageClicked() signal: |
| |
| \code |
| SystemTrayIcon { |
| visible: true |
| icon.source: "qrc:/images/tray-icon.png" |
| |
| onMessageClicked: console.log("Message clicked") |
| Component.onCompleted: showMessage("Message title", "Something important came up. Click this to know more.") |
| } |
| \endcode |
| |
| \section2 Availability |
| |
| A native system tray icon is currently \l available on the following platforms: |
| |
| \list |
| \li All window managers and independent tray implementations for X11 that implement the |
| \l{http://standards.freedesktop.org/systemtray-spec/systemtray-spec-0.2.html} |
| {freedesktop.org XEmbed system tray specification}. |
| \li All desktop environments that implement the |
| \l{http://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/StatusNotifierItem} |
| {freedesktop.org D-Bus StatusNotifierItem specification}, including recent versions of KDE and Unity. |
| \li All supported versions of macOS. Note that the Growl notification system must be installed |
| for showMessage() to display messages on OS X prior to 10.8 (Mountain Lion). |
| \endlist |
| |
| \input includes/widgets.qdocinc 1 |
| |
| \labs |
| |
| \sa Menu |
| */ |
| |
| /*! |
| \qmlsignal Qt.labs.platform::SystemTrayIcon::activated(ActivationReason reason) |
| |
| This signal is emitted when the system tray icon is activated by the user. The |
| \a reason argument specifies how the system tray icon was activated. |
| |
| Available reasons: |
| |
| \value SystemTrayIcon.Unknown Unknown reason |
| \value SystemTrayIcon.Context The context menu for the system tray icon was requested |
| \value SystemTrayIcon.DoubleClick The system tray icon was double clicked |
| \value SystemTrayIcon.Trigger The system tray icon was clicked |
| \value SystemTrayIcon.MiddleClick The system tray icon was clicked with the middle mouse button |
| */ |
| |
| /*! |
| \qmlsignal Qt.labs.platform::SystemTrayIcon::messageClicked() |
| |
| This signal is emitted when a notification message is clicked by the user. |
| |
| \sa showMessage() |
| */ |
| |
| Q_DECLARE_LOGGING_CATEGORY(qtLabsPlatformTray) |
| |
| QQuickPlatformSystemTrayIcon::QQuickPlatformSystemTrayIcon(QObject *parent) |
| : QObject(parent), |
| m_complete(false), |
| m_visible(false), |
| m_menu(nullptr), |
| m_iconLoader(nullptr), |
| m_handle(nullptr) |
| { |
| m_handle = QGuiApplicationPrivate::platformTheme()->createPlatformSystemTrayIcon(); |
| if (!m_handle) |
| m_handle = QWidgetPlatform::createSystemTrayIcon(this); |
| qCDebug(qtLabsPlatformTray) << "SystemTrayIcon ->" << m_handle; |
| |
| if (m_handle) { |
| connect(m_handle, &QPlatformSystemTrayIcon::activated, this, &QQuickPlatformSystemTrayIcon::activated); |
| connect(m_handle, &QPlatformSystemTrayIcon::messageClicked, this, &QQuickPlatformSystemTrayIcon::messageClicked); |
| } |
| } |
| |
| QQuickPlatformSystemTrayIcon::~QQuickPlatformSystemTrayIcon() |
| { |
| if (m_menu) |
| m_menu->setSystemTrayIcon(nullptr); |
| cleanup(); |
| delete m_iconLoader; |
| m_iconLoader = nullptr; |
| delete m_handle; |
| m_handle = nullptr; |
| } |
| |
| QPlatformSystemTrayIcon *QQuickPlatformSystemTrayIcon::handle() const |
| { |
| return m_handle; |
| } |
| |
| /*! |
| \readonly |
| \qmlproperty bool Qt.labs.platform::SystemTrayIcon::available |
| |
| This property holds whether the system tray is available. |
| */ |
| bool QQuickPlatformSystemTrayIcon::isAvailable() const |
| { |
| return m_handle && m_handle->isSystemTrayAvailable(); |
| } |
| |
| /*! |
| \readonly |
| \qmlproperty bool Qt.labs.platform::SystemTrayIcon::supportsMessages |
| |
| This property holds whether the system tray icon supports notification messages. |
| |
| \sa showMessage() |
| */ |
| bool QQuickPlatformSystemTrayIcon::supportsMessages() const |
| { |
| return m_handle && m_handle->supportsMessages(); |
| } |
| |
| /*! |
| \qmlproperty bool Qt.labs.platform::SystemTrayIcon::visible |
| |
| This property holds whether the system tray icon is visible. |
| |
| The default value is \c false. |
| */ |
| bool QQuickPlatformSystemTrayIcon::isVisible() const |
| { |
| return m_visible; |
| } |
| |
| void QQuickPlatformSystemTrayIcon::setVisible(bool visible) |
| { |
| if (m_visible == visible) |
| return; |
| |
| if (m_handle && m_complete) { |
| if (visible) |
| init(); |
| else |
| cleanup(); |
| } |
| |
| m_visible = visible; |
| emit visibleChanged(); |
| } |
| |
| /*! |
| \qmlproperty url Qt.labs.platform::SystemTrayIcon::iconSource |
| \deprecated Use icon.source instead. |
| \sa icon |
| */ |
| QUrl QQuickPlatformSystemTrayIcon::iconSource() const |
| { |
| return icon().source(); |
| } |
| |
| void QQuickPlatformSystemTrayIcon::setIconSource(const QUrl& source) |
| { |
| QQuickPlatformIcon newIcon = icon(); |
| if (source == newIcon.source()) |
| return; |
| |
| newIcon.setSource(source); |
| iconLoader()->setIcon(newIcon); |
| emit iconSourceChanged(); |
| } |
| |
| /*! |
| \qmlproperty string Qt.labs.platform::SystemTrayIcon::iconName |
| \deprecated Use icon.name instead. |
| \sa icon |
| */ |
| QString QQuickPlatformSystemTrayIcon::iconName() const |
| { |
| return icon().name(); |
| } |
| |
| void QQuickPlatformSystemTrayIcon::setIconName(const QString& name) |
| { |
| QQuickPlatformIcon newIcon = icon(); |
| if (name == newIcon.name()) |
| return; |
| |
| newIcon.setName(name); |
| iconLoader()->setIcon(newIcon); |
| emit iconNameChanged(); |
| } |
| |
| /*! |
| \qmlproperty string Qt.labs.platform::SystemTrayIcon::tooltip |
| |
| This property holds the tooltip of the system tray icon. |
| */ |
| QString QQuickPlatformSystemTrayIcon::tooltip() const |
| { |
| return m_tooltip; |
| } |
| |
| void QQuickPlatformSystemTrayIcon::setTooltip(const QString &tooltip) |
| { |
| if (m_tooltip == tooltip) |
| return; |
| |
| if (m_handle && m_complete) |
| m_handle->updateToolTip(tooltip); |
| |
| m_tooltip = tooltip; |
| emit tooltipChanged(); |
| } |
| |
| /*! |
| \qmlproperty Menu Qt.labs.platform::SystemTrayIcon::menu |
| |
| This property holds a menu for the system tray icon. |
| */ |
| QQuickPlatformMenu *QQuickPlatformSystemTrayIcon::menu() const |
| { |
| return m_menu; |
| } |
| |
| void QQuickPlatformSystemTrayIcon::setMenu(QQuickPlatformMenu *menu) |
| { |
| if (m_menu == menu) |
| return; |
| |
| if (m_menu) |
| m_menu->setSystemTrayIcon(nullptr); |
| if (menu) { |
| menu->setSystemTrayIcon(this); |
| if (m_handle && m_complete && menu->create()) |
| m_handle->updateMenu(menu->handle()); |
| } |
| |
| m_menu = menu; |
| emit menuChanged(); |
| } |
| |
| /*! |
| \since Qt.labs.platform 1.1 (Qt 5.12) |
| \qmlproperty rect Qt.labs.platform::SystemTrayIcon::geometry |
| |
| This property holds the geometry of the system tray icon. |
| */ |
| QRect QQuickPlatformSystemTrayIcon::geometry() const |
| { |
| return m_handle ? m_handle->geometry() : QRect(); |
| } |
| |
| /*! |
| \since Qt.labs.platform 1.1 (Qt 5.12) |
| \qmlpropertygroup Qt.labs.platform::SystemTrayIcon::icon |
| \qmlproperty url Qt.labs.platform::SystemTrayIcon::icon.source |
| \qmlproperty string Qt.labs.platform::SystemTrayIcon::icon.name |
| \qmlproperty bool Qt.labs.platform::SystemTrayIcon::icon.mask |
| |
| This property holds the system tray icon. |
| |
| \code |
| SystemTrayIcon { |
| icon.mask: true |
| icon.source: "qrc:/images/tray-icon.png" |
| } |
| \endcode |
| */ |
| QQuickPlatformIcon QQuickPlatformSystemTrayIcon::icon() const |
| { |
| if (!m_iconLoader) |
| return QQuickPlatformIcon(); |
| |
| return m_iconLoader->icon(); |
| } |
| |
| void QQuickPlatformSystemTrayIcon::setIcon(const QQuickPlatformIcon &icon) |
| { |
| if (iconLoader()->icon() == icon) |
| return; |
| |
| iconLoader()->setIcon(icon); |
| emit iconChanged(); |
| } |
| |
| /*! |
| \qmlmethod void Qt.labs.platform::SystemTrayIcon::show() |
| |
| Shows the system tray icon. |
| */ |
| void QQuickPlatformSystemTrayIcon::show() |
| { |
| setVisible(true); |
| } |
| |
| /*! |
| \qmlmethod void Qt.labs.platform::SystemTrayIcon::hide() |
| |
| Hides the system tray icon. |
| */ |
| void QQuickPlatformSystemTrayIcon::hide() |
| { |
| setVisible(false); |
| } |
| |
| /*! |
| \qmlmethod void Qt.labs.platform::SystemTrayIcon::showMessage(string title, string message, MessageIcon icon, int msecs) |
| |
| Shows a system tray message with the given \a title, \a message and \a icon |
| for the time specified in \a msecs. |
| |
| \note System tray messages are dependent on the system configuration and user preferences, |
| and may not appear at all. Therefore, it should not be relied upon as the sole means for providing |
| critical information. |
| |
| \sa supportsMessages, messageClicked() |
| */ |
| void QQuickPlatformSystemTrayIcon::showMessage(const QString &title, const QString &msg, QPlatformSystemTrayIcon::MessageIcon icon, int msecs) |
| { |
| if (m_handle) |
| m_handle->showMessage(title, msg, QIcon(), icon, msecs); |
| } |
| |
| void QQuickPlatformSystemTrayIcon::init() |
| { |
| if (!m_handle) |
| return; |
| |
| m_handle->init(); |
| if (m_menu && m_menu->create()) |
| m_handle->updateMenu(m_menu->handle()); |
| m_handle->updateToolTip(m_tooltip); |
| if (m_iconLoader) |
| m_iconLoader->setEnabled(true); |
| } |
| |
| void QQuickPlatformSystemTrayIcon::cleanup() |
| { |
| if (m_handle) |
| m_handle->cleanup(); |
| if (m_iconLoader) |
| m_iconLoader->setEnabled(false); |
| } |
| |
| void QQuickPlatformSystemTrayIcon::classBegin() |
| { |
| } |
| |
| void QQuickPlatformSystemTrayIcon::componentComplete() |
| { |
| m_complete = true; |
| if (m_visible) |
| init(); |
| } |
| |
| QQuickPlatformIconLoader *QQuickPlatformSystemTrayIcon::iconLoader() const |
| { |
| if (!m_iconLoader) { |
| QQuickPlatformSystemTrayIcon *that = const_cast<QQuickPlatformSystemTrayIcon *>(this); |
| static int slot = staticMetaObject.indexOfSlot("updateIcon()"); |
| m_iconLoader = new QQuickPlatformIconLoader(slot, that); |
| m_iconLoader->setEnabled(m_complete); |
| } |
| return m_iconLoader; |
| } |
| |
| void QQuickPlatformSystemTrayIcon::updateIcon() |
| { |
| if (!m_handle || !m_iconLoader) |
| return; |
| |
| const QRect oldGeometry = m_handle->geometry(); |
| |
| m_handle->updateIcon(m_iconLoader->toQIcon()); |
| |
| if (oldGeometry != m_handle->geometry()) |
| emit geometryChanged(); |
| } |
| |
| QT_END_NAMESPACE |