From 13e7c603d51f22763d47e98a4e37468e46deac98 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 29 Sep 2016 16:49:12 +0200 Subject: move dbusmenu and dbustray under themes/genericunix that's the only place where they are used, and this clarifies the structure. Change-Id: I874beb7f049b34cc73079609b8baabcc1bd3cd39 Reviewed-by: Jake Petroules --- src/platformsupport/dbusmenu/dbusmenu.pri | 19 -- src/platformsupport/dbusmenu/qdbusmenuadaptor.cpp | 163 ----------- src/platformsupport/dbusmenu/qdbusmenuadaptor_p.h | 182 ------------ src/platformsupport/dbusmenu/qdbusmenubar.cpp | 177 ------------ src/platformsupport/dbusmenu/qdbusmenubar_p.h | 92 ------ .../dbusmenu/qdbusmenuconnection.cpp | 136 --------- .../dbusmenu/qdbusmenuconnection_p.h | 95 ------- .../dbusmenu/qdbusmenuregistrarproxy.cpp | 64 ----- .../dbusmenu/qdbusmenuregistrarproxy_p.h | 127 --------- src/platformsupport/dbusmenu/qdbusmenutypes.cpp | 301 -------------------- src/platformsupport/dbusmenu/qdbusmenutypes_p.h | 155 ----------- src/platformsupport/dbusmenu/qdbusplatformmenu.cpp | 307 --------------------- src/platformsupport/dbusmenu/qdbusplatformmenu_p.h | 207 -------------- src/platformsupport/dbustray/dbustray.pri | 15 - src/platformsupport/dbustray/qdbustrayicon.cpp | 305 -------------------- src/platformsupport/dbustray/qdbustrayicon_p.h | 169 ------------ src/platformsupport/dbustray/qdbustraytypes.cpp | 212 -------------- src/platformsupport/dbustray/qdbustraytypes_p.h | 108 -------- .../dbustray/qstatusnotifieritemadaptor.cpp | 186 ------------- .../dbustray/qstatusnotifieritemadaptor_p.h | 204 -------------- .../dbustray/qxdgnotificationproxy.cpp | 53 ---- .../dbustray/qxdgnotificationproxy_p.h | 152 ---------- src/platformsupport/platformsupport.pro | 7 - .../themes/genericunix/dbusmenu/dbusmenu.pri | 19 ++ .../genericunix/dbusmenu/qdbusmenuadaptor.cpp | 163 +++++++++++ .../genericunix/dbusmenu/qdbusmenuadaptor_p.h | 182 ++++++++++++ .../themes/genericunix/dbusmenu/qdbusmenubar.cpp | 177 ++++++++++++ .../themes/genericunix/dbusmenu/qdbusmenubar_p.h | 92 ++++++ .../genericunix/dbusmenu/qdbusmenuconnection.cpp | 136 +++++++++ .../genericunix/dbusmenu/qdbusmenuconnection_p.h | 95 +++++++ .../dbusmenu/qdbusmenuregistrarproxy.cpp | 64 +++++ .../dbusmenu/qdbusmenuregistrarproxy_p.h | 127 +++++++++ .../themes/genericunix/dbusmenu/qdbusmenutypes.cpp | 301 ++++++++++++++++++++ .../themes/genericunix/dbusmenu/qdbusmenutypes_p.h | 155 +++++++++++ .../genericunix/dbusmenu/qdbusplatformmenu.cpp | 307 +++++++++++++++++++++ .../genericunix/dbusmenu/qdbusplatformmenu_p.h | 207 ++++++++++++++ .../themes/genericunix/dbustray/dbustray.pri | 15 + .../themes/genericunix/dbustray/qdbustrayicon.cpp | 305 ++++++++++++++++++++ .../themes/genericunix/dbustray/qdbustrayicon_p.h | 169 ++++++++++++ .../themes/genericunix/dbustray/qdbustraytypes.cpp | 212 ++++++++++++++ .../themes/genericunix/dbustray/qdbustraytypes_p.h | 108 ++++++++ .../dbustray/qstatusnotifieritemadaptor.cpp | 186 +++++++++++++ .../dbustray/qstatusnotifieritemadaptor_p.h | 204 ++++++++++++++ .../genericunix/dbustray/qxdgnotificationproxy.cpp | 53 ++++ .../genericunix/dbustray/qxdgnotificationproxy_p.h | 152 ++++++++++ .../themes/genericunix/genericunix.pri | 5 + 46 files changed, 3434 insertions(+), 3436 deletions(-) delete mode 100644 src/platformsupport/dbusmenu/dbusmenu.pri delete mode 100644 src/platformsupport/dbusmenu/qdbusmenuadaptor.cpp delete mode 100644 src/platformsupport/dbusmenu/qdbusmenuadaptor_p.h delete mode 100644 src/platformsupport/dbusmenu/qdbusmenubar.cpp delete mode 100644 src/platformsupport/dbusmenu/qdbusmenubar_p.h delete mode 100644 src/platformsupport/dbusmenu/qdbusmenuconnection.cpp delete mode 100644 src/platformsupport/dbusmenu/qdbusmenuconnection_p.h delete mode 100644 src/platformsupport/dbusmenu/qdbusmenuregistrarproxy.cpp delete mode 100644 src/platformsupport/dbusmenu/qdbusmenuregistrarproxy_p.h delete mode 100644 src/platformsupport/dbusmenu/qdbusmenutypes.cpp delete mode 100644 src/platformsupport/dbusmenu/qdbusmenutypes_p.h delete mode 100644 src/platformsupport/dbusmenu/qdbusplatformmenu.cpp delete mode 100644 src/platformsupport/dbusmenu/qdbusplatformmenu_p.h delete mode 100644 src/platformsupport/dbustray/dbustray.pri delete mode 100644 src/platformsupport/dbustray/qdbustrayicon.cpp delete mode 100644 src/platformsupport/dbustray/qdbustrayicon_p.h delete mode 100644 src/platformsupport/dbustray/qdbustraytypes.cpp delete mode 100644 src/platformsupport/dbustray/qdbustraytypes_p.h delete mode 100644 src/platformsupport/dbustray/qstatusnotifieritemadaptor.cpp delete mode 100644 src/platformsupport/dbustray/qstatusnotifieritemadaptor_p.h delete mode 100644 src/platformsupport/dbustray/qxdgnotificationproxy.cpp delete mode 100644 src/platformsupport/dbustray/qxdgnotificationproxy_p.h create mode 100644 src/platformsupport/themes/genericunix/dbusmenu/dbusmenu.pri create mode 100644 src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuadaptor.cpp create mode 100644 src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuadaptor_p.h create mode 100644 src/platformsupport/themes/genericunix/dbusmenu/qdbusmenubar.cpp create mode 100644 src/platformsupport/themes/genericunix/dbusmenu/qdbusmenubar_p.h create mode 100644 src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp create mode 100644 src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h create mode 100644 src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuregistrarproxy.cpp create mode 100644 src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuregistrarproxy_p.h create mode 100644 src/platformsupport/themes/genericunix/dbusmenu/qdbusmenutypes.cpp create mode 100644 src/platformsupport/themes/genericunix/dbusmenu/qdbusmenutypes_p.h create mode 100644 src/platformsupport/themes/genericunix/dbusmenu/qdbusplatformmenu.cpp create mode 100644 src/platformsupport/themes/genericunix/dbusmenu/qdbusplatformmenu_p.h create mode 100644 src/platformsupport/themes/genericunix/dbustray/dbustray.pri create mode 100644 src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp create mode 100644 src/platformsupport/themes/genericunix/dbustray/qdbustrayicon_p.h create mode 100644 src/platformsupport/themes/genericunix/dbustray/qdbustraytypes.cpp create mode 100644 src/platformsupport/themes/genericunix/dbustray/qdbustraytypes_p.h create mode 100644 src/platformsupport/themes/genericunix/dbustray/qstatusnotifieritemadaptor.cpp create mode 100644 src/platformsupport/themes/genericunix/dbustray/qstatusnotifieritemadaptor_p.h create mode 100644 src/platformsupport/themes/genericunix/dbustray/qxdgnotificationproxy.cpp create mode 100644 src/platformsupport/themes/genericunix/dbustray/qxdgnotificationproxy_p.h diff --git a/src/platformsupport/dbusmenu/dbusmenu.pri b/src/platformsupport/dbusmenu/dbusmenu.pri deleted file mode 100644 index 662ebfdae6..0000000000 --- a/src/platformsupport/dbusmenu/dbusmenu.pri +++ /dev/null @@ -1,19 +0,0 @@ -QT_FOR_PRIVATE += dbus - -INCLUDEPATH += $$PWD - -HEADERS += \ - $$PWD/qdbusmenuadaptor_p.h \ - $$PWD/qdbusmenutypes_p.h \ - $$PWD/qdbusmenuconnection_p.h \ - $$PWD/qdbusmenubar_p.h \ - $$PWD/qdbusmenuregistrarproxy_p.h \ - $$PWD/qdbusplatformmenu_p.h \ - -SOURCES += \ - $$PWD/qdbusmenuadaptor.cpp \ - $$PWD/qdbusmenutypes.cpp \ - $$PWD/qdbusmenuconnection.cpp \ - $$PWD/qdbusmenubar.cpp \ - $$PWD/qdbusmenuregistrarproxy.cpp \ - $$PWD/qdbusplatformmenu.cpp \ diff --git a/src/platformsupport/dbusmenu/qdbusmenuadaptor.cpp b/src/platformsupport/dbusmenu/qdbusmenuadaptor.cpp deleted file mode 100644 index 354b9c3a2e..0000000000 --- a/src/platformsupport/dbusmenu/qdbusmenuadaptor.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/* - This file was originally created by qdbusxml2cpp version 0.8 - Command line was: - qdbusxml2cpp -a dbusmenu ../../3rdparty/dbus-ifaces/dbus-menu.xml - - However it is maintained manually. -*/ - -#include "qdbusmenuadaptor_p.h" -#include "qdbusplatformmenu_p.h" -#include -#include -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -QDBusMenuAdaptor::QDBusMenuAdaptor(QDBusPlatformMenu *topLevelMenu) - : QDBusAbstractAdaptor(topLevelMenu) - , m_topLevelMenu(topLevelMenu) -{ - setAutoRelaySignals(true); -} - -QDBusMenuAdaptor::~QDBusMenuAdaptor() -{ -} - -QString QDBusMenuAdaptor::status() const -{ - qCDebug(qLcMenu); - return QLatin1String("normal"); -} - -QString QDBusMenuAdaptor::textDirection() const -{ - return QLocale().textDirection() == Qt::RightToLeft ? QLatin1String("rtl") : QLatin1String("ltr"); -} - -uint QDBusMenuAdaptor::version() const -{ - return 4; -} - -bool QDBusMenuAdaptor::AboutToShow(int id) -{ - qCDebug(qLcMenu) << id; - if (id == 0) { - emit m_topLevelMenu->aboutToShow(); - } else { - QDBusPlatformMenuItem *item = QDBusPlatformMenuItem::byId(id); - if (item) { - const QDBusPlatformMenu *menu = static_cast(item->menu()); - if (menu) - emit const_cast(menu)->aboutToShow(); - } - } - return false; // updateNeeded (we don't know that, so false) -} - -QList QDBusMenuAdaptor::AboutToShowGroup(const QList &ids, QList &idErrors) -{ - qCDebug(qLcMenu) << ids; - Q_UNUSED(idErrors) - idErrors.clear(); - for (int id : ids) - AboutToShow(id); - return QList(); // updatesNeeded -} - -void QDBusMenuAdaptor::Event(int id, const QString &eventId, const QDBusVariant &data, uint timestamp) -{ - Q_UNUSED(data) - Q_UNUSED(timestamp) - QDBusPlatformMenuItem *item = QDBusPlatformMenuItem::byId(id); - qCDebug(qLcMenu) << id << (item ? item->text() : QLatin1String("")) << eventId; - if (item && eventId == QLatin1String("clicked")) - item->trigger(); - if (item && eventId == QLatin1String("hovered")) - emit item->hovered(); - if (eventId == QLatin1String("closed")) { - // There is no explicit AboutToHide method, so map closed event to aboutToHide method - const QDBusPlatformMenu *menu = Q_NULLPTR; - if (item) - menu = static_cast(item->menu()); - else if (id == 0) - menu = m_topLevelMenu; - if (menu) - emit const_cast(menu)->aboutToHide(); - } -} - -QList QDBusMenuAdaptor::EventGroup(const QDBusMenuEventList &events) -{ - for (const QDBusMenuEvent &ev : events) - Event(ev.m_id, ev.m_eventId, ev.m_data, ev.m_timestamp); - return QList(); // idErrors -} - -QDBusMenuItemList QDBusMenuAdaptor::GetGroupProperties(const QList &ids, const QStringList &propertyNames) -{ - qCDebug(qLcMenu) << ids << propertyNames << "=>" << QDBusMenuItem::items(ids, propertyNames); - return QDBusMenuItem::items(ids, propertyNames); -} - -uint QDBusMenuAdaptor::GetLayout(int parentId, int recursionDepth, const QStringList &propertyNames, QDBusMenuLayoutItem &layout) -{ - uint ret = layout.populate(parentId, recursionDepth, propertyNames, m_topLevelMenu); - qCDebug(qLcMenu) << parentId << "depth" << recursionDepth << propertyNames << layout.m_id << layout.m_properties << "revision" << ret << layout; - return ret; -} - -QDBusVariant QDBusMenuAdaptor::GetProperty(int id, const QString &name) -{ - qCDebug(qLcMenu) << id << name; - // handle method call com.canonical.dbusmenu.GetProperty - QDBusVariant value; - return value; -} - -QT_END_NAMESPACE diff --git a/src/platformsupport/dbusmenu/qdbusmenuadaptor_p.h b/src/platformsupport/dbusmenu/qdbusmenuadaptor_p.h deleted file mode 100644 index 6612f019a7..0000000000 --- a/src/platformsupport/dbusmenu/qdbusmenuadaptor_p.h +++ /dev/null @@ -1,182 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtDBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/* - This file was originally created by qdbusxml2cpp version 0.8 - Command line was: - qdbusxml2cpp -a dbusmenu ../../3rdparty/dbus-ifaces/dbus-menu.xml - - However it is maintained manually. - - It is also not part of the public API. This header file may change from - version to version without notice, or even be removed. -*/ - -#ifndef DBUSMENUADAPTOR_H -#define DBUSMENUADAPTOR_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -#include "qdbusmenutypes_p.h" - -QT_BEGIN_NAMESPACE - -/* - * Adaptor class for interface com.canonical.dbusmenu - */ -class QDBusMenuAdaptor: public QDBusAbstractAdaptor -{ - Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "com.canonical.dbusmenu") - Q_CLASSINFO("D-Bus Introspection", "" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" - "") -public: - QDBusMenuAdaptor(QDBusPlatformMenu *topLevelMenu); - virtual ~QDBusMenuAdaptor(); - -public: // PROPERTIES - Q_PROPERTY(QString Status READ status) - QString status() const; - - Q_PROPERTY(QString TextDirection READ textDirection) - QString textDirection() const; - - Q_PROPERTY(uint Version READ version) - uint version() const; - -public Q_SLOTS: // METHODS - bool AboutToShow(int id); - QList AboutToShowGroup(const QList &ids, QList &idErrors); - void Event(int id, const QString &eventId, const QDBusVariant &data, uint timestamp); - QList EventGroup(const QDBusMenuEventList &events); - QDBusMenuItemList GetGroupProperties(const QList &ids, const QStringList &propertyNames); - uint GetLayout(int parentId, int recursionDepth, const QStringList &propertyNames, QDBusMenuLayoutItem &layout); - QDBusVariant GetProperty(int id, const QString &name); - -Q_SIGNALS: // SIGNALS - void ItemActivationRequested(int id, uint timestamp); - void ItemsPropertiesUpdated(const QDBusMenuItemList &updatedProps, const QDBusMenuItemKeysList &removedProps); - void LayoutUpdated(uint revision, int parent); - -private: - QDBusPlatformMenu *m_topLevelMenu; -}; - -QT_END_NAMESPACE - -#endif // DBUSMENUADAPTOR_H diff --git a/src/platformsupport/dbusmenu/qdbusmenubar.cpp b/src/platformsupport/dbusmenu/qdbusmenubar.cpp deleted file mode 100644 index 76d658f51a..0000000000 --- a/src/platformsupport/dbusmenu/qdbusmenubar.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Dmitry Shachnev -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qdbusmenubar_p.h" -#include "qdbusmenuregistrarproxy_p.h" - -QT_BEGIN_NAMESPACE - -/* note: do not change these to QStringLiteral; - we are unloaded before QtDBus is done using the strings. - */ -#define REGISTRAR_SERVICE QLatin1String("com.canonical.AppMenu.Registrar") -#define REGISTRAR_PATH QLatin1String("/com/canonical/AppMenu/Registrar") - -QDBusMenuBar::QDBusMenuBar() - : QPlatformMenuBar() - , m_menu(new QDBusPlatformMenu()) - , m_menuAdaptor(new QDBusMenuAdaptor(m_menu)) - , m_windowId(0) -{ - QDBusMenuItem::registerDBusTypes(); - connect(m_menu, &QDBusPlatformMenu::propertiesUpdated, - m_menuAdaptor, &QDBusMenuAdaptor::ItemsPropertiesUpdated); - connect(m_menu, &QDBusPlatformMenu::updated, - m_menuAdaptor, &QDBusMenuAdaptor::LayoutUpdated); -} - -QDBusMenuBar::~QDBusMenuBar() -{ - unregisterMenuBar(); - delete m_menuAdaptor; - delete m_menu; - qDeleteAll(m_menuItems); -} - -QDBusPlatformMenuItem *QDBusMenuBar::menuItemForMenu(QPlatformMenu *menu) -{ - if (!menu) - return nullptr; - quintptr tag = menu->tag(); - const auto it = m_menuItems.constFind(tag); - if (it != m_menuItems.cend()) { - return *it; - } else { - QDBusPlatformMenuItem *item = new QDBusPlatformMenuItem; - updateMenuItem(item, menu); - m_menuItems.insert(tag, item); - return item; - } -} - -void QDBusMenuBar::updateMenuItem(QDBusPlatformMenuItem *item, QPlatformMenu *menu) -{ - const QDBusPlatformMenu *ourMenu = qobject_cast(menu); - item->setText(ourMenu->text()); - item->setIcon(ourMenu->icon()); - item->setEnabled(ourMenu->isEnabled()); - item->setVisible(ourMenu->isVisible()); - item->setMenu(menu); -} - -void QDBusMenuBar::insertMenu(QPlatformMenu *menu, QPlatformMenu *before) -{ - QDBusPlatformMenuItem *menuItem = menuItemForMenu(menu); - QDBusPlatformMenuItem *beforeItem = menuItemForMenu(before); - m_menu->insertMenuItem(menuItem, beforeItem); - m_menu->emitUpdated(); -} - -void QDBusMenuBar::removeMenu(QPlatformMenu *menu) -{ - QDBusPlatformMenuItem *menuItem = menuItemForMenu(menu); - m_menu->removeMenuItem(menuItem); - m_menu->emitUpdated(); -} - -void QDBusMenuBar::syncMenu(QPlatformMenu *menu) -{ - QDBusPlatformMenuItem *menuItem = menuItemForMenu(menu); - updateMenuItem(menuItem, menu); -} - -void QDBusMenuBar::handleReparent(QWindow *newParentWindow) -{ - if (newParentWindow && newParentWindow->winId() != m_windowId) { - unregisterMenuBar(); - m_windowId = newParentWindow->winId(); - registerMenuBar(); - } -} - -QPlatformMenu *QDBusMenuBar::menuForTag(quintptr tag) const -{ - QDBusPlatformMenuItem *menuItem = m_menuItems.value(tag); - if (menuItem) - return const_cast(menuItem->menu()); - return nullptr; -} - -QPlatformMenu *QDBusMenuBar::createMenu() const -{ - return new QDBusPlatformMenu; -} - -void QDBusMenuBar::registerMenuBar() -{ - static uint menuBarId = 0; - - QDBusConnection connection = QDBusConnection::sessionBus(); - m_objectPath = QStringLiteral("/MenuBar/%1").arg(++menuBarId); - if (!connection.registerObject(m_objectPath, m_menu)) - return; - - QDBusMenuRegistrarInterface registrar(REGISTRAR_SERVICE, REGISTRAR_PATH, connection, this); - QDBusPendingReply<> r = registrar.RegisterWindow(m_windowId, QDBusObjectPath(m_objectPath)); - r.waitForFinished(); - if (r.isError()) { - qWarning("Failed to register window menu, reason: %s (\"%s\")", - qUtf8Printable(r.error().name()), qUtf8Printable(r.error().message())); - connection.unregisterObject(m_objectPath); - } -} - -void QDBusMenuBar::unregisterMenuBar() -{ - QDBusConnection connection = QDBusConnection::sessionBus(); - - if (m_windowId) { - QDBusMenuRegistrarInterface registrar(REGISTRAR_SERVICE, REGISTRAR_PATH, connection, this); - QDBusPendingReply<> r = registrar.UnregisterWindow(m_windowId); - r.waitForFinished(); - if (r.isError()) - qWarning("Failed to unregister window menu, reason: %s (\"%s\")", - qUtf8Printable(r.error().name()), qUtf8Printable(r.error().message())); - } - - if (!m_objectPath.isEmpty()) - connection.unregisterObject(m_objectPath); -} - -QT_END_NAMESPACE diff --git a/src/platformsupport/dbusmenu/qdbusmenubar_p.h b/src/platformsupport/dbusmenu/qdbusmenubar_p.h deleted file mode 100644 index 8266a395f5..0000000000 --- a/src/platformsupport/dbusmenu/qdbusmenubar_p.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Dmitry Shachnev -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QDBUSMENUBAR_P_H -#define QDBUSMENUBAR_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class QDBusMenuBar : public QPlatformMenuBar -{ - Q_OBJECT - -public: - QDBusMenuBar(); - virtual ~QDBusMenuBar(); - - void insertMenu(QPlatformMenu *menu, QPlatformMenu *before) Q_DECL_OVERRIDE; - void removeMenu(QPlatformMenu *menu) Q_DECL_OVERRIDE; - void syncMenu(QPlatformMenu *menu) Q_DECL_OVERRIDE; - void handleReparent(QWindow *newParentWindow) Q_DECL_OVERRIDE; - QPlatformMenu *menuForTag(quintptr tag) const Q_DECL_OVERRIDE; - QPlatformMenu *createMenu() const Q_DECL_OVERRIDE; - -private: - QDBusPlatformMenu *m_menu; - QDBusMenuAdaptor *m_menuAdaptor; - QHash m_menuItems; - uint m_windowId; - QString m_objectPath; - - QDBusPlatformMenuItem *menuItemForMenu(QPlatformMenu *menu); - static void updateMenuItem(QDBusPlatformMenuItem *item, QPlatformMenu *menu); - void registerMenuBar(); - void unregisterMenuBar(); -}; - -QT_END_NAMESPACE - -#endif // QDBUSMENUBAR_P_H diff --git a/src/platformsupport/dbusmenu/qdbusmenuconnection.cpp b/src/platformsupport/dbusmenu/qdbusmenuconnection.cpp deleted file mode 100644 index 361146dc23..0000000000 --- a/src/platformsupport/dbusmenu/qdbusmenuconnection.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT_NO_SYSTEMTRAYICON -#include "qdbustrayicon_p.h" -#endif -#include "qdbusmenuconnection_p.h" -#include "qdbusmenuadaptor_p.h" -#include "qdbusplatformmenu_p.h" - -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -Q_DECLARE_LOGGING_CATEGORY(qLcMenu) - -const QString StatusNotifierWatcherService = QLatin1String("org.kde.StatusNotifierWatcher"); -const QString StatusNotifierWatcherPath = QLatin1String("/StatusNotifierWatcher"); -const QString StatusNotifierItemPath = QLatin1String("/StatusNotifierItem"); -const QString MenuBarPath = QLatin1String("/MenuBar"); - -/*! - \class QDBusMenuConnection - \internal - A D-Bus connection which is used for both menu and tray icon services. - Connects to the session bus and registers with the respective watcher services. -*/ -QDBusMenuConnection::QDBusMenuConnection(QObject *parent, const QString &serviceName) - : QObject(parent) - , m_connection(serviceName.isNull() ? QDBusConnection::sessionBus() - : QDBusConnection::connectToBus(QDBusConnection::SessionBus, serviceName)) - , m_dbusWatcher(new QDBusServiceWatcher(StatusNotifierWatcherService, m_connection, QDBusServiceWatcher::WatchForRegistration, this)) - , m_statusNotifierHostRegistered(false) -{ -#ifndef QT_NO_SYSTEMTRAYICON - QDBusInterface systrayHost(StatusNotifierWatcherService, StatusNotifierWatcherPath, StatusNotifierWatcherService, m_connection); - if (systrayHost.isValid() && systrayHost.property("IsStatusNotifierHostRegistered").toBool()) - m_statusNotifierHostRegistered = true; - else - qCDebug(qLcMenu) << "StatusNotifierHost is not registered"; -#endif -} - -void QDBusMenuConnection::dbusError(const QDBusError &error) -{ - qWarning() << "QDBusTrayIcon encountered a D-Bus error:" << error; -} - -#ifndef QT_NO_SYSTEMTRAYICON -bool QDBusMenuConnection::registerTrayIconMenu(QDBusTrayIcon *item) -{ - bool success = connection().registerObject(MenuBarPath, item->menu()); - if (!success) // success == false is normal, because the object may be already registered - qCDebug(qLcMenu) << "failed to register" << item->instanceId() << MenuBarPath; - return success; -} - -bool QDBusMenuConnection::registerTrayIcon(QDBusTrayIcon *item) -{ - bool success = connection().registerService(item->instanceId()); - if (!success) { - qWarning() << "failed to register service" << item->instanceId(); - return false; - } - - success = connection().registerObject(StatusNotifierItemPath, item); - if (!success) { - unregisterTrayIcon(item); - qWarning() << "failed to register" << item->instanceId() << StatusNotifierItemPath; - return false; - } - - if (item->menu()) - registerTrayIconMenu(item); - - QDBusMessage registerMethod = QDBusMessage::createMethodCall( - StatusNotifierWatcherService, StatusNotifierWatcherPath, StatusNotifierWatcherService, - QLatin1String("RegisterStatusNotifierItem")); - registerMethod.setArguments(QVariantList() << item->instanceId()); - success = m_connection.callWithCallback(registerMethod, this, SIGNAL(trayIconRegistered()), SLOT(dbusError(QDBusError))); - - return success; -} - -bool QDBusMenuConnection::unregisterTrayIcon(QDBusTrayIcon *item) -{ - connection().unregisterObject(MenuBarPath); - connection().unregisterObject(StatusNotifierItemPath); - bool success = connection().unregisterService(item->instanceId()); - if (!success) - qWarning() << "failed to unregister service" << item->instanceId(); - return success; -} -#endif // QT_NO_SYSTEMTRAYICON - -QT_END_NAMESPACE diff --git a/src/platformsupport/dbusmenu/qdbusmenuconnection_p.h b/src/platformsupport/dbusmenu/qdbusmenuconnection_p.h deleted file mode 100644 index 84eb2a6f3a..0000000000 --- a/src/platformsupport/dbusmenu/qdbusmenuconnection_p.h +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DBUSCONNECTION_H -#define DBUSCONNECTION_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class QDBusServiceWatcher; -#ifndef QT_NO_SYSTEMTRAYICON -class QDBusTrayIcon; -#endif // QT_NO_SYSTEMTRAYICON - -class QDBusMenuConnection : public QObject -{ - Q_OBJECT - -public: - QDBusMenuConnection(QObject *parent = 0, const QString &serviceName = QString()); - QDBusConnection connection() const { return m_connection; } - bool isStatusNotifierHostRegistered() const { return m_statusNotifierHostRegistered; } -#ifndef QT_NO_SYSTEMTRAYICON - bool registerTrayIconMenu(QDBusTrayIcon *item); - bool registerTrayIcon(QDBusTrayIcon *item); - bool unregisterTrayIcon(QDBusTrayIcon *item); -#endif // QT_NO_SYSTEMTRAYICON - -Q_SIGNALS: -#ifndef QT_NO_SYSTEMTRAYICON - void trayIconRegistered(); -#endif // QT_NO_SYSTEMTRAYICON - -private Q_SLOTS: - void dbusError(const QDBusError &error); - -private: - QDBusConnection m_connection; - QDBusServiceWatcher *m_dbusWatcher; - bool m_statusNotifierHostRegistered; -}; - -QT_END_NAMESPACE - -#endif // DBUSCONNECTION_H diff --git a/src/platformsupport/dbusmenu/qdbusmenuregistrarproxy.cpp b/src/platformsupport/dbusmenu/qdbusmenuregistrarproxy.cpp deleted file mode 100644 index c59b5a675e..0000000000 --- a/src/platformsupport/dbusmenu/qdbusmenuregistrarproxy.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Dmitry Shachnev -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/* - * This file was originally created by qdbusxml2cpp version 0.8 - * Command line was: qdbusxml2cpp -p qdbusmenuregistrarproxy ../../3rdparty/dbus-ifaces/com.canonical.AppMenu.Registrar.xml - * - * However it is maintained manually. - */ - -#include "qdbusmenuregistrarproxy_p.h" - -QT_BEGIN_NAMESPACE - -/* - * Implementation of interface class QDBusMenuRegistrarInterface - */ - -QDBusMenuRegistrarInterface::QDBusMenuRegistrarInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) - : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) -{ -} - -QDBusMenuRegistrarInterface::~QDBusMenuRegistrarInterface() -{ -} - -QT_END_NAMESPACE diff --git a/src/platformsupport/dbusmenu/qdbusmenuregistrarproxy_p.h b/src/platformsupport/dbusmenu/qdbusmenuregistrarproxy_p.h deleted file mode 100644 index c92de0a140..0000000000 --- a/src/platformsupport/dbusmenu/qdbusmenuregistrarproxy_p.h +++ /dev/null @@ -1,127 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Dmitry Shachnev -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/* - * This file was originally created by qdbusxml2cpp version 0.8 - * Command line was: qdbusxml2cpp -p qdbusmenuregistrarproxy ../../3rdparty/dbus-ifaces/com.canonical.AppMenu.Registrar.xml - * - * However it is maintained manually. - */ - -#ifndef QDBUSMENUREGISTRARPROXY_P_H -#define QDBUSMENUREGISTRARPROXY_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -#include -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -/* - * Proxy class for interface com.canonical.AppMenu.Registrar - */ -class QDBusMenuRegistrarInterface : public QDBusAbstractInterface -{ - Q_OBJECT -public: - static inline const char *staticInterfaceName() - { - return "com.canonical.AppMenu.Registrar"; - } - -public: - explicit QDBusMenuRegistrarInterface(const QString &service, - const QString &path, - const QDBusConnection &connection, - QObject *parent = nullptr); - - ~QDBusMenuRegistrarInterface(); - -public Q_SLOTS: // METHODS - QDBusPendingReply GetMenuForWindow(uint windowId) - { - QList argumentList; - argumentList << QVariant::fromValue(windowId); - return asyncCallWithArgumentList(QStringLiteral("GetMenuForWindow"), argumentList); - } - QDBusReply GetMenuForWindow(uint windowId, QDBusObjectPath &menuObjectPath) - { - QList argumentList; - argumentList << QVariant::fromValue(windowId); - QDBusMessage reply = callWithArgumentList(QDBus::Block, QStringLiteral("GetMenuForWindow"), argumentList); - QList arguments = reply.arguments(); - if (reply.type() == QDBusMessage::ReplyMessage && arguments.count() == 2) - menuObjectPath = qdbus_cast(arguments.at(1)); - return reply; - } - - QDBusPendingReply<> RegisterWindow(uint windowId, const QDBusObjectPath &menuObjectPath) - { - QList argumentList; - argumentList << QVariant::fromValue(windowId) << QVariant::fromValue(menuObjectPath); - return asyncCallWithArgumentList(QStringLiteral("RegisterWindow"), argumentList); - } - - QDBusPendingReply<> UnregisterWindow(uint windowId) - { - QList argumentList; - argumentList << QVariant::fromValue(windowId); - return asyncCallWithArgumentList(QStringLiteral("UnregisterWindow"), argumentList); - } -}; - -QT_END_NAMESPACE - -#endif // QDBUSMENUREGISTRARPROXY_P_H diff --git a/src/platformsupport/dbusmenu/qdbusmenutypes.cpp b/src/platformsupport/dbusmenu/qdbusmenutypes.cpp deleted file mode 100644 index 82a13d2fa0..0000000000 --- a/src/platformsupport/dbusmenu/qdbusmenutypes.cpp +++ /dev/null @@ -1,301 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qdbusmenutypes_p.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "qdbusplatformmenu_p.h" - -QT_BEGIN_NAMESPACE - -const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuItem &item) -{ - arg.beginStructure(); - arg << item.m_id << item.m_properties; - arg.endStructure(); - return arg; -} - -const QDBusArgument &operator>>(const QDBusArgument &arg, QDBusMenuItem &item) -{ - arg.beginStructure(); - arg >> item.m_id >> item.m_properties; - arg.endStructure(); - return arg; -} - -const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuItemKeys &keys) -{ - arg.beginStructure(); - arg << keys.id << keys.properties; - arg.endStructure(); - return arg; -} - -const QDBusArgument &operator>>(const QDBusArgument &arg, QDBusMenuItemKeys &keys) -{ - arg.beginStructure(); - arg >> keys.id >> keys.properties; - arg.endStructure(); - return arg; -} - -uint QDBusMenuLayoutItem::populate(int id, int depth, const QStringList &propertyNames, const QDBusPlatformMenu *topLevelMenu) -{ - qCDebug(qLcMenu) << id << "depth" << depth << propertyNames; - m_id = id; - if (id == 0) { - m_properties.insert(QLatin1String("children-display"), QLatin1String("submenu")); - if (topLevelMenu) - populate(topLevelMenu, depth, propertyNames); - return 1; // revision - } - - QDBusPlatformMenuItem *item = QDBusPlatformMenuItem::byId(id); - if (item) { - const QDBusPlatformMenu *menu = static_cast(item->menu()); - - if (menu) { - if (depth != 0) - populate(menu, depth, propertyNames); - return menu->revision(); - } - } - - return 1; // revision -} - -void QDBusMenuLayoutItem::populate(const QDBusPlatformMenu *menu, int depth, const QStringList &propertyNames) -{ - const auto items = menu->items(); - for (QDBusPlatformMenuItem *item : items) { - QDBusMenuLayoutItem child; - child.populate(item, depth - 1, propertyNames); - m_children << child; - } -} - -void QDBusMenuLayoutItem::populate(const QDBusPlatformMenuItem *item, int depth, const QStringList &propertyNames) -{ - m_id = item->dbusID(); - QDBusMenuItem proxy(item); - m_properties = proxy.m_properties; - - const QDBusPlatformMenu *menu = static_cast(item->menu()); - if (depth != 0 && menu) - populate(menu, depth, propertyNames); -} - -const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuLayoutItem &item) -{ - arg.beginStructure(); - arg << item.m_id << item.m_properties; - arg.beginArray(qMetaTypeId()); - for (const QDBusMenuLayoutItem &child : item.m_children) - arg << QDBusVariant(QVariant::fromValue(child)); - arg.endArray(); - arg.endStructure(); - return arg; -} - -const QDBusArgument &operator>>(const QDBusArgument &arg, QDBusMenuLayoutItem &item) -{ - arg.beginStructure(); - arg >> item.m_id >> item.m_properties; - arg.beginArray(); - while (!arg.atEnd()) { - QDBusVariant dbusVariant; - arg >> dbusVariant; - QDBusArgument childArgument = dbusVariant.variant().value(); - - QDBusMenuLayoutItem child; - childArgument >> child; - item.m_children.append(child); - } - arg.endArray(); - arg.endStructure(); - return arg; -} - -void QDBusMenuItem::registerDBusTypes() -{ - qDBusRegisterMetaType(); - qDBusRegisterMetaType(); - qDBusRegisterMetaType(); - qDBusRegisterMetaType(); - qDBusRegisterMetaType(); - qDBusRegisterMetaType(); - qDBusRegisterMetaType(); - qDBusRegisterMetaType(); - qDBusRegisterMetaType(); -} - -QDBusMenuItem::QDBusMenuItem(const QDBusPlatformMenuItem *item) - : m_id(item->dbusID()) -{ - if (item->isSeparator()) { - m_properties.insert(QLatin1String("type"), QLatin1String("separator")); - } else { - m_properties.insert(QLatin1String("label"), convertMnemonic(item->text())); - if (item->menu()) - m_properties.insert(QLatin1String("children-display"), QLatin1String("submenu")); - m_properties.insert(QLatin1String("enabled"), item->isEnabled()); - if (item->isCheckable()) { - QString toggleType = item->hasExclusiveGroup() ? QLatin1String("radio") : QLatin1String("checkmark"); - m_properties.insert(QLatin1String("toggle-type"), toggleType); - m_properties.insert(QLatin1String("toggle-state"), item->isChecked() ? 1 : 0); - } -#ifndef QT_NO_SHORTCUT - const QKeySequence &scut = item->shortcut(); - if (!scut.isEmpty()) { - QDBusMenuShortcut shortcut = convertKeySequence(scut); - m_properties.insert(QLatin1String("shortcut"), QVariant::fromValue(shortcut)); - } -#endif - const QIcon &icon = item->icon(); - if (!icon.name().isEmpty()) { - m_properties.insert(QLatin1String("icon-name"), icon.name()); - } else if (!icon.isNull()) { - QBuffer buf; - icon.pixmap(16).save(&buf, "PNG"); - m_properties.insert(QLatin1String("icon-data"), buf.data()); - } - } - m_properties.insert(QLatin1String("visible"), item->isVisible()); -} - -QDBusMenuItemList QDBusMenuItem::items(const QList &ids, const QStringList &propertyNames) -{ - Q_UNUSED(propertyNames) - QDBusMenuItemList ret; - const QList items = QDBusPlatformMenuItem::byIds(ids); - ret.reserve(items.size()); - for (const QDBusPlatformMenuItem *item : items) - ret << QDBusMenuItem(item); - return ret; -} - -QString QDBusMenuItem::convertMnemonic(const QString &label) -{ - // convert only the first occurrence of ampersand which is not at the end - // dbusmenu uses underscore instead of ampersand - int idx = label.indexOf(QLatin1Char('&')); - if (idx < 0 || idx == label.length() - 1) - return label; - QString ret(label); - ret[idx] = QLatin1Char('_'); - return ret; -} - -#ifndef QT_NO_SHORTCUT -QDBusMenuShortcut QDBusMenuItem::convertKeySequence(const QKeySequence &sequence) -{ - QDBusMenuShortcut shortcut; - for (int i = 0; i < sequence.count(); ++i) { - QStringList tokens; - int key = sequence[i]; - if (key & Qt::MetaModifier) - tokens << QStringLiteral("Super"); - if (key & Qt::ControlModifier) - tokens << QStringLiteral("Control"); - if (key & Qt::AltModifier) - tokens << QStringLiteral("Alt"); - if (key & Qt::ShiftModifier) - tokens << QStringLiteral("Shift"); - if (key & Qt::KeypadModifier) - tokens << QStringLiteral("Num"); - - QString keyName = QKeySequencePrivate::keyName(key, QKeySequence::PortableText); - if (keyName == QLatin1String("+")) - tokens << QStringLiteral("plus"); - else if (keyName == QLatin1String("-")) - tokens << QStringLiteral("minus"); - else - tokens << keyName; - shortcut << tokens; - } - return shortcut; -} -#endif - -const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuEvent &ev) -{ - arg.beginStructure(); - arg << ev.m_id << ev.m_eventId << ev.m_data << ev.m_timestamp; - arg.endStructure(); - return arg; -} - -const QDBusArgument &operator>>(const QDBusArgument &arg, QDBusMenuEvent &ev) -{ - arg.beginStructure(); - arg >> ev.m_id >> ev.m_eventId >> ev.m_data >> ev.m_timestamp; - arg.endStructure(); - return arg; -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const QDBusMenuItem &item) -{ - QDebugStateSaver saver(d); - d.nospace(); - d << "QDBusMenuItem(id=" << item.m_id << ", properties=" << item.m_properties << ')'; - return d; -} - -QDebug operator<<(QDebug d, const QDBusMenuLayoutItem &item) -{ - QDebugStateSaver saver(d); - d.nospace(); - d << "QDBusMenuLayoutItem(id=" << item.m_id << ", properties=" << item.m_properties << ", " << item.m_children.count() << " children)"; - return d; -} -#endif - -QT_END_NAMESPACE diff --git a/src/platformsupport/dbusmenu/qdbusmenutypes_p.h b/src/platformsupport/dbusmenu/qdbusmenutypes_p.h deleted file mode 100644 index fd6727d3be..0000000000 --- a/src/platformsupport/dbusmenu/qdbusmenutypes_p.h +++ /dev/null @@ -1,155 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QDBUSMENUTYPES_H -#define QDBUSMENUTYPES_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class QDBusPlatformMenu; -class QDBusPlatformMenuItem; -class QDBusMenuItem; -typedef QVector QDBusMenuItemList; -typedef QVector QDBusMenuShortcut; - -class QDBusMenuItem -{ -public: - QDBusMenuItem() { } - QDBusMenuItem(const QDBusPlatformMenuItem *item); - - static QDBusMenuItemList items(const QList &ids, const QStringList &propertyNames); - static QString convertMnemonic(const QString &label); -#ifndef QT_NO_SHORTCUT - static QDBusMenuShortcut convertKeySequence(const QKeySequence &sequence); -#endif - static void registerDBusTypes(); - - int m_id; - QVariantMap m_properties; -}; -Q_DECLARE_TYPEINFO(QDBusMenuItem, Q_MOVABLE_TYPE); - -const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuItem &item); -const QDBusArgument &operator>>(const QDBusArgument &arg, QDBusMenuItem &item); - -class QDBusMenuItemKeys -{ -public: - - int id; - QStringList properties; -}; -Q_DECLARE_TYPEINFO(QDBusMenuItemKeys, Q_MOVABLE_TYPE); - -const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuItemKeys &keys); -const QDBusArgument &operator>>(const QDBusArgument &arg, QDBusMenuItemKeys &keys); - -typedef QVector QDBusMenuItemKeysList; - -class QDBusMenuLayoutItem -{ -public: - uint populate(int id, int depth, const QStringList &propertyNames, const QDBusPlatformMenu *topLevelMenu); - void populate(const QDBusPlatformMenu *menu, int depth, const QStringList &propertyNames); - void populate(const QDBusPlatformMenuItem *item, int depth, const QStringList &propertyNames); - - int m_id; - QVariantMap m_properties; - QVector m_children; -}; -Q_DECLARE_TYPEINFO(QDBusMenuLayoutItem, Q_MOVABLE_TYPE); - -const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuLayoutItem &); -const QDBusArgument &operator>>(const QDBusArgument &arg, QDBusMenuLayoutItem &item); - -typedef QVector QDBusMenuLayoutItemList; - -class QDBusMenuEvent -{ -public: - int m_id; - QString m_eventId; - QDBusVariant m_data; - uint m_timestamp; -}; -Q_DECLARE_TYPEINFO(QDBusMenuEvent, Q_MOVABLE_TYPE); // QDBusVariant is movable, even though it cannot - // be marked as such until Qt 6. - -const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuEvent &ev); -const QDBusArgument &operator>>(const QDBusArgument &arg, QDBusMenuEvent &ev); - -typedef QVector QDBusMenuEventList; - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const QDBusMenuItem &item); -QDebug operator<<(QDebug d, const QDBusMenuLayoutItem &item); -#endif - -QT_END_NAMESPACE - -Q_DECLARE_METATYPE(QDBusMenuItem) -Q_DECLARE_METATYPE(QDBusMenuItemList) -Q_DECLARE_METATYPE(QDBusMenuItemKeys) -Q_DECLARE_METATYPE(QDBusMenuItemKeysList) -Q_DECLARE_METATYPE(QDBusMenuLayoutItem) -Q_DECLARE_METATYPE(QDBusMenuLayoutItemList) -Q_DECLARE_METATYPE(QDBusMenuEvent) -Q_DECLARE_METATYPE(QDBusMenuEventList) -Q_DECLARE_METATYPE(QDBusMenuShortcut) - -#endif diff --git a/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp b/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp deleted file mode 100644 index 15440a03cd..0000000000 --- a/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp +++ /dev/null @@ -1,307 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qdbusplatformmenu_p.h" - -#include -#include - -QT_BEGIN_NAMESPACE - -Q_LOGGING_CATEGORY(qLcMenu, "qt.qpa.menu") - -static int nextDBusID = 1; -QHash menuItemsByID; - -QDBusPlatformMenuItem::QDBusPlatformMenuItem(quintptr tag) - : m_tag(tag ? tag : reinterpret_cast(this)) // QMenu will overwrite this later - , m_subMenu(Q_NULLPTR) - , m_role(NoRole) - , m_isEnabled(true) - , m_isVisible(true) - , m_isSeparator(false) - , m_isCheckable(false) - , m_isChecked(false) - , m_dbusID(nextDBusID++) - , m_hasExclusiveGroup(false) -{ - menuItemsByID.insert(m_dbusID, this); -} - -QDBusPlatformMenuItem::~QDBusPlatformMenuItem() -{ - menuItemsByID.remove(m_dbusID); - if (m_subMenu) - static_cast(m_subMenu)->setContainingMenuItem(Q_NULLPTR); -} - -void QDBusPlatformMenuItem::setTag(quintptr tag) -{ - m_tag = tag; -} - -void QDBusPlatformMenuItem::setText(const QString &text) -{ - qCDebug(qLcMenu) << m_dbusID << text; - m_text = text; -} - -void QDBusPlatformMenuItem::setIcon(const QIcon &icon) -{ - m_icon = icon; -} - -/*! - Set a submenu under this menu item. -*/ -void QDBusPlatformMenuItem::setMenu(QPlatformMenu *menu) -{ - if (m_subMenu) - static_cast(m_subMenu)->setContainingMenuItem(Q_NULLPTR); - m_subMenu = menu; - if (menu) - static_cast(menu)->setContainingMenuItem(this); -} - -void QDBusPlatformMenuItem::setEnabled(bool enabled) -{ - m_isEnabled = enabled; -} - -void QDBusPlatformMenuItem::setVisible(bool isVisible) -{ - m_isVisible = isVisible; -} - -void QDBusPlatformMenuItem::setIsSeparator(bool isSeparator) -{ - m_isSeparator = isSeparator; -} - -void QDBusPlatformMenuItem::setRole(QPlatformMenuItem::MenuRole role) -{ - m_role = role; -} - -void QDBusPlatformMenuItem::setCheckable(bool checkable) -{ - m_isCheckable = checkable; -} - -void QDBusPlatformMenuItem::setChecked(bool isChecked) -{ - m_isChecked = isChecked; -} - -void QDBusPlatformMenuItem::setHasExclusiveGroup(bool hasExclusiveGroup) -{ - m_hasExclusiveGroup = hasExclusiveGroup; -} - -#ifndef QT_NO_SHORTCUT -void QDBusPlatformMenuItem::setShortcut(const QKeySequence &shortcut) -{ - m_shortcut = shortcut; -} -#endif - -void QDBusPlatformMenuItem::trigger() -{ - emit activated(); -} - -QDBusPlatformMenuItem *QDBusPlatformMenuItem::byId(int id) -{ - // We need to check contains because otherwise QHash would insert - // a default-constructed nullptr value into menuItemsByID - if (menuItemsByID.contains(id)) - return menuItemsByID[id]; - return Q_NULLPTR; -} - -QList QDBusPlatformMenuItem::byIds(const QList &ids) -{ - QList ret; - for (int id : ids) { - if (menuItemsByID.contains(id)) - ret << menuItemsByID[id]; - } - return ret; -} - - -QDBusPlatformMenu::QDBusPlatformMenu(quintptr tag) - : m_tag(tag ? tag : reinterpret_cast(this)) - , m_isEnabled(true) - , m_isVisible(true) - , m_isSeparator(false) - , m_revision(1) - , m_containingMenuItem(Q_NULLPTR) -{ -} - -QDBusPlatformMenu::~QDBusPlatformMenu() -{ - if (m_containingMenuItem) - m_containingMenuItem->setMenu(Q_NULLPTR); -} - -void QDBusPlatformMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) -{ - QDBusPlatformMenuItem *item = static_cast(menuItem); - QDBusPlatformMenuItem *beforeItem = static_cast(before); - int idx = m_items.indexOf(beforeItem); - qCDebug(qLcMenu) << item->dbusID() << item->text(); - if (idx < 0) - m_items.append(item); - else - m_items.insert(idx, item); - m_itemsByTag.insert(item->tag(), item); - if (item->menu()) - syncSubMenu(static_cast(item->menu())); - emitUpdated(); -} - -void QDBusPlatformMenu::removeMenuItem(QPlatformMenuItem *menuItem) -{ - QDBusPlatformMenuItem *item = static_cast(menuItem); - m_items.removeAll(item); - m_itemsByTag.remove(menuItem->tag()); - if (item->menu()) { - // disconnect from the signals we connected to in syncSubMenu() - const QDBusPlatformMenu *menu = static_cast(item->menu()); - disconnect(menu, &QDBusPlatformMenu::propertiesUpdated, - this, &QDBusPlatformMenu::propertiesUpdated); - disconnect(menu, &QDBusPlatformMenu::updated, - this, &QDBusPlatformMenu::updated); - } - emitUpdated(); -} - -void QDBusPlatformMenu::syncSubMenu(const QDBusPlatformMenu *menu) -{ - // The adaptor is only connected to the propertiesUpdated signal of the top-level - // menu, so the submenus should transfer their signals to their parents. - connect(menu, &QDBusPlatformMenu::propertiesUpdated, - this, &QDBusPlatformMenu::propertiesUpdated, Qt::UniqueConnection); - connect(menu, &QDBusPlatformMenu::updated, - this, &QDBusPlatformMenu::updated, Qt::UniqueConnection); -} - -void QDBusPlatformMenu::syncMenuItem(QPlatformMenuItem *menuItem) -{ - QDBusPlatformMenuItem *item = static_cast(menuItem); - // if a submenu was added to this item, we need to connect to its signals - if (item->menu()) - syncSubMenu(static_cast(item->menu())); - // TODO keep around copies of the QDBusMenuLayoutItems so they can be updated? - // or eliminate them by putting dbus streaming operators in this class instead? - // or somehow tell the dbusmenu client that something has changed, so it will ask for properties again - QDBusMenuItemList updated; - QDBusMenuItemKeysList removed; - updated << QDBusMenuItem(item); - qCDebug(qLcMenu) << updated; - emit propertiesUpdated(updated, removed); -} - -void QDBusPlatformMenu::emitUpdated() -{ - if (m_containingMenuItem) - emit updated(++m_revision, m_containingMenuItem->dbusID()); - else - emit updated(++m_revision, 0); -} - -void QDBusPlatformMenu::setTag(quintptr tag) -{ - m_tag = tag; -} - -void QDBusPlatformMenu::setText(const QString &text) -{ - m_text = text; -} - -void QDBusPlatformMenu::setIcon(const QIcon &icon) -{ - m_icon = icon; -} - -void QDBusPlatformMenu::setEnabled(bool enabled) -{ - m_isEnabled = enabled; -} - -void QDBusPlatformMenu::setVisible(bool isVisible) -{ - m_isVisible = isVisible; -} - -void QDBusPlatformMenu::setContainingMenuItem(QDBusPlatformMenuItem *item) -{ - m_containingMenuItem = item; -} - -QPlatformMenuItem *QDBusPlatformMenu::menuItemAt(int position) const -{ - return m_items.value(position); -} - -QPlatformMenuItem *QDBusPlatformMenu::menuItemForTag(quintptr tag) const -{ - return m_itemsByTag[tag]; -} - -const QList QDBusPlatformMenu::items() const -{ - return m_items; -} - -QPlatformMenuItem *QDBusPlatformMenu::createMenuItem() const -{ - QDBusPlatformMenuItem *ret = new QDBusPlatformMenuItem(); - return ret; -} - -QPlatformMenu *QDBusPlatformMenu::createSubMenu() const -{ - return new QDBusPlatformMenu; -} - -QT_END_NAMESPACE diff --git a/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h b/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h deleted file mode 100644 index 38c27e8051..0000000000 --- a/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h +++ /dev/null @@ -1,207 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QDBUSPLATFORMMENU_H -#define QDBUSPLATFORMMENU_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// -// -// W A R N I N G -// ------------- -// -// This file is part of the DBus menu support and is not meant to be used -// in applications. Usage of this API may make your code -// source and binary incompatible with future versions of Qt. -// - -#include -#include -#include "qdbusmenutypes_p.h" - -QT_BEGIN_NAMESPACE -Q_DECLARE_LOGGING_CATEGORY(qLcMenu) - -class QDBusPlatformMenu; - -class QDBusPlatformMenuItem : public QPlatformMenuItem -{ - Q_OBJECT - -public: - QDBusPlatformMenuItem(quintptr tag = 0LL); - ~QDBusPlatformMenuItem(); - - quintptr tag()const Q_DECL_OVERRIDE { return m_tag; } - void setTag(quintptr tag) Q_DECL_OVERRIDE; - - const QString text() const { return m_text; } - void setText(const QString &text) Q_DECL_OVERRIDE; - QIcon icon() const { return m_icon; } - void setIcon(const QIcon &icon) Q_DECL_OVERRIDE; - const QPlatformMenu *menu() const { return m_subMenu; } - void setMenu(QPlatformMenu *menu) Q_DECL_OVERRIDE; - bool isEnabled() const { return m_isEnabled; } - void setEnabled(bool enabled) Q_DECL_OVERRIDE; - bool isVisible() const { return m_isVisible; } - void setVisible(bool isVisible) Q_DECL_OVERRIDE; - bool isSeparator() const { return m_isSeparator; } - void setIsSeparator(bool isSeparator) Q_DECL_OVERRIDE; - void setFont(const QFont &font) Q_DECL_OVERRIDE { Q_UNUSED(font); } - void setRole(MenuRole role) Q_DECL_OVERRIDE; - bool isCheckable() const { return m_isCheckable; } - void setCheckable(bool checkable) Q_DECL_OVERRIDE; - bool isChecked() const { return m_isChecked; } - void setChecked(bool isChecked) Q_DECL_OVERRIDE; - bool hasExclusiveGroup() const { return m_hasExclusiveGroup; } - void setHasExclusiveGroup(bool hasExclusiveGroup) Q_DECL_OVERRIDE; -#ifndef QT_NO_SHORTCUT - QKeySequence shortcut() const { return m_shortcut; } - void setShortcut(const QKeySequence& shortcut) Q_DECL_OVERRIDE; -#endif - void setIconSize(int size) Q_DECL_OVERRIDE { Q_UNUSED(size); } - void setNativeContents(WId item) Q_DECL_OVERRIDE { Q_UNUSED(item); } - - int dbusID() const { return m_dbusID; } - - void trigger(); - - bool operator==(const QDBusPlatformMenuItem& other) { return m_tag == other.m_tag; } - - static QDBusPlatformMenuItem *byId(int id); - static QList byIds(const QList &ids); - -private: - quintptr m_tag; - QString m_text; - QIcon m_icon; - QPlatformMenu *m_subMenu; - MenuRole m_role : 4; - bool m_isEnabled : 1; - bool m_isVisible : 1; - bool m_isSeparator : 1; - bool m_isCheckable : 1; - bool m_isChecked : 1; - int m_dbusID : 16; - bool m_hasExclusiveGroup : 1; - int m_reserved : 6; - QKeySequence m_shortcut; -}; - -class QDBusPlatformMenu : public QPlatformMenu -{ - Q_OBJECT - -public: - QDBusPlatformMenu(quintptr tag = 0LL); - ~QDBusPlatformMenu(); - void insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) Q_DECL_OVERRIDE; - void removeMenuItem(QPlatformMenuItem *menuItem) Q_DECL_OVERRIDE; - void syncSubMenu(const QDBusPlatformMenu *menu); - void syncMenuItem(QPlatformMenuItem *menuItem) Q_DECL_OVERRIDE; - void syncSeparatorsCollapsible(bool enable) Q_DECL_OVERRIDE { Q_UNUSED(enable); } - - quintptr tag()const Q_DECL_OVERRIDE { return m_tag; } - void setTag(quintptr tag) Q_DECL_OVERRIDE; - - const QString text() const { return m_text; } - void setText(const QString &text) Q_DECL_OVERRIDE; - QIcon icon() const { return m_icon; } - void setIcon(const QIcon &icon) Q_DECL_OVERRIDE; - bool isEnabled() const Q_DECL_OVERRIDE { return m_isEnabled; } - void setEnabled(bool enabled) Q_DECL_OVERRIDE; - bool isVisible() const { return m_isVisible; } - void setVisible(bool visible) Q_DECL_OVERRIDE; - void setMinimumWidth(int width) Q_DECL_OVERRIDE { Q_UNUSED(width); } - void setFont(const QFont &font) Q_DECL_OVERRIDE { Q_UNUSED(font); } - void setMenuType(MenuType type) Q_DECL_OVERRIDE { Q_UNUSED(type); } - void setContainingMenuItem(QDBusPlatformMenuItem *item); - - void showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item) Q_DECL_OVERRIDE - { - Q_UNUSED(parentWindow); - Q_UNUSED(targetRect); - Q_UNUSED(item); - setVisible(true); - } - - void dismiss() Q_DECL_OVERRIDE { } // Closes this and all its related menu popups - - QPlatformMenuItem *menuItemAt(int position) const Q_DECL_OVERRIDE; - QPlatformMenuItem *menuItemForTag(quintptr tag) const Q_DECL_OVERRIDE; - const QList items() const; - - QPlatformMenuItem *createMenuItem() const Q_DECL_OVERRIDE; - QPlatformMenu *createSubMenu() const Q_DECL_OVERRIDE; - - bool operator==(const QDBusPlatformMenu& other) { return m_tag == other.m_tag; } - - uint revision() const { return m_revision; } - - void emitUpdated(); - -signals: - void updated(uint revision, int dbusId); - void propertiesUpdated(QDBusMenuItemList updatedProps, QDBusMenuItemKeysList removedProps); - -private: - quintptr m_tag; - QString m_text; - QIcon m_icon; - bool m_isEnabled; - bool m_isVisible; - bool m_isSeparator; - uint m_revision; - QHash m_itemsByTag; - QList m_items; - QDBusPlatformMenuItem *m_containingMenuItem; -}; - -QT_END_NAMESPACE - -#endif - diff --git a/src/platformsupport/dbustray/dbustray.pri b/src/platformsupport/dbustray/dbustray.pri deleted file mode 100644 index f703e24ba9..0000000000 --- a/src/platformsupport/dbustray/dbustray.pri +++ /dev/null @@ -1,15 +0,0 @@ -QT_FOR_PRIVATE += dbus - -INCLUDEPATH += $$PWD - -HEADERS += \ - $$PWD/qdbustrayicon_p.h \ - $$PWD/qdbustraytypes_p.h \ - $$PWD/qstatusnotifieritemadaptor_p.h \ - $$PWD/qxdgnotificationproxy_p.h \ - -SOURCES += \ - $$PWD/qdbustrayicon.cpp \ - $$PWD/qdbustraytypes.cpp \ - $$PWD/qstatusnotifieritemadaptor.cpp \ - $$PWD/qxdgnotificationproxy.cpp \ diff --git a/src/platformsupport/dbustray/qdbustrayicon.cpp b/src/platformsupport/dbustray/qdbustrayicon.cpp deleted file mode 100644 index 36939b467e..0000000000 --- a/src/platformsupport/dbustray/qdbustrayicon.cpp +++ /dev/null @@ -1,305 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qdbustrayicon_p.h" - -#ifndef QT_NO_SYSTEMTRAYICON - -#include "qdbusmenuconnection_p.h" -#include "qstatusnotifieritemadaptor_p.h" -#include "qdbusmenuadaptor_p.h" -#include "dbusmenu/qdbusplatformmenu_p.h" -#include "qxdgnotificationproxy_p.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Defined in Windows headers which get included by qlockfile_p.h -#undef interface - -QT_BEGIN_NAMESPACE - -Q_LOGGING_CATEGORY(qLcTray, "qt.qpa.tray") - -static const QString KDEItemFormat = QStringLiteral("org.kde.StatusNotifierItem-%1-%2"); -static const QString KDEWatcherService = QStringLiteral("org.kde.StatusNotifierWatcher"); -static const QString TempFileTemplate = QDir::tempPath() + QLatin1String("/qt-trayicon-XXXXXX.png"); -static const QString XdgNotificationService = QStringLiteral("org.freedesktop.Notifications"); -static const QString XdgNotificationPath = QStringLiteral("/org/freedesktop/Notifications"); -static const QString DefaultAction = QStringLiteral("default"); -static int instanceCount = 0; - -/*! - \class QDBusTrayIcon - \internal -*/ - -QDBusTrayIcon::QDBusTrayIcon() - : m_dbusConnection(Q_NULLPTR) - , m_adaptor(new QStatusNotifierItemAdaptor(this)) - , m_menuAdaptor(Q_NULLPTR) - , m_menu(Q_NULLPTR) - , m_notifier(Q_NULLPTR) - , m_instanceId(KDEItemFormat.arg(QCoreApplication::applicationPid()).arg(++instanceCount)) - , m_category(QStringLiteral("ApplicationStatus")) - , m_defaultStatus(QStringLiteral("Active")) // be visible all the time. QSystemTrayIcon has no API to control this. - , m_status(m_defaultStatus) - , m_tempIcon(Q_NULLPTR) - , m_tempAttentionIcon(Q_NULLPTR) - , m_registered(false) -{ - qCDebug(qLcTray); - if (instanceCount == 1) { - QDBusMenuItem::registerDBusTypes(); - qDBusRegisterMetaType(); - qDBusRegisterMetaType(); - qDBusRegisterMetaType(); - } - connect(this, SIGNAL(statusChanged(QString)), m_adaptor, SIGNAL(NewStatus(QString))); - connect(this, SIGNAL(tooltipChanged()), m_adaptor, SIGNAL(NewToolTip())); - connect(this, SIGNAL(iconChanged()), m_adaptor, SIGNAL(NewIcon())); - connect(this, SIGNAL(attention()), m_adaptor, SIGNAL(NewAttentionIcon())); - connect(this, SIGNAL(attention()), m_adaptor, SIGNAL(NewTitle())); - connect(&m_attentionTimer, SIGNAL(timeout()), this, SLOT(attentionTimerExpired())); - m_attentionTimer.setSingleShot(true); -} - -QDBusTrayIcon::~QDBusTrayIcon() -{ -} - -void QDBusTrayIcon::init() -{ - qCDebug(qLcTray) << "registering" << m_instanceId; - m_registered = dBusConnection()->registerTrayIcon(this); -} - -void QDBusTrayIcon::cleanup() -{ - qCDebug(qLcTray) << "unregistering" << m_instanceId; - if (m_registered) - dBusConnection()->unregisterTrayIcon(this); - delete m_dbusConnection; - m_dbusConnection = Q_NULLPTR; - delete m_notifier; - m_notifier = Q_NULLPTR; - m_registered = false; -} - -void QDBusTrayIcon::attentionTimerExpired() -{ - m_messageTitle = QString(); - m_message = QString(); - m_attentionIcon = QIcon(); - emit attention(); - emit tooltipChanged(); - setStatus(m_defaultStatus); -} - -void QDBusTrayIcon::setStatus(const QString &status) -{ - qCDebug(qLcTray) << status; - if (m_status == status) - return; - m_status = status; - emit statusChanged(m_status); -} - -QTemporaryFile *QDBusTrayIcon::tempIcon(const QIcon &icon) -{ - // Hack for indicator-application, which doesn't handle icons sent across D-Bus: - // save the icon to a temp file and set the icon name to that filename. - static bool necessity_checked = false; - static bool necessary = false; - if (!necessity_checked) { - QDBusConnection session = QDBusConnection::sessionBus(); - uint pid = session.interface()->servicePid(KDEWatcherService).value(); - QString processName = QLockFilePrivate::processNameByPid(pid); - necessary = processName.endsWith(QLatin1String("indicator-application-service")); - necessity_checked = true; - } - if (!necessary) - return Q_NULLPTR; - qreal dpr = qGuiApp->devicePixelRatio(); - QTemporaryFile *ret = new QTemporaryFile(TempFileTemplate, this); - ret->open(); - icon.pixmap(QSize(22 * dpr, 22 * dpr)).save(ret); - ret->close(); - return ret; -} - -QDBusMenuConnection * QDBusTrayIcon::dBusConnection() -{ - if (!m_dbusConnection) { - m_dbusConnection = new QDBusMenuConnection(this, m_instanceId); - m_notifier = new QXdgNotificationInterface(XdgNotificationService, - XdgNotificationPath, m_dbusConnection->connection(), this); - connect(m_notifier, SIGNAL(NotificationClosed(uint,uint)), this, SLOT(notificationClosed(uint,uint))); - connect(m_notifier, SIGNAL(ActionInvoked(uint,QString)), this, SLOT(actionInvoked(uint,QString))); - } - return m_dbusConnection; -} - -void QDBusTrayIcon::updateIcon(const QIcon &icon) -{ - m_iconName = icon.name(); - m_icon = icon; - if (m_iconName.isEmpty()) { - if (m_tempIcon) - delete m_tempIcon; - m_tempIcon = tempIcon(icon); - if (m_tempIcon) - m_iconName = m_tempIcon->fileName(); - } - qCDebug(qLcTray) << m_iconName << icon.availableSizes(); - emit iconChanged(); -} - -void QDBusTrayIcon::updateToolTip(const QString &tooltip) -{ - qCDebug(qLcTray) << tooltip; - m_tooltip = tooltip; - emit tooltipChanged(); -} - -QPlatformMenu *QDBusTrayIcon::createMenu() const -{ - return new QDBusPlatformMenu(); -} - -void QDBusTrayIcon::updateMenu(QPlatformMenu * menu) -{ - qCDebug(qLcTray) << menu; - bool needsRegistering = !m_menu; - if (!m_menu) - m_menu = qobject_cast(menu); - if (!m_menuAdaptor) { - m_menuAdaptor = new QDBusMenuAdaptor(m_menu); - // TODO connect(m_menu, , m_menuAdaptor, SIGNAL(ItemActivationRequested(int,uint))); - connect(m_menu, SIGNAL(propertiesUpdated(QDBusMenuItemList,QDBusMenuItemKeysList)), - m_menuAdaptor, SIGNAL(ItemsPropertiesUpdated(QDBusMenuItemList,QDBusMenuItemKeysList))); - connect(m_menu, SIGNAL(updated(uint,int)), - m_menuAdaptor, SIGNAL(LayoutUpdated(uint,int))); - } - m_menu->emitUpdated(); - if (needsRegistering) - dBusConnection()->registerTrayIconMenu(this); -} - -void QDBusTrayIcon::showMessage(const QString &title, const QString &msg, const QIcon &icon, - QPlatformSystemTrayIcon::MessageIcon iconType, int msecs) -{ - m_messageTitle = title; - m_message = msg; - m_attentionIcon = icon; - QStringList notificationActions; - switch (iconType) { - case Information: - m_attentionIconName = QStringLiteral("dialog-information"); - break; - case Warning: - m_attentionIconName = QStringLiteral("dialog-warning"); - break; - case Critical: - m_attentionIconName = QStringLiteral("dialog-error"); - // If there are actions, the desktop notification may appear as a message dialog - // with button(s), which will interrupt the user and require a response. - // That is an optional feature in implementations of org.freedesktop.Notifications - notificationActions << DefaultAction << tr("OK"); - break; - default: - m_attentionIconName.clear(); - break; - } - if (m_attentionIconName.isEmpty()) { - if (m_tempAttentionIcon) - delete m_tempAttentionIcon; - m_tempAttentionIcon = tempIcon(icon); - if (m_tempAttentionIcon) - m_attentionIconName = m_tempAttentionIcon->fileName(); - } - qCDebug(qLcTray) << title << msg << - QPlatformSystemTrayIcon::metaObject()->enumerator( - QPlatformSystemTrayIcon::staticMetaObject.indexOfEnumerator("MessageIcon")).valueToKey(iconType) - << m_attentionIconName << msecs; - setStatus(QStringLiteral("NeedsAttention")); - m_attentionTimer.start(msecs); - emit tooltipChanged(); - emit attention(); - - // Desktop notification - QVariantMap hints; - // urgency levels according to https://developer.gnome.org/notification-spec/#urgency-levels - // 0 low, 1 normal, 2 critical - int urgency = static_cast(iconType) - 1; - if (urgency < 0) // no icon - urgency = 0; - hints.insert(QLatin1String("urgency"), QVariant(urgency)); - m_notifier->notify(QCoreApplication::applicationName(), 0, - m_attentionIconName, title, msg, notificationActions, hints, msecs); -} - -void QDBusTrayIcon::actionInvoked(uint id, const QString &action) -{ - qCDebug(qLcTray) << id << action; - emit messageClicked(); -} - -void QDBusTrayIcon::notificationClosed(uint id, uint reason) -{ - qCDebug(qLcTray) << id << reason; -} - -bool QDBusTrayIcon::isSystemTrayAvailable() const -{ - QDBusMenuConnection * conn = const_cast(this)->dBusConnection(); - qCDebug(qLcTray) << conn->isStatusNotifierHostRegistered(); - return conn->isStatusNotifierHostRegistered(); -} - -QT_END_NAMESPACE -#endif //QT_NO_SYSTEMTRAYICON diff --git a/src/platformsupport/dbustray/qdbustrayicon_p.h b/src/platformsupport/dbustray/qdbustrayicon_p.h deleted file mode 100644 index a383ef86fc..0000000000 --- a/src/platformsupport/dbustray/qdbustrayicon_p.h +++ /dev/null @@ -1,169 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QDBUSTRAYICON_H -#define QDBUSTRAYICON_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include - -#ifndef QT_NO_SYSTEMTRAYICON - -#include -#include -#include -#include "QtGui/qpa/qplatformsystemtrayicon.h" -#include "private/qdbusmenuconnection_p.h" - -QT_BEGIN_NAMESPACE - -class QStatusNotifierItemAdaptor; -class QDBusMenuAdaptor; -class QDBusPlatformMenu; -class QXdgNotificationInterface; - -class QDBusTrayIcon: public QPlatformSystemTrayIcon -{ - Q_OBJECT - Q_PROPERTY(QString category READ category NOTIFY categoryChanged) - Q_PROPERTY(QString status READ status NOTIFY statusChanged) - Q_PROPERTY(QString tooltip READ tooltip NOTIFY tooltipChanged) - Q_PROPERTY(QString iconName READ iconName NOTIFY iconChanged) - Q_PROPERTY(QIcon icon READ icon NOTIFY iconChanged) - Q_PROPERTY(bool isRequestingAttention READ isRequestingAttention NOTIFY attention) - Q_PROPERTY(QString attentionTitle READ attentionTitle NOTIFY attention) - Q_PROPERTY(QString attentionMessage READ attentionMessage NOTIFY attention) - Q_PROPERTY(QString attentionIconName READ attentionIconName NOTIFY attention) - Q_PROPERTY(QIcon attentionIcon READ attentionIcon NOTIFY attention) - Q_PROPERTY(QDBusPlatformMenu *menu READ menu NOTIFY menuChanged) - -public: - QDBusTrayIcon(); - - virtual ~QDBusTrayIcon(); - - QDBusMenuConnection * dBusConnection(); - - void init() Q_DECL_OVERRIDE; - void cleanup() Q_DECL_OVERRIDE; - void updateIcon(const QIcon &icon) Q_DECL_OVERRIDE; - void updateToolTip(const QString &tooltip) Q_DECL_OVERRIDE; - void updateMenu(QPlatformMenu *menu) Q_DECL_OVERRIDE; - QPlatformMenu *createMenu() const Q_DECL_OVERRIDE; - void showMessage(const QString &title, const QString &msg, - const QIcon &icon, MessageIcon iconType, int msecs) Q_DECL_OVERRIDE; - - bool isSystemTrayAvailable() const Q_DECL_OVERRIDE; - bool supportsMessages() const Q_DECL_OVERRIDE { return true; } - QRect geometry() const Q_DECL_OVERRIDE { return QRect(); } - - QString category() const { return m_category; } - QString status() const { return m_status; } - QString tooltip() const { return m_tooltip; } - - QString iconName() const { return m_iconName; } - const QIcon & icon() const { return m_icon; } - - bool isRequestingAttention() const { return m_attentionTimer.isActive(); } - QString attentionTitle() const { return m_messageTitle; } - QString attentionMessage() const { return m_message; } - QString attentionIconName() const { return m_attentionIconName; } - const QIcon & attentionIcon() const { return m_attentionIcon; } - - QString instanceId() const { return m_instanceId; } - - QDBusPlatformMenu *menu() { return m_menu; } - -signals: - void categoryChanged(); - void statusChanged(QString arg); - void tooltipChanged(); - void iconChanged(); - void attention(); - void menuChanged(); - -private Q_SLOTS: - void attentionTimerExpired(); - void actionInvoked(uint id, const QString &action); - void notificationClosed(uint id, uint reason); - -private: - void setStatus(const QString &status); - QTemporaryFile *tempIcon(const QIcon &icon); - -private: - QDBusMenuConnection* m_dbusConnection; - QStatusNotifierItemAdaptor *m_adaptor; - QDBusMenuAdaptor *m_menuAdaptor; - QDBusPlatformMenu *m_menu; - QXdgNotificationInterface *m_notifier; - QString m_instanceId; - QString m_category; - QString m_defaultStatus; - QString m_status; - QString m_tooltip; - QString m_messageTitle; - QString m_message; - QIcon m_icon; - QTemporaryFile *m_tempIcon; - QString m_iconName; - QIcon m_attentionIcon; - QTemporaryFile *m_tempAttentionIcon; - QString m_attentionIconName; - QTimer m_attentionTimer; - bool m_isRequestingAttention; - bool m_hasMenu; - bool m_registered; -}; - -QT_END_NAMESPACE - -#endif // QT_NO_SYSTEMTRAYICON -#endif // QDBUSTRAYICON_H diff --git a/src/platformsupport/dbustray/qdbustraytypes.cpp b/src/platformsupport/dbustray/qdbustraytypes.cpp deleted file mode 100644 index fc0fa00655..0000000000 --- a/src/platformsupport/dbustray/qdbustraytypes.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Marco Martin -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT_NO_SYSTEMTRAYICON - -#include "qdbustraytypes_p.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "qdbusplatformmenu_p.h" - -QT_BEGIN_NAMESPACE - -static const int IconSizeLimit = 64; -static const int IconNormalSmallSize = 22; -static const int IconNormalMediumSize = 64; - -QXdgDBusImageVector iconToQXdgDBusImageVector(const QIcon &icon) -{ - QXdgDBusImageVector ret; - QList sizes = icon.availableSizes(); - - // Omit any size larger than 64 px, to save D-Bus bandwidth; - // ensure that 22px or smaller exists, because it's a common size; - // and ensure that something between 22px and 64px exists, for better scaling to other sizes. - bool hasSmallIcon = false; - bool hasMediumIcon = false; - qreal dpr = qGuiApp->devicePixelRatio(); - QList toRemove; - Q_FOREACH (const QSize &size, sizes) { - int maxSize = qMax(size.width(), size.height()); - if (maxSize <= IconNormalSmallSize * dpr) - hasSmallIcon = true; - else if (maxSize <= IconNormalMediumSize * dpr) - hasMediumIcon = true; - else if (maxSize > IconSizeLimit * dpr) - toRemove << size; - } - Q_FOREACH (const QSize &size, toRemove) - sizes.removeOne(size); - if (!hasSmallIcon) - sizes.append(QSize(IconNormalSmallSize * dpr, IconNormalSmallSize * dpr)); - if (!hasMediumIcon) - sizes.append(QSize(IconNormalMediumSize * dpr, IconNormalMediumSize * dpr)); - - ret.reserve(sizes.size()); - foreach (QSize size, sizes) { - // Protocol specifies ARGB32 format in network byte order - QImage im = icon.pixmap(size).toImage().convertToFormat(QImage::Format_ARGB32); - // letterbox if necessary to make it square - if (im.height() != im.width()) { - int maxSize = qMax(im.width(), im.height()); - QImage padded(maxSize, maxSize, QImage::Format_ARGB32); - padded.fill(Qt::transparent); - QPainter painter(&padded); - painter.drawImage((maxSize - im.width()) / 2, (maxSize - im.height()) / 2, im); - im = padded; - } - // copy and endian-convert - QXdgDBusImageStruct kim(im.width(), im.height()); - const uchar *end = im.constBits() + im.byteCount(); - uchar *dest = reinterpret_cast(kim.data.data()); - for (const uchar *src = im.constBits(); src < end; src += 4, dest += 4) - qToUnaligned(qToBigEndian(qFromUnaligned(src)), dest); - - ret << kim; - } - return ret; -} - -// Marshall the ImageStruct data into a D-Bus argument -const QDBusArgument &operator<<(QDBusArgument &argument, const QXdgDBusImageStruct &icon) -{ - argument.beginStructure(); - argument << icon.width; - argument << icon.height; - argument << icon.data; - argument.endStructure(); - return argument; -} - -// Retrieve the ImageStruct data from the D-Bus argument -const QDBusArgument &operator>>(const QDBusArgument &argument, QXdgDBusImageStruct &icon) -{ - qint32 width; - qint32 height; - QByteArray data; - - argument.beginStructure(); - argument >> width; - argument >> height; - argument >> data; - argument.endStructure(); - - icon.width = width; - icon.height = height; - icon.data = data; - - return argument; -} - -// Marshall the ImageVector data into a D-Bus argument -const QDBusArgument &operator<<(QDBusArgument &argument, const QXdgDBusImageVector &iconVector) -{ - argument.beginArray(qMetaTypeId()); - for (int i = 0; i < iconVector.size(); ++i) { - argument << iconVector[i]; - } - argument.endArray(); - return argument; -} - -// Retrieve the ImageVector data from the D-Bus argument -const QDBusArgument &operator>>(const QDBusArgument &argument, QXdgDBusImageVector &iconVector) -{ - argument.beginArray(); - iconVector.clear(); - - while (!argument.atEnd()) { - QXdgDBusImageStruct element; - argument >> element; - iconVector.append(element); - } - - argument.endArray(); - - return argument; -} - -// Marshall the ToolTipStruct data into a D-Bus argument -const QDBusArgument &operator<<(QDBusArgument &argument, const QXdgDBusToolTipStruct &toolTip) -{ - argument.beginStructure(); - argument << toolTip.icon; - argument << toolTip.image; - argument << toolTip.title; - argument << toolTip.subTitle; - argument.endStructure(); - return argument; -} - -// Retrieve the ToolTipStruct data from the D-Bus argument -const QDBusArgument &operator>>(const QDBusArgument &argument, QXdgDBusToolTipStruct &toolTip) -{ - QString icon; - QXdgDBusImageVector image; - QString title; - QString subTitle; - - argument.beginStructure(); - argument >> icon; - argument >> image; - argument >> title; - argument >> subTitle; - argument.endStructure(); - - toolTip.icon = icon; - toolTip.image = image; - toolTip.title = title; - toolTip.subTitle = subTitle; - - return argument; -} - -QT_END_NAMESPACE -#endif // QT_NO_SYSTEMTRAYICON diff --git a/src/platformsupport/dbustray/qdbustraytypes_p.h b/src/platformsupport/dbustray/qdbustraytypes_p.h deleted file mode 100644 index 1bdc855c3c..0000000000 --- a/src/platformsupport/dbustray/qdbustraytypes_p.h +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Marco Martin -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QDBUSTRAYTYPES_P_H -#define QDBUSTRAYTYPES_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#ifndef QT_NO_SYSTEMTRAYICON - -#include -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -// Custom message type to send icons across D-Bus -struct QXdgDBusImageStruct -{ - QXdgDBusImageStruct() { } - QXdgDBusImageStruct(int w, int h) - : width(w), height(h), data(width * height * 4, 0) { } - int width; - int height; - QByteArray data; -}; -Q_DECLARE_TYPEINFO(QXdgDBusImageStruct, Q_MOVABLE_TYPE); - -typedef QVector QXdgDBusImageVector; - -QXdgDBusImageVector iconToQXdgDBusImageVector(const QIcon &icon); - -// Custom message type to send tooltips across D-Bus -struct QXdgDBusToolTipStruct -{ - QString icon; - QXdgDBusImageVector image; - QString title; - QString subTitle; -}; -Q_DECLARE_TYPEINFO(QXdgDBusToolTipStruct, Q_MOVABLE_TYPE); - -const QDBusArgument &operator<<(QDBusArgument &argument, const QXdgDBusImageStruct &icon); -const QDBusArgument &operator>>(const QDBusArgument &argument, QXdgDBusImageStruct &icon); - -const QDBusArgument &operator<<(QDBusArgument &argument, const QXdgDBusImageVector &iconVector); -const QDBusArgument &operator>>(const QDBusArgument &argument, QXdgDBusImageVector &iconVector); - -const QDBusArgument &operator<<(QDBusArgument &argument, const QXdgDBusToolTipStruct &toolTip); -const QDBusArgument &operator>>(const QDBusArgument &argument, QXdgDBusToolTipStruct &toolTip); - -QT_END_NAMESPACE - -Q_DECLARE_METATYPE(QXdgDBusImageStruct) -Q_DECLARE_METATYPE(QXdgDBusImageVector) -Q_DECLARE_METATYPE(QXdgDBusToolTipStruct) - -#endif // QT_NO_SYSTEMTRAYICON -#endif // QDBUSTRAYTYPES_P_H diff --git a/src/platformsupport/dbustray/qstatusnotifieritemadaptor.cpp b/src/platformsupport/dbustray/qstatusnotifieritemadaptor.cpp deleted file mode 100644 index d3c5454f01..0000000000 --- a/src/platformsupport/dbustray/qstatusnotifieritemadaptor.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/* - This file was originally created by qdbusxml2cpp version 0.8 - Command line was: - qdbusxml2cpp -a statusnotifieritem ../../3rdparty/dbus-ifaces/org.kde.StatusNotifierItem.xml - - However it is maintained manually, because this adapter needs to do - significant interface adaptation, and can do it more efficiently using the - QDBusTrayIcon API directly rather than via QObject::property() and - QMetaObject::invokeMethod(). -*/ - -#include "qstatusnotifieritemadaptor_p.h" - -#ifndef QT_NO_SYSTEMTRAYICON - -#include "qdbustrayicon_p.h" - -QT_BEGIN_NAMESPACE - -Q_DECLARE_LOGGING_CATEGORY(qLcMenu) -Q_DECLARE_LOGGING_CATEGORY(qLcTray) - -QStatusNotifierItemAdaptor::QStatusNotifierItemAdaptor(QDBusTrayIcon *parent) - : QDBusAbstractAdaptor(parent), m_trayIcon(parent) -{ - setAutoRelaySignals(true); -} - -QStatusNotifierItemAdaptor::~QStatusNotifierItemAdaptor() -{ -} - -QString QStatusNotifierItemAdaptor::attentionIconName() const -{ - return m_trayIcon->attentionIconName(); -} - -QXdgDBusImageVector QStatusNotifierItemAdaptor::attentionIconPixmap() const -{ - return iconToQXdgDBusImageVector(m_trayIcon->attentionIcon()); -} - -QString QStatusNotifierItemAdaptor::attentionMovieName() const -{ - return QString(); -} - -QString QStatusNotifierItemAdaptor::category() const -{ - return m_trayIcon->category(); -} - -QString QStatusNotifierItemAdaptor::iconName() const -{ - return m_trayIcon->iconName(); -} - -QXdgDBusImageVector QStatusNotifierItemAdaptor::iconPixmap() const -{ - return iconToQXdgDBusImageVector(m_trayIcon->icon()); -} - -QString QStatusNotifierItemAdaptor::id() const -{ - // from the API docs: "a name that should be unique for this application and - // consistent between sessions, such as the application name itself" - return QCoreApplication::applicationName(); -} - -bool QStatusNotifierItemAdaptor::itemIsMenu() const -{ - // From KDE docs: if this is true, the item only supports the context menu, - // so the visualization should prefer sending ContextMenu() instead of Activate(). - // But QSystemTrayIcon doesn't have such a setting: it will emit activated() - // and the application is free to use it or ignore it; we don't know whether it will. - return false; -} - -QDBusObjectPath QStatusNotifierItemAdaptor::menu() const -{ - return QDBusObjectPath(m_trayIcon->menu() ? "/MenuBar" : "/NO_DBUSMENU"); -} - -QString QStatusNotifierItemAdaptor::overlayIconName() const -{ - return QString(); -} - -QXdgDBusImageVector QStatusNotifierItemAdaptor::overlayIconPixmap() const -{ - QXdgDBusImageVector ret; // empty vector - return ret; -} - -QString QStatusNotifierItemAdaptor::status() const -{ - return m_trayIcon->status(); -} - -QString QStatusNotifierItemAdaptor::title() const -{ - // Shown e.g. when the icon is hidden, in the popup showing all hidden items. - // Since QSystemTrayIcon doesn't have this property, the application name - // is the best information we have available. - return QCoreApplication::applicationName(); -} - -QXdgDBusToolTipStruct QStatusNotifierItemAdaptor::toolTip() const -{ - QXdgDBusToolTipStruct ret; - if (m_trayIcon->isRequestingAttention()) { - ret.title = m_trayIcon->attentionTitle(); - ret.subTitle = m_trayIcon->attentionMessage(); - ret.icon = m_trayIcon->attentionIconName(); - } else { - ret.title = m_trayIcon->tooltip(); - } - return ret; -} - -void QStatusNotifierItemAdaptor::Activate(int x, int y) -{ - qCDebug(qLcTray) << x << y; - emit m_trayIcon->activated(QPlatformSystemTrayIcon::Trigger); -} - -void QStatusNotifierItemAdaptor::ContextMenu(int x, int y) -{ - qCDebug(qLcTray) << x << y; - emit m_trayIcon->activated(QPlatformSystemTrayIcon::Context); -} - -void QStatusNotifierItemAdaptor::Scroll(int w, const QString &s) -{ - qCDebug(qLcTray) << w << s; - // unsupported -} - -void QStatusNotifierItemAdaptor::SecondaryActivate(int x, int y) -{ - qCDebug(qLcTray) << x << y; - emit m_trayIcon->activated(QPlatformSystemTrayIcon::MiddleClick); -} - -QT_END_NAMESPACE - -#endif // QT_NO_SYSTEMTRAYICON diff --git a/src/platformsupport/dbustray/qstatusnotifieritemadaptor_p.h b/src/platformsupport/dbustray/qstatusnotifieritemadaptor_p.h deleted file mode 100644 index 776e1b23ef..0000000000 --- a/src/platformsupport/dbustray/qstatusnotifieritemadaptor_p.h +++ /dev/null @@ -1,204 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/* - This file was originally created by qdbusxml2cpp version 0.8 - Command line was: - qdbusxml2cpp -a statusnotifieritem ../../3rdparty/dbus-ifaces/org.kde.StatusNotifierItem.xml - - However it is maintained manually. - - It is also not part of the public API. This header file may change from - version to version without notice, or even be removed. -*/ - -#ifndef QSTATUSNOTIFIERITEMADAPTER_P_H -#define QSTATUSNOTIFIERITEMADAPTER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include - -#ifndef QT_NO_SYSTEMTRAYICON - -#include -#include - -#include "qdbustraytypes_p.h" - -QT_BEGIN_NAMESPACE -class QDBusTrayIcon; - -/* - Adaptor class for interface org.kde.StatusNotifierItem - see http://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/ - (also http://www.notmart.org/misc/statusnotifieritem/) -*/ -class QStatusNotifierItemAdaptor: public QDBusAbstractAdaptor -{ - Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "org.kde.StatusNotifierItem") - Q_CLASSINFO("D-Bus Introspection", "" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" - "") -public: - QStatusNotifierItemAdaptor(QDBusTrayIcon *parent); - virtual ~QStatusNotifierItemAdaptor(); - -public: // PROPERTIES - Q_PROPERTY(QString AttentionIconName READ attentionIconName) - QString attentionIconName() const; - - Q_PROPERTY(QXdgDBusImageVector AttentionIconPixmap READ attentionIconPixmap) - QXdgDBusImageVector attentionIconPixmap() const; - - Q_PROPERTY(QString AttentionMovieName READ attentionMovieName) - QString attentionMovieName() const; - - Q_PROPERTY(QString Category READ category) - QString category() const; - - Q_PROPERTY(QString IconName READ iconName) - QString iconName() const; - - Q_PROPERTY(QXdgDBusImageVector IconPixmap READ iconPixmap) - QXdgDBusImageVector iconPixmap() const; - - Q_PROPERTY(QString Id READ id) - QString id() const; - - Q_PROPERTY(bool ItemIsMenu READ itemIsMenu) - bool itemIsMenu() const; - - Q_PROPERTY(QDBusObjectPath Menu READ menu) - QDBusObjectPath menu() const; - - Q_PROPERTY(QString OverlayIconName READ overlayIconName) - QString overlayIconName() const; - - Q_PROPERTY(QXdgDBusImageVector OverlayIconPixmap READ overlayIconPixmap) - QXdgDBusImageVector overlayIconPixmap() const; - - Q_PROPERTY(QString Status READ status) - QString status() const; - - Q_PROPERTY(QString Title READ title) - QString title() const; - - Q_PROPERTY(QXdgDBusToolTipStruct ToolTip READ toolTip) - QXdgDBusToolTipStruct toolTip() const; - -public Q_SLOTS: // METHODS - void Activate(int x, int y); - void ContextMenu(int x, int y); - void Scroll(int delta, const QString &orientation); - void SecondaryActivate(int x, int y); -Q_SIGNALS: // SIGNALS - void NewAttentionIcon(); - void NewIcon(); - void NewOverlayIcon(); - void NewStatus(const QString &status); - void NewTitle(); - void NewToolTip(); - -private: - QDBusTrayIcon *m_trayIcon; -}; - -QT_END_NAMESPACE -#endif // QT_NO_SYSTEMTRAYICON -#endif // QSTATUSNOTIFIERITEMADAPTER_P_H diff --git a/src/platformsupport/dbustray/qxdgnotificationproxy.cpp b/src/platformsupport/dbustray/qxdgnotificationproxy.cpp deleted file mode 100644 index ef2aa799c8..0000000000 --- a/src/platformsupport/dbustray/qxdgnotificationproxy.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qxdgnotificationproxy_p.h" - -QT_BEGIN_NAMESPACE - -QXdgNotificationInterface::QXdgNotificationInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) - : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) -{ -} - -QXdgNotificationInterface::~QXdgNotificationInterface() -{ -} - -QT_END_NAMESPACE diff --git a/src/platformsupport/dbustray/qxdgnotificationproxy_p.h b/src/platformsupport/dbustray/qxdgnotificationproxy_p.h deleted file mode 100644 index 03899723ab..0000000000 --- a/src/platformsupport/dbustray/qxdgnotificationproxy_p.h +++ /dev/null @@ -1,152 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/* - This file was originally created by qdbusxml2cpp version 0.8 - Command line was: - qdbusxml2cpp -p qxdgnotificationproxy ../../3rdparty/dbus-ifaces/org.freedesktop.Notifications.xml - - However it is maintained manually. - - It is also not part of the public API. This header file may change from - version to version without notice, or even be removed. -*/ - -#ifndef QXDGNOTIFICATIONPROXY_P_H -#define QXDGNOTIFICATIONPROXY_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -#include -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -Q_DECLARE_LOGGING_CATEGORY(qLcTray) - -/* - * Proxy class for interface org.freedesktop.Notifications - */ -class QXdgNotificationInterface: public QDBusAbstractInterface -{ - Q_OBJECT -public: - static inline const char *staticInterfaceName() - { return "org.freedesktop.Notifications"; } - -public: - QXdgNotificationInterface(const QString &service, const QString &path, - const QDBusConnection &connection, QObject *parent = 0); - - ~QXdgNotificationInterface(); - -public Q_SLOTS: // METHODS - inline QDBusPendingReply<> closeNotification(uint id) - { - QList argumentList; - argumentList << QVariant::fromValue(id); - return asyncCallWithArgumentList(QStringLiteral("CloseNotification"), argumentList); - } - - inline QDBusPendingReply getCapabilities() - { - QList argumentList; - return asyncCallWithArgumentList(QStringLiteral("GetCapabilities"), argumentList); - } - - inline QDBusPendingReply getServerInformation() - { - QList argumentList; - return asyncCallWithArgumentList(QStringLiteral("GetServerInformation"), argumentList); - } - inline QDBusReply getServerInformation(QString &vendor, QString &version, QString &specVersion) - { - QList argumentList; - QDBusMessage reply = callWithArgumentList(QDBus::Block, QStringLiteral("GetServerInformation"), argumentList); - if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 4) { - vendor = qdbus_cast(reply.arguments().at(1)); - version = qdbus_cast(reply.arguments().at(2)); - specVersion = qdbus_cast(reply.arguments().at(3)); - } - return reply; - } - - // see https://developer.gnome.org/notification-spec/#basic-design - inline QDBusPendingReply notify(const QString &appName, uint replacesId, const QString &appIcon, - const QString &summary, const QString &body, const QStringList &actions, - const QVariantMap &hints, int timeout) - { - qCDebug(qLcTray) << appName << replacesId << appIcon << summary << body << actions << hints << timeout; - QList argumentList; - argumentList << QVariant::fromValue(appName) << QVariant::fromValue(replacesId) << - QVariant::fromValue(appIcon) << QVariant::fromValue(summary) << - QVariant::fromValue(body) << QVariant::fromValue(actions) << - QVariant::fromValue(hints) << QVariant::fromValue(timeout); - return asyncCallWithArgumentList(QStringLiteral("Notify"), argumentList); - } - -Q_SIGNALS: - void ActionInvoked(uint id, const QString &action_key); - void NotificationClosed(uint id, uint reason); -}; - -namespace org { - namespace freedesktop { - typedef ::QXdgNotificationInterface Notifications; - } -} - -QT_END_NAMESPACE - -#endif diff --git a/src/platformsupport/platformsupport.pro b/src/platformsupport/platformsupport.pro index 19efa60f48..f9b57acaa8 100644 --- a/src/platformsupport/platformsupport.pro +++ b/src/platformsupport/platformsupport.pro @@ -22,13 +22,6 @@ include(linuxaccessibility/linuxaccessibility.pri) include(clipboard/clipboard.pri) include(platformcompositor/platformcompositor.pri) -# dbus convenience for unix except darwin: the platform -# plugins for these platforms do not use dbus and we -# don't want to create a false dependency. -unix:!darwin:qtConfig(dbus) { - include(dbusmenu/dbusmenu.pri) - include(dbustray/dbustray.pri) -} darwin: include(graphics/graphics.pri) load(qt_module) diff --git a/src/platformsupport/themes/genericunix/dbusmenu/dbusmenu.pri b/src/platformsupport/themes/genericunix/dbusmenu/dbusmenu.pri new file mode 100644 index 0000000000..662ebfdae6 --- /dev/null +++ b/src/platformsupport/themes/genericunix/dbusmenu/dbusmenu.pri @@ -0,0 +1,19 @@ +QT_FOR_PRIVATE += dbus + +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/qdbusmenuadaptor_p.h \ + $$PWD/qdbusmenutypes_p.h \ + $$PWD/qdbusmenuconnection_p.h \ + $$PWD/qdbusmenubar_p.h \ + $$PWD/qdbusmenuregistrarproxy_p.h \ + $$PWD/qdbusplatformmenu_p.h \ + +SOURCES += \ + $$PWD/qdbusmenuadaptor.cpp \ + $$PWD/qdbusmenutypes.cpp \ + $$PWD/qdbusmenuconnection.cpp \ + $$PWD/qdbusmenubar.cpp \ + $$PWD/qdbusmenuregistrarproxy.cpp \ + $$PWD/qdbusplatformmenu.cpp \ diff --git a/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuadaptor.cpp b/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuadaptor.cpp new file mode 100644 index 0000000000..354b9c3a2e --- /dev/null +++ b/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuadaptor.cpp @@ -0,0 +1,163 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + This file was originally created by qdbusxml2cpp version 0.8 + Command line was: + qdbusxml2cpp -a dbusmenu ../../3rdparty/dbus-ifaces/dbus-menu.xml + + However it is maintained manually. +*/ + +#include "qdbusmenuadaptor_p.h" +#include "qdbusplatformmenu_p.h" +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +QDBusMenuAdaptor::QDBusMenuAdaptor(QDBusPlatformMenu *topLevelMenu) + : QDBusAbstractAdaptor(topLevelMenu) + , m_topLevelMenu(topLevelMenu) +{ + setAutoRelaySignals(true); +} + +QDBusMenuAdaptor::~QDBusMenuAdaptor() +{ +} + +QString QDBusMenuAdaptor::status() const +{ + qCDebug(qLcMenu); + return QLatin1String("normal"); +} + +QString QDBusMenuAdaptor::textDirection() const +{ + return QLocale().textDirection() == Qt::RightToLeft ? QLatin1String("rtl") : QLatin1String("ltr"); +} + +uint QDBusMenuAdaptor::version() const +{ + return 4; +} + +bool QDBusMenuAdaptor::AboutToShow(int id) +{ + qCDebug(qLcMenu) << id; + if (id == 0) { + emit m_topLevelMenu->aboutToShow(); + } else { + QDBusPlatformMenuItem *item = QDBusPlatformMenuItem::byId(id); + if (item) { + const QDBusPlatformMenu *menu = static_cast(item->menu()); + if (menu) + emit const_cast(menu)->aboutToShow(); + } + } + return false; // updateNeeded (we don't know that, so false) +} + +QList QDBusMenuAdaptor::AboutToShowGroup(const QList &ids, QList &idErrors) +{ + qCDebug(qLcMenu) << ids; + Q_UNUSED(idErrors) + idErrors.clear(); + for (int id : ids) + AboutToShow(id); + return QList(); // updatesNeeded +} + +void QDBusMenuAdaptor::Event(int id, const QString &eventId, const QDBusVariant &data, uint timestamp) +{ + Q_UNUSED(data) + Q_UNUSED(timestamp) + QDBusPlatformMenuItem *item = QDBusPlatformMenuItem::byId(id); + qCDebug(qLcMenu) << id << (item ? item->text() : QLatin1String("")) << eventId; + if (item && eventId == QLatin1String("clicked")) + item->trigger(); + if (item && eventId == QLatin1String("hovered")) + emit item->hovered(); + if (eventId == QLatin1String("closed")) { + // There is no explicit AboutToHide method, so map closed event to aboutToHide method + const QDBusPlatformMenu *menu = Q_NULLPTR; + if (item) + menu = static_cast(item->menu()); + else if (id == 0) + menu = m_topLevelMenu; + if (menu) + emit const_cast(menu)->aboutToHide(); + } +} + +QList QDBusMenuAdaptor::EventGroup(const QDBusMenuEventList &events) +{ + for (const QDBusMenuEvent &ev : events) + Event(ev.m_id, ev.m_eventId, ev.m_data, ev.m_timestamp); + return QList(); // idErrors +} + +QDBusMenuItemList QDBusMenuAdaptor::GetGroupProperties(const QList &ids, const QStringList &propertyNames) +{ + qCDebug(qLcMenu) << ids << propertyNames << "=>" << QDBusMenuItem::items(ids, propertyNames); + return QDBusMenuItem::items(ids, propertyNames); +} + +uint QDBusMenuAdaptor::GetLayout(int parentId, int recursionDepth, const QStringList &propertyNames, QDBusMenuLayoutItem &layout) +{ + uint ret = layout.populate(parentId, recursionDepth, propertyNames, m_topLevelMenu); + qCDebug(qLcMenu) << parentId << "depth" << recursionDepth << propertyNames << layout.m_id << layout.m_properties << "revision" << ret << layout; + return ret; +} + +QDBusVariant QDBusMenuAdaptor::GetProperty(int id, const QString &name) +{ + qCDebug(qLcMenu) << id << name; + // handle method call com.canonical.dbusmenu.GetProperty + QDBusVariant value; + return value; +} + +QT_END_NAMESPACE diff --git a/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuadaptor_p.h b/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuadaptor_p.h new file mode 100644 index 0000000000..6612f019a7 --- /dev/null +++ b/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuadaptor_p.h @@ -0,0 +1,182 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtDBus module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + This file was originally created by qdbusxml2cpp version 0.8 + Command line was: + qdbusxml2cpp -a dbusmenu ../../3rdparty/dbus-ifaces/dbus-menu.xml + + However it is maintained manually. + + It is also not part of the public API. This header file may change from + version to version without notice, or even be removed. +*/ + +#ifndef DBUSMENUADAPTOR_H +#define DBUSMENUADAPTOR_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include "qdbusmenutypes_p.h" + +QT_BEGIN_NAMESPACE + +/* + * Adaptor class for interface com.canonical.dbusmenu + */ +class QDBusMenuAdaptor: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.canonical.dbusmenu") + Q_CLASSINFO("D-Bus Introspection", "" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" + "") +public: + QDBusMenuAdaptor(QDBusPlatformMenu *topLevelMenu); + virtual ~QDBusMenuAdaptor(); + +public: // PROPERTIES + Q_PROPERTY(QString Status READ status) + QString status() const; + + Q_PROPERTY(QString TextDirection READ textDirection) + QString textDirection() const; + + Q_PROPERTY(uint Version READ version) + uint version() const; + +public Q_SLOTS: // METHODS + bool AboutToShow(int id); + QList AboutToShowGroup(const QList &ids, QList &idErrors); + void Event(int id, const QString &eventId, const QDBusVariant &data, uint timestamp); + QList EventGroup(const QDBusMenuEventList &events); + QDBusMenuItemList GetGroupProperties(const QList &ids, const QStringList &propertyNames); + uint GetLayout(int parentId, int recursionDepth, const QStringList &propertyNames, QDBusMenuLayoutItem &layout); + QDBusVariant GetProperty(int id, const QString &name); + +Q_SIGNALS: // SIGNALS + void ItemActivationRequested(int id, uint timestamp); + void ItemsPropertiesUpdated(const QDBusMenuItemList &updatedProps, const QDBusMenuItemKeysList &removedProps); + void LayoutUpdated(uint revision, int parent); + +private: + QDBusPlatformMenu *m_topLevelMenu; +}; + +QT_END_NAMESPACE + +#endif // DBUSMENUADAPTOR_H diff --git a/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenubar.cpp b/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenubar.cpp new file mode 100644 index 0000000000..76d658f51a --- /dev/null +++ b/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenubar.cpp @@ -0,0 +1,177 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Dmitry Shachnev +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdbusmenubar_p.h" +#include "qdbusmenuregistrarproxy_p.h" + +QT_BEGIN_NAMESPACE + +/* note: do not change these to QStringLiteral; + we are unloaded before QtDBus is done using the strings. + */ +#define REGISTRAR_SERVICE QLatin1String("com.canonical.AppMenu.Registrar") +#define REGISTRAR_PATH QLatin1String("/com/canonical/AppMenu/Registrar") + +QDBusMenuBar::QDBusMenuBar() + : QPlatformMenuBar() + , m_menu(new QDBusPlatformMenu()) + , m_menuAdaptor(new QDBusMenuAdaptor(m_menu)) + , m_windowId(0) +{ + QDBusMenuItem::registerDBusTypes(); + connect(m_menu, &QDBusPlatformMenu::propertiesUpdated, + m_menuAdaptor, &QDBusMenuAdaptor::ItemsPropertiesUpdated); + connect(m_menu, &QDBusPlatformMenu::updated, + m_menuAdaptor, &QDBusMenuAdaptor::LayoutUpdated); +} + +QDBusMenuBar::~QDBusMenuBar() +{ + unregisterMenuBar(); + delete m_menuAdaptor; + delete m_menu; + qDeleteAll(m_menuItems); +} + +QDBusPlatformMenuItem *QDBusMenuBar::menuItemForMenu(QPlatformMenu *menu) +{ + if (!menu) + return nullptr; + quintptr tag = menu->tag(); + const auto it = m_menuItems.constFind(tag); + if (it != m_menuItems.cend()) { + return *it; + } else { + QDBusPlatformMenuItem *item = new QDBusPlatformMenuItem; + updateMenuItem(item, menu); + m_menuItems.insert(tag, item); + return item; + } +} + +void QDBusMenuBar::updateMenuItem(QDBusPlatformMenuItem *item, QPlatformMenu *menu) +{ + const QDBusPlatformMenu *ourMenu = qobject_cast(menu); + item->setText(ourMenu->text()); + item->setIcon(ourMenu->icon()); + item->setEnabled(ourMenu->isEnabled()); + item->setVisible(ourMenu->isVisible()); + item->setMenu(menu); +} + +void QDBusMenuBar::insertMenu(QPlatformMenu *menu, QPlatformMenu *before) +{ + QDBusPlatformMenuItem *menuItem = menuItemForMenu(menu); + QDBusPlatformMenuItem *beforeItem = menuItemForMenu(before); + m_menu->insertMenuItem(menuItem, beforeItem); + m_menu->emitUpdated(); +} + +void QDBusMenuBar::removeMenu(QPlatformMenu *menu) +{ + QDBusPlatformMenuItem *menuItem = menuItemForMenu(menu); + m_menu->removeMenuItem(menuItem); + m_menu->emitUpdated(); +} + +void QDBusMenuBar::syncMenu(QPlatformMenu *menu) +{ + QDBusPlatformMenuItem *menuItem = menuItemForMenu(menu); + updateMenuItem(menuItem, menu); +} + +void QDBusMenuBar::handleReparent(QWindow *newParentWindow) +{ + if (newParentWindow && newParentWindow->winId() != m_windowId) { + unregisterMenuBar(); + m_windowId = newParentWindow->winId(); + registerMenuBar(); + } +} + +QPlatformMenu *QDBusMenuBar::menuForTag(quintptr tag) const +{ + QDBusPlatformMenuItem *menuItem = m_menuItems.value(tag); + if (menuItem) + return const_cast(menuItem->menu()); + return nullptr; +} + +QPlatformMenu *QDBusMenuBar::createMenu() const +{ + return new QDBusPlatformMenu; +} + +void QDBusMenuBar::registerMenuBar() +{ + static uint menuBarId = 0; + + QDBusConnection connection = QDBusConnection::sessionBus(); + m_objectPath = QStringLiteral("/MenuBar/%1").arg(++menuBarId); + if (!connection.registerObject(m_objectPath, m_menu)) + return; + + QDBusMenuRegistrarInterface registrar(REGISTRAR_SERVICE, REGISTRAR_PATH, connection, this); + QDBusPendingReply<> r = registrar.RegisterWindow(m_windowId, QDBusObjectPath(m_objectPath)); + r.waitForFinished(); + if (r.isError()) { + qWarning("Failed to register window menu, reason: %s (\"%s\")", + qUtf8Printable(r.error().name()), qUtf8Printable(r.error().message())); + connection.unregisterObject(m_objectPath); + } +} + +void QDBusMenuBar::unregisterMenuBar() +{ + QDBusConnection connection = QDBusConnection::sessionBus(); + + if (m_windowId) { + QDBusMenuRegistrarInterface registrar(REGISTRAR_SERVICE, REGISTRAR_PATH, connection, this); + QDBusPendingReply<> r = registrar.UnregisterWindow(m_windowId); + r.waitForFinished(); + if (r.isError()) + qWarning("Failed to unregister window menu, reason: %s (\"%s\")", + qUtf8Printable(r.error().name()), qUtf8Printable(r.error().message())); + } + + if (!m_objectPath.isEmpty()) + connection.unregisterObject(m_objectPath); +} + +QT_END_NAMESPACE diff --git a/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenubar_p.h b/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenubar_p.h new file mode 100644 index 0000000000..8266a395f5 --- /dev/null +++ b/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenubar_p.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Dmitry Shachnev +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDBUSMENUBAR_P_H +#define QDBUSMENUBAR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QDBusMenuBar : public QPlatformMenuBar +{ + Q_OBJECT + +public: + QDBusMenuBar(); + virtual ~QDBusMenuBar(); + + void insertMenu(QPlatformMenu *menu, QPlatformMenu *before) Q_DECL_OVERRIDE; + void removeMenu(QPlatformMenu *menu) Q_DECL_OVERRIDE; + void syncMenu(QPlatformMenu *menu) Q_DECL_OVERRIDE; + void handleReparent(QWindow *newParentWindow) Q_DECL_OVERRIDE; + QPlatformMenu *menuForTag(quintptr tag) const Q_DECL_OVERRIDE; + QPlatformMenu *createMenu() const Q_DECL_OVERRIDE; + +private: + QDBusPlatformMenu *m_menu; + QDBusMenuAdaptor *m_menuAdaptor; + QHash m_menuItems; + uint m_windowId; + QString m_objectPath; + + QDBusPlatformMenuItem *menuItemForMenu(QPlatformMenu *menu); + static void updateMenuItem(QDBusPlatformMenuItem *item, QPlatformMenu *menu); + void registerMenuBar(); + void unregisterMenuBar(); +}; + +QT_END_NAMESPACE + +#endif // QDBUSMENUBAR_P_H diff --git a/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp b/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp new file mode 100644 index 0000000000..361146dc23 --- /dev/null +++ b/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection.cpp @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT_NO_SYSTEMTRAYICON +#include "qdbustrayicon_p.h" +#endif +#include "qdbusmenuconnection_p.h" +#include "qdbusmenuadaptor_p.h" +#include "qdbusplatformmenu_p.h" + +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(qLcMenu) + +const QString StatusNotifierWatcherService = QLatin1String("org.kde.StatusNotifierWatcher"); +const QString StatusNotifierWatcherPath = QLatin1String("/StatusNotifierWatcher"); +const QString StatusNotifierItemPath = QLatin1String("/StatusNotifierItem"); +const QString MenuBarPath = QLatin1String("/MenuBar"); + +/*! + \class QDBusMenuConnection + \internal + A D-Bus connection which is used for both menu and tray icon services. + Connects to the session bus and registers with the respective watcher services. +*/ +QDBusMenuConnection::QDBusMenuConnection(QObject *parent, const QString &serviceName) + : QObject(parent) + , m_connection(serviceName.isNull() ? QDBusConnection::sessionBus() + : QDBusConnection::connectToBus(QDBusConnection::SessionBus, serviceName)) + , m_dbusWatcher(new QDBusServiceWatcher(StatusNotifierWatcherService, m_connection, QDBusServiceWatcher::WatchForRegistration, this)) + , m_statusNotifierHostRegistered(false) +{ +#ifndef QT_NO_SYSTEMTRAYICON + QDBusInterface systrayHost(StatusNotifierWatcherService, StatusNotifierWatcherPath, StatusNotifierWatcherService, m_connection); + if (systrayHost.isValid() && systrayHost.property("IsStatusNotifierHostRegistered").toBool()) + m_statusNotifierHostRegistered = true; + else + qCDebug(qLcMenu) << "StatusNotifierHost is not registered"; +#endif +} + +void QDBusMenuConnection::dbusError(const QDBusError &error) +{ + qWarning() << "QDBusTrayIcon encountered a D-Bus error:" << error; +} + +#ifndef QT_NO_SYSTEMTRAYICON +bool QDBusMenuConnection::registerTrayIconMenu(QDBusTrayIcon *item) +{ + bool success = connection().registerObject(MenuBarPath, item->menu()); + if (!success) // success == false is normal, because the object may be already registered + qCDebug(qLcMenu) << "failed to register" << item->instanceId() << MenuBarPath; + return success; +} + +bool QDBusMenuConnection::registerTrayIcon(QDBusTrayIcon *item) +{ + bool success = connection().registerService(item->instanceId()); + if (!success) { + qWarning() << "failed to register service" << item->instanceId(); + return false; + } + + success = connection().registerObject(StatusNotifierItemPath, item); + if (!success) { + unregisterTrayIcon(item); + qWarning() << "failed to register" << item->instanceId() << StatusNotifierItemPath; + return false; + } + + if (item->menu()) + registerTrayIconMenu(item); + + QDBusMessage registerMethod = QDBusMessage::createMethodCall( + StatusNotifierWatcherService, StatusNotifierWatcherPath, StatusNotifierWatcherService, + QLatin1String("RegisterStatusNotifierItem")); + registerMethod.setArguments(QVariantList() << item->instanceId()); + success = m_connection.callWithCallback(registerMethod, this, SIGNAL(trayIconRegistered()), SLOT(dbusError(QDBusError))); + + return success; +} + +bool QDBusMenuConnection::unregisterTrayIcon(QDBusTrayIcon *item) +{ + connection().unregisterObject(MenuBarPath); + connection().unregisterObject(StatusNotifierItemPath); + bool success = connection().unregisterService(item->instanceId()); + if (!success) + qWarning() << "failed to unregister service" << item->instanceId(); + return success; +} +#endif // QT_NO_SYSTEMTRAYICON + +QT_END_NAMESPACE diff --git a/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h b/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h new file mode 100644 index 0000000000..84eb2a6f3a --- /dev/null +++ b/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuconnection_p.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DBUSCONNECTION_H +#define DBUSCONNECTION_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QDBusServiceWatcher; +#ifndef QT_NO_SYSTEMTRAYICON +class QDBusTrayIcon; +#endif // QT_NO_SYSTEMTRAYICON + +class QDBusMenuConnection : public QObject +{ + Q_OBJECT + +public: + QDBusMenuConnection(QObject *parent = 0, const QString &serviceName = QString()); + QDBusConnection connection() const { return m_connection; } + bool isStatusNotifierHostRegistered() const { return m_statusNotifierHostRegistered; } +#ifndef QT_NO_SYSTEMTRAYICON + bool registerTrayIconMenu(QDBusTrayIcon *item); + bool registerTrayIcon(QDBusTrayIcon *item); + bool unregisterTrayIcon(QDBusTrayIcon *item); +#endif // QT_NO_SYSTEMTRAYICON + +Q_SIGNALS: +#ifndef QT_NO_SYSTEMTRAYICON + void trayIconRegistered(); +#endif // QT_NO_SYSTEMTRAYICON + +private Q_SLOTS: + void dbusError(const QDBusError &error); + +private: + QDBusConnection m_connection; + QDBusServiceWatcher *m_dbusWatcher; + bool m_statusNotifierHostRegistered; +}; + +QT_END_NAMESPACE + +#endif // DBUSCONNECTION_H diff --git a/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuregistrarproxy.cpp b/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuregistrarproxy.cpp new file mode 100644 index 0000000000..c59b5a675e --- /dev/null +++ b/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuregistrarproxy.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Dmitry Shachnev +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + * This file was originally created by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -p qdbusmenuregistrarproxy ../../3rdparty/dbus-ifaces/com.canonical.AppMenu.Registrar.xml + * + * However it is maintained manually. + */ + +#include "qdbusmenuregistrarproxy_p.h" + +QT_BEGIN_NAMESPACE + +/* + * Implementation of interface class QDBusMenuRegistrarInterface + */ + +QDBusMenuRegistrarInterface::QDBusMenuRegistrarInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +QDBusMenuRegistrarInterface::~QDBusMenuRegistrarInterface() +{ +} + +QT_END_NAMESPACE diff --git a/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuregistrarproxy_p.h b/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuregistrarproxy_p.h new file mode 100644 index 0000000000..c92de0a140 --- /dev/null +++ b/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenuregistrarproxy_p.h @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Dmitry Shachnev +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + * This file was originally created by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -p qdbusmenuregistrarproxy ../../3rdparty/dbus-ifaces/com.canonical.AppMenu.Registrar.xml + * + * However it is maintained manually. + */ + +#ifndef QDBUSMENUREGISTRARPROXY_P_H +#define QDBUSMENUREGISTRARPROXY_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +/* + * Proxy class for interface com.canonical.AppMenu.Registrar + */ +class QDBusMenuRegistrarInterface : public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { + return "com.canonical.AppMenu.Registrar"; + } + +public: + explicit QDBusMenuRegistrarInterface(const QString &service, + const QString &path, + const QDBusConnection &connection, + QObject *parent = nullptr); + + ~QDBusMenuRegistrarInterface(); + +public Q_SLOTS: // METHODS + QDBusPendingReply GetMenuForWindow(uint windowId) + { + QList argumentList; + argumentList << QVariant::fromValue(windowId); + return asyncCallWithArgumentList(QStringLiteral("GetMenuForWindow"), argumentList); + } + QDBusReply GetMenuForWindow(uint windowId, QDBusObjectPath &menuObjectPath) + { + QList argumentList; + argumentList << QVariant::fromValue(windowId); + QDBusMessage reply = callWithArgumentList(QDBus::Block, QStringLiteral("GetMenuForWindow"), argumentList); + QList arguments = reply.arguments(); + if (reply.type() == QDBusMessage::ReplyMessage && arguments.count() == 2) + menuObjectPath = qdbus_cast(arguments.at(1)); + return reply; + } + + QDBusPendingReply<> RegisterWindow(uint windowId, const QDBusObjectPath &menuObjectPath) + { + QList argumentList; + argumentList << QVariant::fromValue(windowId) << QVariant::fromValue(menuObjectPath); + return asyncCallWithArgumentList(QStringLiteral("RegisterWindow"), argumentList); + } + + QDBusPendingReply<> UnregisterWindow(uint windowId) + { + QList argumentList; + argumentList << QVariant::fromValue(windowId); + return asyncCallWithArgumentList(QStringLiteral("UnregisterWindow"), argumentList); + } +}; + +QT_END_NAMESPACE + +#endif // QDBUSMENUREGISTRARPROXY_P_H diff --git a/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenutypes.cpp b/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenutypes.cpp new file mode 100644 index 0000000000..82a13d2fa0 --- /dev/null +++ b/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenutypes.cpp @@ -0,0 +1,301 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdbusmenutypes_p.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "qdbusplatformmenu_p.h" + +QT_BEGIN_NAMESPACE + +const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuItem &item) +{ + arg.beginStructure(); + arg << item.m_id << item.m_properties; + arg.endStructure(); + return arg; +} + +const QDBusArgument &operator>>(const QDBusArgument &arg, QDBusMenuItem &item) +{ + arg.beginStructure(); + arg >> item.m_id >> item.m_properties; + arg.endStructure(); + return arg; +} + +const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuItemKeys &keys) +{ + arg.beginStructure(); + arg << keys.id << keys.properties; + arg.endStructure(); + return arg; +} + +const QDBusArgument &operator>>(const QDBusArgument &arg, QDBusMenuItemKeys &keys) +{ + arg.beginStructure(); + arg >> keys.id >> keys.properties; + arg.endStructure(); + return arg; +} + +uint QDBusMenuLayoutItem::populate(int id, int depth, const QStringList &propertyNames, const QDBusPlatformMenu *topLevelMenu) +{ + qCDebug(qLcMenu) << id << "depth" << depth << propertyNames; + m_id = id; + if (id == 0) { + m_properties.insert(QLatin1String("children-display"), QLatin1String("submenu")); + if (topLevelMenu) + populate(topLevelMenu, depth, propertyNames); + return 1; // revision + } + + QDBusPlatformMenuItem *item = QDBusPlatformMenuItem::byId(id); + if (item) { + const QDBusPlatformMenu *menu = static_cast(item->menu()); + + if (menu) { + if (depth != 0) + populate(menu, depth, propertyNames); + return menu->revision(); + } + } + + return 1; // revision +} + +void QDBusMenuLayoutItem::populate(const QDBusPlatformMenu *menu, int depth, const QStringList &propertyNames) +{ + const auto items = menu->items(); + for (QDBusPlatformMenuItem *item : items) { + QDBusMenuLayoutItem child; + child.populate(item, depth - 1, propertyNames); + m_children << child; + } +} + +void QDBusMenuLayoutItem::populate(const QDBusPlatformMenuItem *item, int depth, const QStringList &propertyNames) +{ + m_id = item->dbusID(); + QDBusMenuItem proxy(item); + m_properties = proxy.m_properties; + + const QDBusPlatformMenu *menu = static_cast(item->menu()); + if (depth != 0 && menu) + populate(menu, depth, propertyNames); +} + +const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuLayoutItem &item) +{ + arg.beginStructure(); + arg << item.m_id << item.m_properties; + arg.beginArray(qMetaTypeId()); + for (const QDBusMenuLayoutItem &child : item.m_children) + arg << QDBusVariant(QVariant::fromValue(child)); + arg.endArray(); + arg.endStructure(); + return arg; +} + +const QDBusArgument &operator>>(const QDBusArgument &arg, QDBusMenuLayoutItem &item) +{ + arg.beginStructure(); + arg >> item.m_id >> item.m_properties; + arg.beginArray(); + while (!arg.atEnd()) { + QDBusVariant dbusVariant; + arg >> dbusVariant; + QDBusArgument childArgument = dbusVariant.variant().value(); + + QDBusMenuLayoutItem child; + childArgument >> child; + item.m_children.append(child); + } + arg.endArray(); + arg.endStructure(); + return arg; +} + +void QDBusMenuItem::registerDBusTypes() +{ + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); +} + +QDBusMenuItem::QDBusMenuItem(const QDBusPlatformMenuItem *item) + : m_id(item->dbusID()) +{ + if (item->isSeparator()) { + m_properties.insert(QLatin1String("type"), QLatin1String("separator")); + } else { + m_properties.insert(QLatin1String("label"), convertMnemonic(item->text())); + if (item->menu()) + m_properties.insert(QLatin1String("children-display"), QLatin1String("submenu")); + m_properties.insert(QLatin1String("enabled"), item->isEnabled()); + if (item->isCheckable()) { + QString toggleType = item->hasExclusiveGroup() ? QLatin1String("radio") : QLatin1String("checkmark"); + m_properties.insert(QLatin1String("toggle-type"), toggleType); + m_properties.insert(QLatin1String("toggle-state"), item->isChecked() ? 1 : 0); + } +#ifndef QT_NO_SHORTCUT + const QKeySequence &scut = item->shortcut(); + if (!scut.isEmpty()) { + QDBusMenuShortcut shortcut = convertKeySequence(scut); + m_properties.insert(QLatin1String("shortcut"), QVariant::fromValue(shortcut)); + } +#endif + const QIcon &icon = item->icon(); + if (!icon.name().isEmpty()) { + m_properties.insert(QLatin1String("icon-name"), icon.name()); + } else if (!icon.isNull()) { + QBuffer buf; + icon.pixmap(16).save(&buf, "PNG"); + m_properties.insert(QLatin1String("icon-data"), buf.data()); + } + } + m_properties.insert(QLatin1String("visible"), item->isVisible()); +} + +QDBusMenuItemList QDBusMenuItem::items(const QList &ids, const QStringList &propertyNames) +{ + Q_UNUSED(propertyNames) + QDBusMenuItemList ret; + const QList items = QDBusPlatformMenuItem::byIds(ids); + ret.reserve(items.size()); + for (const QDBusPlatformMenuItem *item : items) + ret << QDBusMenuItem(item); + return ret; +} + +QString QDBusMenuItem::convertMnemonic(const QString &label) +{ + // convert only the first occurrence of ampersand which is not at the end + // dbusmenu uses underscore instead of ampersand + int idx = label.indexOf(QLatin1Char('&')); + if (idx < 0 || idx == label.length() - 1) + return label; + QString ret(label); + ret[idx] = QLatin1Char('_'); + return ret; +} + +#ifndef QT_NO_SHORTCUT +QDBusMenuShortcut QDBusMenuItem::convertKeySequence(const QKeySequence &sequence) +{ + QDBusMenuShortcut shortcut; + for (int i = 0; i < sequence.count(); ++i) { + QStringList tokens; + int key = sequence[i]; + if (key & Qt::MetaModifier) + tokens << QStringLiteral("Super"); + if (key & Qt::ControlModifier) + tokens << QStringLiteral("Control"); + if (key & Qt::AltModifier) + tokens << QStringLiteral("Alt"); + if (key & Qt::ShiftModifier) + tokens << QStringLiteral("Shift"); + if (key & Qt::KeypadModifier) + tokens << QStringLiteral("Num"); + + QString keyName = QKeySequencePrivate::keyName(key, QKeySequence::PortableText); + if (keyName == QLatin1String("+")) + tokens << QStringLiteral("plus"); + else if (keyName == QLatin1String("-")) + tokens << QStringLiteral("minus"); + else + tokens << keyName; + shortcut << tokens; + } + return shortcut; +} +#endif + +const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuEvent &ev) +{ + arg.beginStructure(); + arg << ev.m_id << ev.m_eventId << ev.m_data << ev.m_timestamp; + arg.endStructure(); + return arg; +} + +const QDBusArgument &operator>>(const QDBusArgument &arg, QDBusMenuEvent &ev) +{ + arg.beginStructure(); + arg >> ev.m_id >> ev.m_eventId >> ev.m_data >> ev.m_timestamp; + arg.endStructure(); + return arg; +} + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug d, const QDBusMenuItem &item) +{ + QDebugStateSaver saver(d); + d.nospace(); + d << "QDBusMenuItem(id=" << item.m_id << ", properties=" << item.m_properties << ')'; + return d; +} + +QDebug operator<<(QDebug d, const QDBusMenuLayoutItem &item) +{ + QDebugStateSaver saver(d); + d.nospace(); + d << "QDBusMenuLayoutItem(id=" << item.m_id << ", properties=" << item.m_properties << ", " << item.m_children.count() << " children)"; + return d; +} +#endif + +QT_END_NAMESPACE diff --git a/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenutypes_p.h b/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenutypes_p.h new file mode 100644 index 0000000000..fd6727d3be --- /dev/null +++ b/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenutypes_p.h @@ -0,0 +1,155 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDBUSMENUTYPES_H +#define QDBUSMENUTYPES_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QDBusPlatformMenu; +class QDBusPlatformMenuItem; +class QDBusMenuItem; +typedef QVector QDBusMenuItemList; +typedef QVector QDBusMenuShortcut; + +class QDBusMenuItem +{ +public: + QDBusMenuItem() { } + QDBusMenuItem(const QDBusPlatformMenuItem *item); + + static QDBusMenuItemList items(const QList &ids, const QStringList &propertyNames); + static QString convertMnemonic(const QString &label); +#ifndef QT_NO_SHORTCUT + static QDBusMenuShortcut convertKeySequence(const QKeySequence &sequence); +#endif + static void registerDBusTypes(); + + int m_id; + QVariantMap m_properties; +}; +Q_DECLARE_TYPEINFO(QDBusMenuItem, Q_MOVABLE_TYPE); + +const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuItem &item); +const QDBusArgument &operator>>(const QDBusArgument &arg, QDBusMenuItem &item); + +class QDBusMenuItemKeys +{ +public: + + int id; + QStringList properties; +}; +Q_DECLARE_TYPEINFO(QDBusMenuItemKeys, Q_MOVABLE_TYPE); + +const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuItemKeys &keys); +const QDBusArgument &operator>>(const QDBusArgument &arg, QDBusMenuItemKeys &keys); + +typedef QVector QDBusMenuItemKeysList; + +class QDBusMenuLayoutItem +{ +public: + uint populate(int id, int depth, const QStringList &propertyNames, const QDBusPlatformMenu *topLevelMenu); + void populate(const QDBusPlatformMenu *menu, int depth, const QStringList &propertyNames); + void populate(const QDBusPlatformMenuItem *item, int depth, const QStringList &propertyNames); + + int m_id; + QVariantMap m_properties; + QVector m_children; +}; +Q_DECLARE_TYPEINFO(QDBusMenuLayoutItem, Q_MOVABLE_TYPE); + +const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuLayoutItem &); +const QDBusArgument &operator>>(const QDBusArgument &arg, QDBusMenuLayoutItem &item); + +typedef QVector QDBusMenuLayoutItemList; + +class QDBusMenuEvent +{ +public: + int m_id; + QString m_eventId; + QDBusVariant m_data; + uint m_timestamp; +}; +Q_DECLARE_TYPEINFO(QDBusMenuEvent, Q_MOVABLE_TYPE); // QDBusVariant is movable, even though it cannot + // be marked as such until Qt 6. + +const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuEvent &ev); +const QDBusArgument &operator>>(const QDBusArgument &arg, QDBusMenuEvent &ev); + +typedef QVector QDBusMenuEventList; + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug d, const QDBusMenuItem &item); +QDebug operator<<(QDebug d, const QDBusMenuLayoutItem &item); +#endif + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QDBusMenuItem) +Q_DECLARE_METATYPE(QDBusMenuItemList) +Q_DECLARE_METATYPE(QDBusMenuItemKeys) +Q_DECLARE_METATYPE(QDBusMenuItemKeysList) +Q_DECLARE_METATYPE(QDBusMenuLayoutItem) +Q_DECLARE_METATYPE(QDBusMenuLayoutItemList) +Q_DECLARE_METATYPE(QDBusMenuEvent) +Q_DECLARE_METATYPE(QDBusMenuEventList) +Q_DECLARE_METATYPE(QDBusMenuShortcut) + +#endif diff --git a/src/platformsupport/themes/genericunix/dbusmenu/qdbusplatformmenu.cpp b/src/platformsupport/themes/genericunix/dbusmenu/qdbusplatformmenu.cpp new file mode 100644 index 0000000000..15440a03cd --- /dev/null +++ b/src/platformsupport/themes/genericunix/dbusmenu/qdbusplatformmenu.cpp @@ -0,0 +1,307 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdbusplatformmenu_p.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(qLcMenu, "qt.qpa.menu") + +static int nextDBusID = 1; +QHash menuItemsByID; + +QDBusPlatformMenuItem::QDBusPlatformMenuItem(quintptr tag) + : m_tag(tag ? tag : reinterpret_cast(this)) // QMenu will overwrite this later + , m_subMenu(Q_NULLPTR) + , m_role(NoRole) + , m_isEnabled(true) + , m_isVisible(true) + , m_isSeparator(false) + , m_isCheckable(false) + , m_isChecked(false) + , m_dbusID(nextDBusID++) + , m_hasExclusiveGroup(false) +{ + menuItemsByID.insert(m_dbusID, this); +} + +QDBusPlatformMenuItem::~QDBusPlatformMenuItem() +{ + menuItemsByID.remove(m_dbusID); + if (m_subMenu) + static_cast(m_subMenu)->setContainingMenuItem(Q_NULLPTR); +} + +void QDBusPlatformMenuItem::setTag(quintptr tag) +{ + m_tag = tag; +} + +void QDBusPlatformMenuItem::setText(const QString &text) +{ + qCDebug(qLcMenu) << m_dbusID << text; + m_text = text; +} + +void QDBusPlatformMenuItem::setIcon(const QIcon &icon) +{ + m_icon = icon; +} + +/*! + Set a submenu under this menu item. +*/ +void QDBusPlatformMenuItem::setMenu(QPlatformMenu *menu) +{ + if (m_subMenu) + static_cast(m_subMenu)->setContainingMenuItem(Q_NULLPTR); + m_subMenu = menu; + if (menu) + static_cast(menu)->setContainingMenuItem(this); +} + +void QDBusPlatformMenuItem::setEnabled(bool enabled) +{ + m_isEnabled = enabled; +} + +void QDBusPlatformMenuItem::setVisible(bool isVisible) +{ + m_isVisible = isVisible; +} + +void QDBusPlatformMenuItem::setIsSeparator(bool isSeparator) +{ + m_isSeparator = isSeparator; +} + +void QDBusPlatformMenuItem::setRole(QPlatformMenuItem::MenuRole role) +{ + m_role = role; +} + +void QDBusPlatformMenuItem::setCheckable(bool checkable) +{ + m_isCheckable = checkable; +} + +void QDBusPlatformMenuItem::setChecked(bool isChecked) +{ + m_isChecked = isChecked; +} + +void QDBusPlatformMenuItem::setHasExclusiveGroup(bool hasExclusiveGroup) +{ + m_hasExclusiveGroup = hasExclusiveGroup; +} + +#ifndef QT_NO_SHORTCUT +void QDBusPlatformMenuItem::setShortcut(const QKeySequence &shortcut) +{ + m_shortcut = shortcut; +} +#endif + +void QDBusPlatformMenuItem::trigger() +{ + emit activated(); +} + +QDBusPlatformMenuItem *QDBusPlatformMenuItem::byId(int id) +{ + // We need to check contains because otherwise QHash would insert + // a default-constructed nullptr value into menuItemsByID + if (menuItemsByID.contains(id)) + return menuItemsByID[id]; + return Q_NULLPTR; +} + +QList QDBusPlatformMenuItem::byIds(const QList &ids) +{ + QList ret; + for (int id : ids) { + if (menuItemsByID.contains(id)) + ret << menuItemsByID[id]; + } + return ret; +} + + +QDBusPlatformMenu::QDBusPlatformMenu(quintptr tag) + : m_tag(tag ? tag : reinterpret_cast(this)) + , m_isEnabled(true) + , m_isVisible(true) + , m_isSeparator(false) + , m_revision(1) + , m_containingMenuItem(Q_NULLPTR) +{ +} + +QDBusPlatformMenu::~QDBusPlatformMenu() +{ + if (m_containingMenuItem) + m_containingMenuItem->setMenu(Q_NULLPTR); +} + +void QDBusPlatformMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) +{ + QDBusPlatformMenuItem *item = static_cast(menuItem); + QDBusPlatformMenuItem *beforeItem = static_cast(before); + int idx = m_items.indexOf(beforeItem); + qCDebug(qLcMenu) << item->dbusID() << item->text(); + if (idx < 0) + m_items.append(item); + else + m_items.insert(idx, item); + m_itemsByTag.insert(item->tag(), item); + if (item->menu()) + syncSubMenu(static_cast(item->menu())); + emitUpdated(); +} + +void QDBusPlatformMenu::removeMenuItem(QPlatformMenuItem *menuItem) +{ + QDBusPlatformMenuItem *item = static_cast(menuItem); + m_items.removeAll(item); + m_itemsByTag.remove(menuItem->tag()); + if (item->menu()) { + // disconnect from the signals we connected to in syncSubMenu() + const QDBusPlatformMenu *menu = static_cast(item->menu()); + disconnect(menu, &QDBusPlatformMenu::propertiesUpdated, + this, &QDBusPlatformMenu::propertiesUpdated); + disconnect(menu, &QDBusPlatformMenu::updated, + this, &QDBusPlatformMenu::updated); + } + emitUpdated(); +} + +void QDBusPlatformMenu::syncSubMenu(const QDBusPlatformMenu *menu) +{ + // The adaptor is only connected to the propertiesUpdated signal of the top-level + // menu, so the submenus should transfer their signals to their parents. + connect(menu, &QDBusPlatformMenu::propertiesUpdated, + this, &QDBusPlatformMenu::propertiesUpdated, Qt::UniqueConnection); + connect(menu, &QDBusPlatformMenu::updated, + this, &QDBusPlatformMenu::updated, Qt::UniqueConnection); +} + +void QDBusPlatformMenu::syncMenuItem(QPlatformMenuItem *menuItem) +{ + QDBusPlatformMenuItem *item = static_cast(menuItem); + // if a submenu was added to this item, we need to connect to its signals + if (item->menu()) + syncSubMenu(static_cast(item->menu())); + // TODO keep around copies of the QDBusMenuLayoutItems so they can be updated? + // or eliminate them by putting dbus streaming operators in this class instead? + // or somehow tell the dbusmenu client that something has changed, so it will ask for properties again + QDBusMenuItemList updated; + QDBusMenuItemKeysList removed; + updated << QDBusMenuItem(item); + qCDebug(qLcMenu) << updated; + emit propertiesUpdated(updated, removed); +} + +void QDBusPlatformMenu::emitUpdated() +{ + if (m_containingMenuItem) + emit updated(++m_revision, m_containingMenuItem->dbusID()); + else + emit updated(++m_revision, 0); +} + +void QDBusPlatformMenu::setTag(quintptr tag) +{ + m_tag = tag; +} + +void QDBusPlatformMenu::setText(const QString &text) +{ + m_text = text; +} + +void QDBusPlatformMenu::setIcon(const QIcon &icon) +{ + m_icon = icon; +} + +void QDBusPlatformMenu::setEnabled(bool enabled) +{ + m_isEnabled = enabled; +} + +void QDBusPlatformMenu::setVisible(bool isVisible) +{ + m_isVisible = isVisible; +} + +void QDBusPlatformMenu::setContainingMenuItem(QDBusPlatformMenuItem *item) +{ + m_containingMenuItem = item; +} + +QPlatformMenuItem *QDBusPlatformMenu::menuItemAt(int position) const +{ + return m_items.value(position); +} + +QPlatformMenuItem *QDBusPlatformMenu::menuItemForTag(quintptr tag) const +{ + return m_itemsByTag[tag]; +} + +const QList QDBusPlatformMenu::items() const +{ + return m_items; +} + +QPlatformMenuItem *QDBusPlatformMenu::createMenuItem() const +{ + QDBusPlatformMenuItem *ret = new QDBusPlatformMenuItem(); + return ret; +} + +QPlatformMenu *QDBusPlatformMenu::createSubMenu() const +{ + return new QDBusPlatformMenu; +} + +QT_END_NAMESPACE diff --git a/src/platformsupport/themes/genericunix/dbusmenu/qdbusplatformmenu_p.h b/src/platformsupport/themes/genericunix/dbusmenu/qdbusplatformmenu_p.h new file mode 100644 index 0000000000..38c27e8051 --- /dev/null +++ b/src/platformsupport/themes/genericunix/dbusmenu/qdbusplatformmenu_p.h @@ -0,0 +1,207 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDBUSPLATFORMMENU_H +#define QDBUSPLATFORMMENU_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// +// +// W A R N I N G +// ------------- +// +// This file is part of the DBus menu support and is not meant to be used +// in applications. Usage of this API may make your code +// source and binary incompatible with future versions of Qt. +// + +#include +#include +#include "qdbusmenutypes_p.h" + +QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(qLcMenu) + +class QDBusPlatformMenu; + +class QDBusPlatformMenuItem : public QPlatformMenuItem +{ + Q_OBJECT + +public: + QDBusPlatformMenuItem(quintptr tag = 0LL); + ~QDBusPlatformMenuItem(); + + quintptr tag()const Q_DECL_OVERRIDE { return m_tag; } + void setTag(quintptr tag) Q_DECL_OVERRIDE; + + const QString text() const { return m_text; } + void setText(const QString &text) Q_DECL_OVERRIDE; + QIcon icon() const { return m_icon; } + void setIcon(const QIcon &icon) Q_DECL_OVERRIDE; + const QPlatformMenu *menu() const { return m_subMenu; } + void setMenu(QPlatformMenu *menu) Q_DECL_OVERRIDE; + bool isEnabled() const { return m_isEnabled; } + void setEnabled(bool enabled) Q_DECL_OVERRIDE; + bool isVisible() const { return m_isVisible; } + void setVisible(bool isVisible) Q_DECL_OVERRIDE; + bool isSeparator() const { return m_isSeparator; } + void setIsSeparator(bool isSeparator) Q_DECL_OVERRIDE; + void setFont(const QFont &font) Q_DECL_OVERRIDE { Q_UNUSED(font); } + void setRole(MenuRole role) Q_DECL_OVERRIDE; + bool isCheckable() const { return m_isCheckable; } + void setCheckable(bool checkable) Q_DECL_OVERRIDE; + bool isChecked() const { return m_isChecked; } + void setChecked(bool isChecked) Q_DECL_OVERRIDE; + bool hasExclusiveGroup() const { return m_hasExclusiveGroup; } + void setHasExclusiveGroup(bool hasExclusiveGroup) Q_DECL_OVERRIDE; +#ifndef QT_NO_SHORTCUT + QKeySequence shortcut() const { return m_shortcut; } + void setShortcut(const QKeySequence& shortcut) Q_DECL_OVERRIDE; +#endif + void setIconSize(int size) Q_DECL_OVERRIDE { Q_UNUSED(size); } + void setNativeContents(WId item) Q_DECL_OVERRIDE { Q_UNUSED(item); } + + int dbusID() const { return m_dbusID; } + + void trigger(); + + bool operator==(const QDBusPlatformMenuItem& other) { return m_tag == other.m_tag; } + + static QDBusPlatformMenuItem *byId(int id); + static QList byIds(const QList &ids); + +private: + quintptr m_tag; + QString m_text; + QIcon m_icon; + QPlatformMenu *m_subMenu; + MenuRole m_role : 4; + bool m_isEnabled : 1; + bool m_isVisible : 1; + bool m_isSeparator : 1; + bool m_isCheckable : 1; + bool m_isChecked : 1; + int m_dbusID : 16; + bool m_hasExclusiveGroup : 1; + int m_reserved : 6; + QKeySequence m_shortcut; +}; + +class QDBusPlatformMenu : public QPlatformMenu +{ + Q_OBJECT + +public: + QDBusPlatformMenu(quintptr tag = 0LL); + ~QDBusPlatformMenu(); + void insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) Q_DECL_OVERRIDE; + void removeMenuItem(QPlatformMenuItem *menuItem) Q_DECL_OVERRIDE; + void syncSubMenu(const QDBusPlatformMenu *menu); + void syncMenuItem(QPlatformMenuItem *menuItem) Q_DECL_OVERRIDE; + void syncSeparatorsCollapsible(bool enable) Q_DECL_OVERRIDE { Q_UNUSED(enable); } + + quintptr tag()const Q_DECL_OVERRIDE { return m_tag; } + void setTag(quintptr tag) Q_DECL_OVERRIDE; + + const QString text() const { return m_text; } + void setText(const QString &text) Q_DECL_OVERRIDE; + QIcon icon() const { return m_icon; } + void setIcon(const QIcon &icon) Q_DECL_OVERRIDE; + bool isEnabled() const Q_DECL_OVERRIDE { return m_isEnabled; } + void setEnabled(bool enabled) Q_DECL_OVERRIDE; + bool isVisible() const { return m_isVisible; } + void setVisible(bool visible) Q_DECL_OVERRIDE; + void setMinimumWidth(int width) Q_DECL_OVERRIDE { Q_UNUSED(width); } + void setFont(const QFont &font) Q_DECL_OVERRIDE { Q_UNUSED(font); } + void setMenuType(MenuType type) Q_DECL_OVERRIDE { Q_UNUSED(type); } + void setContainingMenuItem(QDBusPlatformMenuItem *item); + + void showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item) Q_DECL_OVERRIDE + { + Q_UNUSED(parentWindow); + Q_UNUSED(targetRect); + Q_UNUSED(item); + setVisible(true); + } + + void dismiss() Q_DECL_OVERRIDE { } // Closes this and all its related menu popups + + QPlatformMenuItem *menuItemAt(int position) const Q_DECL_OVERRIDE; + QPlatformMenuItem *menuItemForTag(quintptr tag) const Q_DECL_OVERRIDE; + const QList items() const; + + QPlatformMenuItem *createMenuItem() const Q_DECL_OVERRIDE; + QPlatformMenu *createSubMenu() const Q_DECL_OVERRIDE; + + bool operator==(const QDBusPlatformMenu& other) { return m_tag == other.m_tag; } + + uint revision() const { return m_revision; } + + void emitUpdated(); + +signals: + void updated(uint revision, int dbusId); + void propertiesUpdated(QDBusMenuItemList updatedProps, QDBusMenuItemKeysList removedProps); + +private: + quintptr m_tag; + QString m_text; + QIcon m_icon; + bool m_isEnabled; + bool m_isVisible; + bool m_isSeparator; + uint m_revision; + QHash m_itemsByTag; + QList m_items; + QDBusPlatformMenuItem *m_containingMenuItem; +}; + +QT_END_NAMESPACE + +#endif + diff --git a/src/platformsupport/themes/genericunix/dbustray/dbustray.pri b/src/platformsupport/themes/genericunix/dbustray/dbustray.pri new file mode 100644 index 0000000000..f703e24ba9 --- /dev/null +++ b/src/platformsupport/themes/genericunix/dbustray/dbustray.pri @@ -0,0 +1,15 @@ +QT_FOR_PRIVATE += dbus + +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/qdbustrayicon_p.h \ + $$PWD/qdbustraytypes_p.h \ + $$PWD/qstatusnotifieritemadaptor_p.h \ + $$PWD/qxdgnotificationproxy_p.h \ + +SOURCES += \ + $$PWD/qdbustrayicon.cpp \ + $$PWD/qdbustraytypes.cpp \ + $$PWD/qstatusnotifieritemadaptor.cpp \ + $$PWD/qxdgnotificationproxy.cpp \ diff --git a/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp b/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp new file mode 100644 index 0000000000..95e9651e9a --- /dev/null +++ b/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp @@ -0,0 +1,305 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdbustrayicon_p.h" + +#ifndef QT_NO_SYSTEMTRAYICON + +#include "qdbusmenuconnection_p.h" +#include "qstatusnotifieritemadaptor_p.h" +#include "qdbusmenuadaptor_p.h" +#include "qdbusplatformmenu_p.h" +#include "qxdgnotificationproxy_p.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Defined in Windows headers which get included by qlockfile_p.h +#undef interface + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(qLcTray, "qt.qpa.tray") + +static const QString KDEItemFormat = QStringLiteral("org.kde.StatusNotifierItem-%1-%2"); +static const QString KDEWatcherService = QStringLiteral("org.kde.StatusNotifierWatcher"); +static const QString TempFileTemplate = QDir::tempPath() + QLatin1String("/qt-trayicon-XXXXXX.png"); +static const QString XdgNotificationService = QStringLiteral("org.freedesktop.Notifications"); +static const QString XdgNotificationPath = QStringLiteral("/org/freedesktop/Notifications"); +static const QString DefaultAction = QStringLiteral("default"); +static int instanceCount = 0; + +/*! + \class QDBusTrayIcon + \internal +*/ + +QDBusTrayIcon::QDBusTrayIcon() + : m_dbusConnection(Q_NULLPTR) + , m_adaptor(new QStatusNotifierItemAdaptor(this)) + , m_menuAdaptor(Q_NULLPTR) + , m_menu(Q_NULLPTR) + , m_notifier(Q_NULLPTR) + , m_instanceId(KDEItemFormat.arg(QCoreApplication::applicationPid()).arg(++instanceCount)) + , m_category(QStringLiteral("ApplicationStatus")) + , m_defaultStatus(QStringLiteral("Active")) // be visible all the time. QSystemTrayIcon has no API to control this. + , m_status(m_defaultStatus) + , m_tempIcon(Q_NULLPTR) + , m_tempAttentionIcon(Q_NULLPTR) + , m_registered(false) +{ + qCDebug(qLcTray); + if (instanceCount == 1) { + QDBusMenuItem::registerDBusTypes(); + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); + } + connect(this, SIGNAL(statusChanged(QString)), m_adaptor, SIGNAL(NewStatus(QString))); + connect(this, SIGNAL(tooltipChanged()), m_adaptor, SIGNAL(NewToolTip())); + connect(this, SIGNAL(iconChanged()), m_adaptor, SIGNAL(NewIcon())); + connect(this, SIGNAL(attention()), m_adaptor, SIGNAL(NewAttentionIcon())); + connect(this, SIGNAL(attention()), m_adaptor, SIGNAL(NewTitle())); + connect(&m_attentionTimer, SIGNAL(timeout()), this, SLOT(attentionTimerExpired())); + m_attentionTimer.setSingleShot(true); +} + +QDBusTrayIcon::~QDBusTrayIcon() +{ +} + +void QDBusTrayIcon::init() +{ + qCDebug(qLcTray) << "registering" << m_instanceId; + m_registered = dBusConnection()->registerTrayIcon(this); +} + +void QDBusTrayIcon::cleanup() +{ + qCDebug(qLcTray) << "unregistering" << m_instanceId; + if (m_registered) + dBusConnection()->unregisterTrayIcon(this); + delete m_dbusConnection; + m_dbusConnection = Q_NULLPTR; + delete m_notifier; + m_notifier = Q_NULLPTR; + m_registered = false; +} + +void QDBusTrayIcon::attentionTimerExpired() +{ + m_messageTitle = QString(); + m_message = QString(); + m_attentionIcon = QIcon(); + emit attention(); + emit tooltipChanged(); + setStatus(m_defaultStatus); +} + +void QDBusTrayIcon::setStatus(const QString &status) +{ + qCDebug(qLcTray) << status; + if (m_status == status) + return; + m_status = status; + emit statusChanged(m_status); +} + +QTemporaryFile *QDBusTrayIcon::tempIcon(const QIcon &icon) +{ + // Hack for indicator-application, which doesn't handle icons sent across D-Bus: + // save the icon to a temp file and set the icon name to that filename. + static bool necessity_checked = false; + static bool necessary = false; + if (!necessity_checked) { + QDBusConnection session = QDBusConnection::sessionBus(); + uint pid = session.interface()->servicePid(KDEWatcherService).value(); + QString processName = QLockFilePrivate::processNameByPid(pid); + necessary = processName.endsWith(QLatin1String("indicator-application-service")); + necessity_checked = true; + } + if (!necessary) + return Q_NULLPTR; + qreal dpr = qGuiApp->devicePixelRatio(); + QTemporaryFile *ret = new QTemporaryFile(TempFileTemplate, this); + ret->open(); + icon.pixmap(QSize(22 * dpr, 22 * dpr)).save(ret); + ret->close(); + return ret; +} + +QDBusMenuConnection * QDBusTrayIcon::dBusConnection() +{ + if (!m_dbusConnection) { + m_dbusConnection = new QDBusMenuConnection(this, m_instanceId); + m_notifier = new QXdgNotificationInterface(XdgNotificationService, + XdgNotificationPath, m_dbusConnection->connection(), this); + connect(m_notifier, SIGNAL(NotificationClosed(uint,uint)), this, SLOT(notificationClosed(uint,uint))); + connect(m_notifier, SIGNAL(ActionInvoked(uint,QString)), this, SLOT(actionInvoked(uint,QString))); + } + return m_dbusConnection; +} + +void QDBusTrayIcon::updateIcon(const QIcon &icon) +{ + m_iconName = icon.name(); + m_icon = icon; + if (m_iconName.isEmpty()) { + if (m_tempIcon) + delete m_tempIcon; + m_tempIcon = tempIcon(icon); + if (m_tempIcon) + m_iconName = m_tempIcon->fileName(); + } + qCDebug(qLcTray) << m_iconName << icon.availableSizes(); + emit iconChanged(); +} + +void QDBusTrayIcon::updateToolTip(const QString &tooltip) +{ + qCDebug(qLcTray) << tooltip; + m_tooltip = tooltip; + emit tooltipChanged(); +} + +QPlatformMenu *QDBusTrayIcon::createMenu() const +{ + return new QDBusPlatformMenu(); +} + +void QDBusTrayIcon::updateMenu(QPlatformMenu * menu) +{ + qCDebug(qLcTray) << menu; + bool needsRegistering = !m_menu; + if (!m_menu) + m_menu = qobject_cast(menu); + if (!m_menuAdaptor) { + m_menuAdaptor = new QDBusMenuAdaptor(m_menu); + // TODO connect(m_menu, , m_menuAdaptor, SIGNAL(ItemActivationRequested(int,uint))); + connect(m_menu, SIGNAL(propertiesUpdated(QDBusMenuItemList,QDBusMenuItemKeysList)), + m_menuAdaptor, SIGNAL(ItemsPropertiesUpdated(QDBusMenuItemList,QDBusMenuItemKeysList))); + connect(m_menu, SIGNAL(updated(uint,int)), + m_menuAdaptor, SIGNAL(LayoutUpdated(uint,int))); + } + m_menu->emitUpdated(); + if (needsRegistering) + dBusConnection()->registerTrayIconMenu(this); +} + +void QDBusTrayIcon::showMessage(const QString &title, const QString &msg, const QIcon &icon, + QPlatformSystemTrayIcon::MessageIcon iconType, int msecs) +{ + m_messageTitle = title; + m_message = msg; + m_attentionIcon = icon; + QStringList notificationActions; + switch (iconType) { + case Information: + m_attentionIconName = QStringLiteral("dialog-information"); + break; + case Warning: + m_attentionIconName = QStringLiteral("dialog-warning"); + break; + case Critical: + m_attentionIconName = QStringLiteral("dialog-error"); + // If there are actions, the desktop notification may appear as a message dialog + // with button(s), which will interrupt the user and require a response. + // That is an optional feature in implementations of org.freedesktop.Notifications + notificationActions << DefaultAction << tr("OK"); + break; + default: + m_attentionIconName.clear(); + break; + } + if (m_attentionIconName.isEmpty()) { + if (m_tempAttentionIcon) + delete m_tempAttentionIcon; + m_tempAttentionIcon = tempIcon(icon); + if (m_tempAttentionIcon) + m_attentionIconName = m_tempAttentionIcon->fileName(); + } + qCDebug(qLcTray) << title << msg << + QPlatformSystemTrayIcon::metaObject()->enumerator( + QPlatformSystemTrayIcon::staticMetaObject.indexOfEnumerator("MessageIcon")).valueToKey(iconType) + << m_attentionIconName << msecs; + setStatus(QStringLiteral("NeedsAttention")); + m_attentionTimer.start(msecs); + emit tooltipChanged(); + emit attention(); + + // Desktop notification + QVariantMap hints; + // urgency levels according to https://developer.gnome.org/notification-spec/#urgency-levels + // 0 low, 1 normal, 2 critical + int urgency = static_cast(iconType) - 1; + if (urgency < 0) // no icon + urgency = 0; + hints.insert(QLatin1String("urgency"), QVariant(urgency)); + m_notifier->notify(QCoreApplication::applicationName(), 0, + m_attentionIconName, title, msg, notificationActions, hints, msecs); +} + +void QDBusTrayIcon::actionInvoked(uint id, const QString &action) +{ + qCDebug(qLcTray) << id << action; + emit messageClicked(); +} + +void QDBusTrayIcon::notificationClosed(uint id, uint reason) +{ + qCDebug(qLcTray) << id << reason; +} + +bool QDBusTrayIcon::isSystemTrayAvailable() const +{ + QDBusMenuConnection * conn = const_cast(this)->dBusConnection(); + qCDebug(qLcTray) << conn->isStatusNotifierHostRegistered(); + return conn->isStatusNotifierHostRegistered(); +} + +QT_END_NAMESPACE +#endif //QT_NO_SYSTEMTRAYICON diff --git a/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon_p.h b/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon_p.h new file mode 100644 index 0000000000..a383ef86fc --- /dev/null +++ b/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon_p.h @@ -0,0 +1,169 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#ifndef QDBUSTRAYICON_H +#define QDBUSTRAYICON_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +#ifndef QT_NO_SYSTEMTRAYICON + +#include +#include +#include +#include "QtGui/qpa/qplatformsystemtrayicon.h" +#include "private/qdbusmenuconnection_p.h" + +QT_BEGIN_NAMESPACE + +class QStatusNotifierItemAdaptor; +class QDBusMenuAdaptor; +class QDBusPlatformMenu; +class QXdgNotificationInterface; + +class QDBusTrayIcon: public QPlatformSystemTrayIcon +{ + Q_OBJECT + Q_PROPERTY(QString category READ category NOTIFY categoryChanged) + Q_PROPERTY(QString status READ status NOTIFY statusChanged) + Q_PROPERTY(QString tooltip READ tooltip NOTIFY tooltipChanged) + Q_PROPERTY(QString iconName READ iconName NOTIFY iconChanged) + Q_PROPERTY(QIcon icon READ icon NOTIFY iconChanged) + Q_PROPERTY(bool isRequestingAttention READ isRequestingAttention NOTIFY attention) + Q_PROPERTY(QString attentionTitle READ attentionTitle NOTIFY attention) + Q_PROPERTY(QString attentionMessage READ attentionMessage NOTIFY attention) + Q_PROPERTY(QString attentionIconName READ attentionIconName NOTIFY attention) + Q_PROPERTY(QIcon attentionIcon READ attentionIcon NOTIFY attention) + Q_PROPERTY(QDBusPlatformMenu *menu READ menu NOTIFY menuChanged) + +public: + QDBusTrayIcon(); + + virtual ~QDBusTrayIcon(); + + QDBusMenuConnection * dBusConnection(); + + void init() Q_DECL_OVERRIDE; + void cleanup() Q_DECL_OVERRIDE; + void updateIcon(const QIcon &icon) Q_DECL_OVERRIDE; + void updateToolTip(const QString &tooltip) Q_DECL_OVERRIDE; + void updateMenu(QPlatformMenu *menu) Q_DECL_OVERRIDE; + QPlatformMenu *createMenu() const Q_DECL_OVERRIDE; + void showMessage(const QString &title, const QString &msg, + const QIcon &icon, MessageIcon iconType, int msecs) Q_DECL_OVERRIDE; + + bool isSystemTrayAvailable() const Q_DECL_OVERRIDE; + bool supportsMessages() const Q_DECL_OVERRIDE { return true; } + QRect geometry() const Q_DECL_OVERRIDE { return QRect(); } + + QString category() const { return m_category; } + QString status() const { return m_status; } + QString tooltip() const { return m_tooltip; } + + QString iconName() const { return m_iconName; } + const QIcon & icon() const { return m_icon; } + + bool isRequestingAttention() const { return m_attentionTimer.isActive(); } + QString attentionTitle() const { return m_messageTitle; } + QString attentionMessage() const { return m_message; } + QString attentionIconName() const { return m_attentionIconName; } + const QIcon & attentionIcon() const { return m_attentionIcon; } + + QString instanceId() const { return m_instanceId; } + + QDBusPlatformMenu *menu() { return m_menu; } + +signals: + void categoryChanged(); + void statusChanged(QString arg); + void tooltipChanged(); + void iconChanged(); + void attention(); + void menuChanged(); + +private Q_SLOTS: + void attentionTimerExpired(); + void actionInvoked(uint id, const QString &action); + void notificationClosed(uint id, uint reason); + +private: + void setStatus(const QString &status); + QTemporaryFile *tempIcon(const QIcon &icon); + +private: + QDBusMenuConnection* m_dbusConnection; + QStatusNotifierItemAdaptor *m_adaptor; + QDBusMenuAdaptor *m_menuAdaptor; + QDBusPlatformMenu *m_menu; + QXdgNotificationInterface *m_notifier; + QString m_instanceId; + QString m_category; + QString m_defaultStatus; + QString m_status; + QString m_tooltip; + QString m_messageTitle; + QString m_message; + QIcon m_icon; + QTemporaryFile *m_tempIcon; + QString m_iconName; + QIcon m_attentionIcon; + QTemporaryFile *m_tempAttentionIcon; + QString m_attentionIconName; + QTimer m_attentionTimer; + bool m_isRequestingAttention; + bool m_hasMenu; + bool m_registered; +}; + +QT_END_NAMESPACE + +#endif // QT_NO_SYSTEMTRAYICON +#endif // QDBUSTRAYICON_H diff --git a/src/platformsupport/themes/genericunix/dbustray/qdbustraytypes.cpp b/src/platformsupport/themes/genericunix/dbustray/qdbustraytypes.cpp new file mode 100644 index 0000000000..fc0fa00655 --- /dev/null +++ b/src/platformsupport/themes/genericunix/dbustray/qdbustraytypes.cpp @@ -0,0 +1,212 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Marco Martin +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT_NO_SYSTEMTRAYICON + +#include "qdbustraytypes_p.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "qdbusplatformmenu_p.h" + +QT_BEGIN_NAMESPACE + +static const int IconSizeLimit = 64; +static const int IconNormalSmallSize = 22; +static const int IconNormalMediumSize = 64; + +QXdgDBusImageVector iconToQXdgDBusImageVector(const QIcon &icon) +{ + QXdgDBusImageVector ret; + QList sizes = icon.availableSizes(); + + // Omit any size larger than 64 px, to save D-Bus bandwidth; + // ensure that 22px or smaller exists, because it's a common size; + // and ensure that something between 22px and 64px exists, for better scaling to other sizes. + bool hasSmallIcon = false; + bool hasMediumIcon = false; + qreal dpr = qGuiApp->devicePixelRatio(); + QList toRemove; + Q_FOREACH (const QSize &size, sizes) { + int maxSize = qMax(size.width(), size.height()); + if (maxSize <= IconNormalSmallSize * dpr) + hasSmallIcon = true; + else if (maxSize <= IconNormalMediumSize * dpr) + hasMediumIcon = true; + else if (maxSize > IconSizeLimit * dpr) + toRemove << size; + } + Q_FOREACH (const QSize &size, toRemove) + sizes.removeOne(size); + if (!hasSmallIcon) + sizes.append(QSize(IconNormalSmallSize * dpr, IconNormalSmallSize * dpr)); + if (!hasMediumIcon) + sizes.append(QSize(IconNormalMediumSize * dpr, IconNormalMediumSize * dpr)); + + ret.reserve(sizes.size()); + foreach (QSize size, sizes) { + // Protocol specifies ARGB32 format in network byte order + QImage im = icon.pixmap(size).toImage().convertToFormat(QImage::Format_ARGB32); + // letterbox if necessary to make it square + if (im.height() != im.width()) { + int maxSize = qMax(im.width(), im.height()); + QImage padded(maxSize, maxSize, QImage::Format_ARGB32); + padded.fill(Qt::transparent); + QPainter painter(&padded); + painter.drawImage((maxSize - im.width()) / 2, (maxSize - im.height()) / 2, im); + im = padded; + } + // copy and endian-convert + QXdgDBusImageStruct kim(im.width(), im.height()); + const uchar *end = im.constBits() + im.byteCount(); + uchar *dest = reinterpret_cast(kim.data.data()); + for (const uchar *src = im.constBits(); src < end; src += 4, dest += 4) + qToUnaligned(qToBigEndian(qFromUnaligned(src)), dest); + + ret << kim; + } + return ret; +} + +// Marshall the ImageStruct data into a D-Bus argument +const QDBusArgument &operator<<(QDBusArgument &argument, const QXdgDBusImageStruct &icon) +{ + argument.beginStructure(); + argument << icon.width; + argument << icon.height; + argument << icon.data; + argument.endStructure(); + return argument; +} + +// Retrieve the ImageStruct data from the D-Bus argument +const QDBusArgument &operator>>(const QDBusArgument &argument, QXdgDBusImageStruct &icon) +{ + qint32 width; + qint32 height; + QByteArray data; + + argument.beginStructure(); + argument >> width; + argument >> height; + argument >> data; + argument.endStructure(); + + icon.width = width; + icon.height = height; + icon.data = data; + + return argument; +} + +// Marshall the ImageVector data into a D-Bus argument +const QDBusArgument &operator<<(QDBusArgument &argument, const QXdgDBusImageVector &iconVector) +{ + argument.beginArray(qMetaTypeId()); + for (int i = 0; i < iconVector.size(); ++i) { + argument << iconVector[i]; + } + argument.endArray(); + return argument; +} + +// Retrieve the ImageVector data from the D-Bus argument +const QDBusArgument &operator>>(const QDBusArgument &argument, QXdgDBusImageVector &iconVector) +{ + argument.beginArray(); + iconVector.clear(); + + while (!argument.atEnd()) { + QXdgDBusImageStruct element; + argument >> element; + iconVector.append(element); + } + + argument.endArray(); + + return argument; +} + +// Marshall the ToolTipStruct data into a D-Bus argument +const QDBusArgument &operator<<(QDBusArgument &argument, const QXdgDBusToolTipStruct &toolTip) +{ + argument.beginStructure(); + argument << toolTip.icon; + argument << toolTip.image; + argument << toolTip.title; + argument << toolTip.subTitle; + argument.endStructure(); + return argument; +} + +// Retrieve the ToolTipStruct data from the D-Bus argument +const QDBusArgument &operator>>(const QDBusArgument &argument, QXdgDBusToolTipStruct &toolTip) +{ + QString icon; + QXdgDBusImageVector image; + QString title; + QString subTitle; + + argument.beginStructure(); + argument >> icon; + argument >> image; + argument >> title; + argument >> subTitle; + argument.endStructure(); + + toolTip.icon = icon; + toolTip.image = image; + toolTip.title = title; + toolTip.subTitle = subTitle; + + return argument; +} + +QT_END_NAMESPACE +#endif // QT_NO_SYSTEMTRAYICON diff --git a/src/platformsupport/themes/genericunix/dbustray/qdbustraytypes_p.h b/src/platformsupport/themes/genericunix/dbustray/qdbustraytypes_p.h new file mode 100644 index 0000000000..1bdc855c3c --- /dev/null +++ b/src/platformsupport/themes/genericunix/dbustray/qdbustraytypes_p.h @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Marco Martin +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDBUSTRAYTYPES_P_H +#define QDBUSTRAYTYPES_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#ifndef QT_NO_SYSTEMTRAYICON + +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +// Custom message type to send icons across D-Bus +struct QXdgDBusImageStruct +{ + QXdgDBusImageStruct() { } + QXdgDBusImageStruct(int w, int h) + : width(w), height(h), data(width * height * 4, 0) { } + int width; + int height; + QByteArray data; +}; +Q_DECLARE_TYPEINFO(QXdgDBusImageStruct, Q_MOVABLE_TYPE); + +typedef QVector QXdgDBusImageVector; + +QXdgDBusImageVector iconToQXdgDBusImageVector(const QIcon &icon); + +// Custom message type to send tooltips across D-Bus +struct QXdgDBusToolTipStruct +{ + QString icon; + QXdgDBusImageVector image; + QString title; + QString subTitle; +}; +Q_DECLARE_TYPEINFO(QXdgDBusToolTipStruct, Q_MOVABLE_TYPE); + +const QDBusArgument &operator<<(QDBusArgument &argument, const QXdgDBusImageStruct &icon); +const QDBusArgument &operator>>(const QDBusArgument &argument, QXdgDBusImageStruct &icon); + +const QDBusArgument &operator<<(QDBusArgument &argument, const QXdgDBusImageVector &iconVector); +const QDBusArgument &operator>>(const QDBusArgument &argument, QXdgDBusImageVector &iconVector); + +const QDBusArgument &operator<<(QDBusArgument &argument, const QXdgDBusToolTipStruct &toolTip); +const QDBusArgument &operator>>(const QDBusArgument &argument, QXdgDBusToolTipStruct &toolTip); + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QXdgDBusImageStruct) +Q_DECLARE_METATYPE(QXdgDBusImageVector) +Q_DECLARE_METATYPE(QXdgDBusToolTipStruct) + +#endif // QT_NO_SYSTEMTRAYICON +#endif // QDBUSTRAYTYPES_P_H diff --git a/src/platformsupport/themes/genericunix/dbustray/qstatusnotifieritemadaptor.cpp b/src/platformsupport/themes/genericunix/dbustray/qstatusnotifieritemadaptor.cpp new file mode 100644 index 0000000000..d3c5454f01 --- /dev/null +++ b/src/platformsupport/themes/genericunix/dbustray/qstatusnotifieritemadaptor.cpp @@ -0,0 +1,186 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + This file was originally created by qdbusxml2cpp version 0.8 + Command line was: + qdbusxml2cpp -a statusnotifieritem ../../3rdparty/dbus-ifaces/org.kde.StatusNotifierItem.xml + + However it is maintained manually, because this adapter needs to do + significant interface adaptation, and can do it more efficiently using the + QDBusTrayIcon API directly rather than via QObject::property() and + QMetaObject::invokeMethod(). +*/ + +#include "qstatusnotifieritemadaptor_p.h" + +#ifndef QT_NO_SYSTEMTRAYICON + +#include "qdbustrayicon_p.h" + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(qLcMenu) +Q_DECLARE_LOGGING_CATEGORY(qLcTray) + +QStatusNotifierItemAdaptor::QStatusNotifierItemAdaptor(QDBusTrayIcon *parent) + : QDBusAbstractAdaptor(parent), m_trayIcon(parent) +{ + setAutoRelaySignals(true); +} + +QStatusNotifierItemAdaptor::~QStatusNotifierItemAdaptor() +{ +} + +QString QStatusNotifierItemAdaptor::attentionIconName() const +{ + return m_trayIcon->attentionIconName(); +} + +QXdgDBusImageVector QStatusNotifierItemAdaptor::attentionIconPixmap() const +{ + return iconToQXdgDBusImageVector(m_trayIcon->attentionIcon()); +} + +QString QStatusNotifierItemAdaptor::attentionMovieName() const +{ + return QString(); +} + +QString QStatusNotifierItemAdaptor::category() const +{ + return m_trayIcon->category(); +} + +QString QStatusNotifierItemAdaptor::iconName() const +{ + return m_trayIcon->iconName(); +} + +QXdgDBusImageVector QStatusNotifierItemAdaptor::iconPixmap() const +{ + return iconToQXdgDBusImageVector(m_trayIcon->icon()); +} + +QString QStatusNotifierItemAdaptor::id() const +{ + // from the API docs: "a name that should be unique for this application and + // consistent between sessions, such as the application name itself" + return QCoreApplication::applicationName(); +} + +bool QStatusNotifierItemAdaptor::itemIsMenu() const +{ + // From KDE docs: if this is true, the item only supports the context menu, + // so the visualization should prefer sending ContextMenu() instead of Activate(). + // But QSystemTrayIcon doesn't have such a setting: it will emit activated() + // and the application is free to use it or ignore it; we don't know whether it will. + return false; +} + +QDBusObjectPath QStatusNotifierItemAdaptor::menu() const +{ + return QDBusObjectPath(m_trayIcon->menu() ? "/MenuBar" : "/NO_DBUSMENU"); +} + +QString QStatusNotifierItemAdaptor::overlayIconName() const +{ + return QString(); +} + +QXdgDBusImageVector QStatusNotifierItemAdaptor::overlayIconPixmap() const +{ + QXdgDBusImageVector ret; // empty vector + return ret; +} + +QString QStatusNotifierItemAdaptor::status() const +{ + return m_trayIcon->status(); +} + +QString QStatusNotifierItemAdaptor::title() const +{ + // Shown e.g. when the icon is hidden, in the popup showing all hidden items. + // Since QSystemTrayIcon doesn't have this property, the application name + // is the best information we have available. + return QCoreApplication::applicationName(); +} + +QXdgDBusToolTipStruct QStatusNotifierItemAdaptor::toolTip() const +{ + QXdgDBusToolTipStruct ret; + if (m_trayIcon->isRequestingAttention()) { + ret.title = m_trayIcon->attentionTitle(); + ret.subTitle = m_trayIcon->attentionMessage(); + ret.icon = m_trayIcon->attentionIconName(); + } else { + ret.title = m_trayIcon->tooltip(); + } + return ret; +} + +void QStatusNotifierItemAdaptor::Activate(int x, int y) +{ + qCDebug(qLcTray) << x << y; + emit m_trayIcon->activated(QPlatformSystemTrayIcon::Trigger); +} + +void QStatusNotifierItemAdaptor::ContextMenu(int x, int y) +{ + qCDebug(qLcTray) << x << y; + emit m_trayIcon->activated(QPlatformSystemTrayIcon::Context); +} + +void QStatusNotifierItemAdaptor::Scroll(int w, const QString &s) +{ + qCDebug(qLcTray) << w << s; + // unsupported +} + +void QStatusNotifierItemAdaptor::SecondaryActivate(int x, int y) +{ + qCDebug(qLcTray) << x << y; + emit m_trayIcon->activated(QPlatformSystemTrayIcon::MiddleClick); +} + +QT_END_NAMESPACE + +#endif // QT_NO_SYSTEMTRAYICON diff --git a/src/platformsupport/themes/genericunix/dbustray/qstatusnotifieritemadaptor_p.h b/src/platformsupport/themes/genericunix/dbustray/qstatusnotifieritemadaptor_p.h new file mode 100644 index 0000000000..776e1b23ef --- /dev/null +++ b/src/platformsupport/themes/genericunix/dbustray/qstatusnotifieritemadaptor_p.h @@ -0,0 +1,204 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + This file was originally created by qdbusxml2cpp version 0.8 + Command line was: + qdbusxml2cpp -a statusnotifieritem ../../3rdparty/dbus-ifaces/org.kde.StatusNotifierItem.xml + + However it is maintained manually. + + It is also not part of the public API. This header file may change from + version to version without notice, or even be removed. +*/ + +#ifndef QSTATUSNOTIFIERITEMADAPTER_P_H +#define QSTATUSNOTIFIERITEMADAPTER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +#ifndef QT_NO_SYSTEMTRAYICON + +#include +#include + +#include "qdbustraytypes_p.h" + +QT_BEGIN_NAMESPACE +class QDBusTrayIcon; + +/* + Adaptor class for interface org.kde.StatusNotifierItem + see http://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/ + (also http://www.notmart.org/misc/statusnotifieritem/) +*/ +class QStatusNotifierItemAdaptor: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.StatusNotifierItem") + Q_CLASSINFO("D-Bus Introspection", "" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" + "") +public: + QStatusNotifierItemAdaptor(QDBusTrayIcon *parent); + virtual ~QStatusNotifierItemAdaptor(); + +public: // PROPERTIES + Q_PROPERTY(QString AttentionIconName READ attentionIconName) + QString attentionIconName() const; + + Q_PROPERTY(QXdgDBusImageVector AttentionIconPixmap READ attentionIconPixmap) + QXdgDBusImageVector attentionIconPixmap() const; + + Q_PROPERTY(QString AttentionMovieName READ attentionMovieName) + QString attentionMovieName() const; + + Q_PROPERTY(QString Category READ category) + QString category() const; + + Q_PROPERTY(QString IconName READ iconName) + QString iconName() const; + + Q_PROPERTY(QXdgDBusImageVector IconPixmap READ iconPixmap) + QXdgDBusImageVector iconPixmap() const; + + Q_PROPERTY(QString Id READ id) + QString id() const; + + Q_PROPERTY(bool ItemIsMenu READ itemIsMenu) + bool itemIsMenu() const; + + Q_PROPERTY(QDBusObjectPath Menu READ menu) + QDBusObjectPath menu() const; + + Q_PROPERTY(QString OverlayIconName READ overlayIconName) + QString overlayIconName() const; + + Q_PROPERTY(QXdgDBusImageVector OverlayIconPixmap READ overlayIconPixmap) + QXdgDBusImageVector overlayIconPixmap() const; + + Q_PROPERTY(QString Status READ status) + QString status() const; + + Q_PROPERTY(QString Title READ title) + QString title() const; + + Q_PROPERTY(QXdgDBusToolTipStruct ToolTip READ toolTip) + QXdgDBusToolTipStruct toolTip() const; + +public Q_SLOTS: // METHODS + void Activate(int x, int y); + void ContextMenu(int x, int y); + void Scroll(int delta, const QString &orientation); + void SecondaryActivate(int x, int y); +Q_SIGNALS: // SIGNALS + void NewAttentionIcon(); + void NewIcon(); + void NewOverlayIcon(); + void NewStatus(const QString &status); + void NewTitle(); + void NewToolTip(); + +private: + QDBusTrayIcon *m_trayIcon; +}; + +QT_END_NAMESPACE +#endif // QT_NO_SYSTEMTRAYICON +#endif // QSTATUSNOTIFIERITEMADAPTER_P_H diff --git a/src/platformsupport/themes/genericunix/dbustray/qxdgnotificationproxy.cpp b/src/platformsupport/themes/genericunix/dbustray/qxdgnotificationproxy.cpp new file mode 100644 index 0000000000..ef2aa799c8 --- /dev/null +++ b/src/platformsupport/themes/genericunix/dbustray/qxdgnotificationproxy.cpp @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qxdgnotificationproxy_p.h" + +QT_BEGIN_NAMESPACE + +QXdgNotificationInterface::QXdgNotificationInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +QXdgNotificationInterface::~QXdgNotificationInterface() +{ +} + +QT_END_NAMESPACE diff --git a/src/platformsupport/themes/genericunix/dbustray/qxdgnotificationproxy_p.h b/src/platformsupport/themes/genericunix/dbustray/qxdgnotificationproxy_p.h new file mode 100644 index 0000000000..03899723ab --- /dev/null +++ b/src/platformsupport/themes/genericunix/dbustray/qxdgnotificationproxy_p.h @@ -0,0 +1,152 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + This file was originally created by qdbusxml2cpp version 0.8 + Command line was: + qdbusxml2cpp -p qxdgnotificationproxy ../../3rdparty/dbus-ifaces/org.freedesktop.Notifications.xml + + However it is maintained manually. + + It is also not part of the public API. This header file may change from + version to version without notice, or even be removed. +*/ + +#ifndef QXDGNOTIFICATIONPROXY_P_H +#define QXDGNOTIFICATIONPROXY_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(qLcTray) + +/* + * Proxy class for interface org.freedesktop.Notifications + */ +class QXdgNotificationInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "org.freedesktop.Notifications"; } + +public: + QXdgNotificationInterface(const QString &service, const QString &path, + const QDBusConnection &connection, QObject *parent = 0); + + ~QXdgNotificationInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply<> closeNotification(uint id) + { + QList argumentList; + argumentList << QVariant::fromValue(id); + return asyncCallWithArgumentList(QStringLiteral("CloseNotification"), argumentList); + } + + inline QDBusPendingReply getCapabilities() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("GetCapabilities"), argumentList); + } + + inline QDBusPendingReply getServerInformation() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("GetServerInformation"), argumentList); + } + inline QDBusReply getServerInformation(QString &vendor, QString &version, QString &specVersion) + { + QList argumentList; + QDBusMessage reply = callWithArgumentList(QDBus::Block, QStringLiteral("GetServerInformation"), argumentList); + if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 4) { + vendor = qdbus_cast(reply.arguments().at(1)); + version = qdbus_cast(reply.arguments().at(2)); + specVersion = qdbus_cast(reply.arguments().at(3)); + } + return reply; + } + + // see https://developer.gnome.org/notification-spec/#basic-design + inline QDBusPendingReply notify(const QString &appName, uint replacesId, const QString &appIcon, + const QString &summary, const QString &body, const QStringList &actions, + const QVariantMap &hints, int timeout) + { + qCDebug(qLcTray) << appName << replacesId << appIcon << summary << body << actions << hints << timeout; + QList argumentList; + argumentList << QVariant::fromValue(appName) << QVariant::fromValue(replacesId) << + QVariant::fromValue(appIcon) << QVariant::fromValue(summary) << + QVariant::fromValue(body) << QVariant::fromValue(actions) << + QVariant::fromValue(hints) << QVariant::fromValue(timeout); + return asyncCallWithArgumentList(QStringLiteral("Notify"), argumentList); + } + +Q_SIGNALS: + void ActionInvoked(uint id, const QString &action_key); + void NotificationClosed(uint id, uint reason); +}; + +namespace org { + namespace freedesktop { + typedef ::QXdgNotificationInterface Notifications; + } +} + +QT_END_NAMESPACE + +#endif diff --git a/src/platformsupport/themes/genericunix/genericunix.pri b/src/platformsupport/themes/genericunix/genericunix.pri index eed48257d0..27019b4aa2 100644 --- a/src/platformsupport/themes/genericunix/genericunix.pri +++ b/src/platformsupport/themes/genericunix/genericunix.pri @@ -1,2 +1,7 @@ HEADERS += $$PWD/qgenericunixthemes_p.h SOURCES += $$PWD/qgenericunixthemes.cpp + +qtConfig(dbus) { + include(dbusmenu/dbusmenu.pri) + include(dbustray/dbustray.pri) +} -- cgit v1.2.3