From b858144c9d38623bdd9afaa02c404d9515243ab7 Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Tue, 16 Feb 2010 16:58:24 +0100 Subject: [PATCH] Basic StatusNotifierItem support This implements the new dbus spec that replaces the old systray: Until the spec has been ratified by freedesktop.org (which should happen soon), we're using the org.kde namespace to get it working in newish (>= 4.4) KDE versions at least. In order to support this even without KDE integration, we've taken a bunch of code from KDE's implementation (written by Marco Martin), only using the parts that are relevant for Quassel, and adapting them to our needs. In case no DBus support is present, or noone listens for the service, we fall back to the classical tray icon. Various bits and pieces are still missing, e.g. tooltips, and the context menu isn't working yet if Qt doesn't support QSystemTrayIcon (but you'll get the dbus item if there's a service listening even without tray icon support in Qt). --- interfaces/org.kde.StatusNotifierItem.xml | 91 ++++++ interfaces/org.kde.StatusNotifierWatcher.xml | 39 +++ src/qtui/CMakeLists.txt | 8 + src/qtui/mainwin.cpp | 5 +- src/qtui/statusnotifieritem.cpp | 177 ++++++++++++ src/qtui/statusnotifieritem.h | 79 +++++ src/qtui/statusnotifieritemdbus.cpp | 287 +++++++++++++++++++ src/qtui/statusnotifieritemdbus.h | 225 +++++++++++++++ 8 files changed, 910 insertions(+), 1 deletion(-) create mode 100644 interfaces/org.kde.StatusNotifierItem.xml create mode 100644 interfaces/org.kde.StatusNotifierWatcher.xml create mode 100644 src/qtui/statusnotifieritem.cpp create mode 100644 src/qtui/statusnotifieritem.h create mode 100644 src/qtui/statusnotifieritemdbus.cpp create mode 100644 src/qtui/statusnotifieritemdbus.h diff --git a/interfaces/org.kde.StatusNotifierItem.xml b/interfaces/org.kde.StatusNotifierItem.xml new file mode 100644 index 00000000..7c3acd51 --- /dev/null +++ b/interfaces/org.kde.StatusNotifierItem.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/interfaces/org.kde.StatusNotifierWatcher.xml b/interfaces/org.kde.StatusNotifierWatcher.xml new file mode 100644 index 00000000..5e043dc9 --- /dev/null +++ b/interfaces/org.kde.StatusNotifierWatcher.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/qtui/CMakeLists.txt b/src/qtui/CMakeLists.txt index 920fe2c2..4b76e972 100644 --- a/src/qtui/CMakeLists.txt +++ b/src/qtui/CMakeLists.txt @@ -154,6 +154,14 @@ else(HAVE_KDE) endif(HAVE_PHONON) endif(HAVE_KDE) +if(HAVE_DBUS) + set(SOURCES ${SOURCES} statusnotifieritem.cpp statusnotifieritemdbus.cpp) + set(MOC_HDRS ${MOC_HDRS} statusnotifieritem.h statusnotifieritemdbus.h) + set(FORMS ${FORMS}) + qt4_add_dbus_interface(DBUS ../../interfaces/org.kde.StatusNotifierWatcher.xml statusnotifierwatcher) + qt4_add_dbus_adaptor(DBUS ../../interfaces/org.kde.StatusNotifierItem.xml statusnotifieritemdbus.h StatusNotifierItemDBus) +endif(HAVE_DBUS) + if(HAVE_SSL) set(SOURCES ${SOURCES} sslinfodlg.cpp) set(MOC_HDRS ${MOC_HDRS} sslinfodlg.h) diff --git a/src/qtui/mainwin.cpp b/src/qtui/mainwin.cpp index ea361d96..b2f18414 100644 --- a/src/qtui/mainwin.cpp +++ b/src/qtui/mainwin.cpp @@ -79,6 +79,7 @@ #include "qtuistyle.h" #include "settingsdlg.h" #include "settingspagedlg.h" +#include "statusnotifieritem.h" #include "toolbaractionprovider.h" #include "topicwidget.h" #include "verticaldock.h" @@ -676,7 +677,9 @@ void MainWin::saveStatusBarStatus(bool enabled) { } void MainWin::setupSystray() { -#ifndef QT_NO_SYSTEMTRAYICON +#ifdef HAVE_DBUS + _systemTray = new StatusNotifierItem(this); +#elif !defined QT_NO_SYSTEMTRAYICON _systemTray = new LegacySystemTray(this); #else _systemTray = new SystemTray(this); // dummy diff --git a/src/qtui/statusnotifieritem.cpp b/src/qtui/statusnotifieritem.cpp new file mode 100644 index 00000000..da15475b --- /dev/null +++ b/src/qtui/statusnotifieritem.cpp @@ -0,0 +1,177 @@ +/*************************************************************************** + * Copyright (C) 2005-2010 by the Quassel Project * + * devel@quassel-irc.org * + * * + * This contains code from KStatusNotifierItem, part of the KDE libs * + * Copyright (C) 2009 Marco Martin * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) version 3. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifdef HAVE_DBUS + +#include "statusnotifieritem.h" +#include "statusnotifieritemdbus.h" + +#include +#include + +const int StatusNotifierItem::_protocolVersion = 0; + +StatusNotifierItem::StatusNotifierItem(QWidget *parent) + : StatusNotifierItemParent(parent), + _statusNotifierItemDBus(0), + _statusNotifierWatcher(0) +{ + +} + +StatusNotifierItem::~StatusNotifierItem() { + delete _statusNotifierWatcher; + +} + +void StatusNotifierItem::init() { +// workaround until we handle the tray menu more sanely +#ifdef QT_NO_SYSTEMTRAYICON + setTrayMenu(new QMenu(associatedWidget())); +#endif + + trayMenu()->installEventFilter(this); + + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); + + _statusNotifierItemDBus = new StatusNotifierItemDBus(this); + + connect(QDBusConnection::sessionBus().interface(), SIGNAL(serviceOwnerChanged(QString,QString,QString)), + SLOT(serviceChange(QString,QString,QString))); + + setMode(StatusNotifier); + + StatusNotifierItemParent::init(); +} + +void StatusNotifierItem::registerToDaemon() { + if(!_statusNotifierWatcher) { + QString interface("org.kde.StatusNotifierWatcher"); + _statusNotifierWatcher = new org::kde::StatusNotifierWatcher(interface, "/StatusNotifierWatcher", + QDBusConnection::sessionBus()); + } + if(_statusNotifierWatcher->isValid() + && _statusNotifierWatcher->property("ProtocolVersion").toInt() == _protocolVersion) { + + _statusNotifierWatcher->RegisterStatusNotifierItem(_statusNotifierItemDBus->service()); + + } else { + qDebug() << "StatusNotifierWatcher not reachable!"; + setMode(Legacy); + } +} + +// FIXME remove deprecated slot with Qt 4.6 +void StatusNotifierItem::serviceChange(const QString& name, const QString& oldOwner, const QString& newOwner) { + bool legacy = false; + if(name == "org.kde.StatusNotifierWatcher") { + if(newOwner.isEmpty()) { + //unregistered + //qDebug() << "Connection to the StatusNotifierWatcher lost"; + legacy = true; + } else if(oldOwner.isEmpty()) { + //registered + legacy = false; + } + } else if(name.startsWith(QLatin1String("org.kde.StatusNotifierHost-"))) { + if(newOwner.isEmpty() && (!_statusNotifierWatcher || + !_statusNotifierWatcher->property("IsStatusNotifierHostRegistered").toBool())) { + //qDebug() << "Connection to the last StatusNotifierHost lost"; + legacy = true; + } else if(oldOwner.isEmpty()) { + //qDebug() << "New StatusNotifierHost"; + legacy = false; + } + } else { + return; + } + + // qDebug() << "Service " << name << "status change, old owner:" << oldOwner << "new:" << newOwner; + + if(legacy == (mode() == Legacy)) { + return; + } + + if(legacy) { + //unregistered + setMode(Legacy); + } else { + //registered + setMode(StatusNotifier); + } +} + +void StatusNotifierItem::setMode(Mode mode_) { + StatusNotifierItemParent::setMode(mode_); + + if(mode() == StatusNotifier) { + registerToDaemon(); + } +} + +void StatusNotifierItem::setState(State state_) { + StatusNotifierItemParent::setState(state_); + + emit _statusNotifierItemDBus->NewStatus(metaObject()->enumerator(metaObject()->indexOfEnumerator("State")).valueToKey(state())); + emit _statusNotifierItemDBus->NewIcon(); +} + +QString StatusNotifierItem::title() const { + return QString("Quassel IRC"); +} + +QString StatusNotifierItem::iconName() const { + if(state() == Passive) + return QString("quassel_inactive"); + else + return QString("quassel"); +} + +QString StatusNotifierItem::attentionIconName() const { + return QString("quassel_message"); +} + +QString StatusNotifierItem::toolTipIconName() const { + return QString("quassel"); +} + +void StatusNotifierItem::activated(const QPoint &pos) { + Q_UNUSED(pos) + activate(Trigger); +} + +bool StatusNotifierItem::eventFilter(QObject *watched, QEvent *event) { + if(mode() == StatusNotifier) { + //FIXME: ugly ugly workaround to weird QMenu's focus problems + if(watched == trayMenu() && + (event->type() == QEvent::WindowDeactivate || (event->type() == QEvent::MouseButtonRelease && static_cast(event)->button() == Qt::LeftButton))) { + // put at the back of event queue to let the action activate anyways + QTimer::singleShot(0, trayMenu(), SLOT(hide())); + } + } + return StatusNotifierItemParent::eventFilter(watched, event); +} + +#endif diff --git a/src/qtui/statusnotifieritem.h b/src/qtui/statusnotifieritem.h new file mode 100644 index 00000000..2efbefda --- /dev/null +++ b/src/qtui/statusnotifieritem.h @@ -0,0 +1,79 @@ +/*************************************************************************** + * Copyright (C) 2005-2010 by the Quassel Project * + * devel@quassel-irc.org * + * * + * This contains code from KStatusNotifierItem, part of the KDE libs * + * Copyright (C) 2009 Marco Martin * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) version 3. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef STATUSNOTIFIERITEM_H_ +#define STATUSNOTIFIERITEM_H_ + +#ifdef HAVE_DBUS + +#include "systemtray.h" +#include "statusnotifierwatcher.h" + +#ifdef QT_NO_SYSTEMTRAYICON +# define StatusNotifierItemParent SystemTray +#else +# define StatusNotifierItemParent LegacySystemTray +# include "legacysystemtray.h" +#endif + +class StatusNotifierItemDBus; + +class StatusNotifierItem : public StatusNotifierItemParent { + Q_OBJECT + +public: + explicit StatusNotifierItem(QWidget *parent); + virtual ~StatusNotifierItem(); + +public slots: + virtual void setState(State state); + +protected: + virtual void init(); + virtual void setMode(Mode mode); + + QString title() const; + QString iconName() const; + QString attentionIconName() const; + QString toolTipIconName() const; + + virtual bool eventFilter(QObject *watched, QEvent *event); + +private slots: + void activated(const QPoint &pos); + void serviceChange(const QString& name, const QString& oldOwner, const QString& newOwner); + +private: + void registerToDaemon(); + + static const int _protocolVersion; + StatusNotifierItemDBus *_statusNotifierItemDBus; + + org::kde::StatusNotifierWatcher *_statusNotifierWatcher; + //org::freedesktop::Notifications *_notificationsClient; + + friend class StatusNotifierItemDBus; +}; + +#endif /* HAVE_DBUS */ +#endif /* STATUSNOTIFIERITEM_H_ */ diff --git a/src/qtui/statusnotifieritemdbus.cpp b/src/qtui/statusnotifieritemdbus.cpp new file mode 100644 index 00000000..db93d5c2 --- /dev/null +++ b/src/qtui/statusnotifieritemdbus.cpp @@ -0,0 +1,287 @@ +/*************************************************************************** + * The original file is part of the KDE libraries * + * Copyright (C) 2009 by Marco Martin * + * Quasselfied 2010 by Manuel Nickschas * + * * + * This file is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "statusnotifieritemdbus.h" +#include "statusnotifieritem.h" +#include "qtui.h" + +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_KDE +# include +# include +#endif + +#include "statusnotifierwatcher.h" +#include "statusnotifieritemadaptor.h" + +// Marshall the ImageStruct data into a D-BUS argument +const QDBusArgument &operator<<(QDBusArgument &argument, const DBusImageStruct &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, DBusImageStruct &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 DBusImageVector &iconVector) +{ + argument.beginArray(qMetaTypeId()); + for (int i=0; i>(const QDBusArgument &argument, DBusImageVector &iconVector) +{ + argument.beginArray(); + iconVector.clear(); + + while ( !argument.atEnd() ) { + DBusImageStruct 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 DBusToolTipStruct &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, DBusToolTipStruct &toolTip) +{ + QString icon; + DBusImageVector 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; +} + + +int StatusNotifierItemDBus::s_serviceCount = 0; + +StatusNotifierItemDBus::StatusNotifierItemDBus(StatusNotifierItem *parent) + : QObject(parent), + m_statusNotifierItem(parent), + m_service(QString("org.kde.StatusNotifierItem-%1-%2") + .arg(QCoreApplication::applicationPid()) + .arg(++s_serviceCount)), + m_dbus(QDBusConnection::connectToBus(QDBusConnection::SessionBus, m_service)) +{ + new StatusNotifierItemAdaptor(this); + qDebug() << "service is" << m_service; + m_dbus.registerService(m_service); + m_dbus.registerObject("/StatusNotifierItem", this); +} + +StatusNotifierItemDBus::~StatusNotifierItemDBus() +{ + m_dbus.unregisterService(m_service); +} + +QString StatusNotifierItemDBus::service() const +{ + return m_service; +} + +//DBUS slots +//Values and calls have been adapted to Quassel + +QString StatusNotifierItemDBus::Category() const +{ + return QString("Communications"); // no need to make this configurable for Quassel +} + +QString StatusNotifierItemDBus::Title() const +{ + return m_statusNotifierItem->title(); +} + +QString StatusNotifierItemDBus::Id() const +{ + return QString("QuasselIRC"); +} + +QString StatusNotifierItemDBus::Status() const + { + return m_statusNotifierItem->metaObject()->enumerator(m_statusNotifierItem->metaObject()->indexOfEnumerator("State")).valueToKey(m_statusNotifierItem->state()); +} + +int StatusNotifierItemDBus::WindowId() const +{ + return (int)QtUi::mainWindow()->winId(); +} + + +//Icon +//We don't need to support serialized icon data in Quassel + +QString StatusNotifierItemDBus::IconName() const +{ + return m_statusNotifierItem->iconName(); +} + +DBusImageVector StatusNotifierItemDBus::IconPixmap() const +{ + return DBusImageVector(); +} + +QString StatusNotifierItemDBus::OverlayIconName() const +{ + return QString(); +} + +DBusImageVector StatusNotifierItemDBus::OverlayIconPixmap() const +{ + return DBusImageVector(); +} + +//Requesting attention icon and movie + +QString StatusNotifierItemDBus::AttentionIconName() const +{ + return m_statusNotifierItem->attentionIconName(); +} + +DBusImageVector StatusNotifierItemDBus::AttentionIconPixmap() const +{ + return DBusImageVector(); +} + +QString StatusNotifierItemDBus::AttentionMovieName() const +{ + return QString(); +} + + +//ToolTip + +DBusToolTipStruct StatusNotifierItemDBus::ToolTip() const +{ + DBusToolTipStruct toolTip; + toolTip.icon = m_statusNotifierItem->toolTipIconName(); + toolTip.image = DBusImageVector(); + toolTip.title = m_statusNotifierItem->toolTipTitle(); + toolTip.subTitle = m_statusNotifierItem->toolTipSubTitle(); + + return toolTip; +} + +//Interaction + +void StatusNotifierItemDBus::ContextMenu(int x, int y) +{ + if (!m_statusNotifierItem->trayMenu()) { + return; + } + + //TODO: nicer placement, possible? + if (!m_statusNotifierItem->trayMenu()->isVisible()) { + m_statusNotifierItem->trayMenu()->setWindowFlags(Qt::Window|Qt::FramelessWindowHint); + m_statusNotifierItem->trayMenu()->popup(QPoint(x,y)); +#ifdef HAVE_KDE + KWindowSystem::setState(m_statusNotifierItem->trayMenu()->winId(), NET::SkipTaskbar|NET::SkipPager|NET::KeepAbove); + KWindowSystem::setType(m_statusNotifierItem->trayMenu()->winId(), NET::PopupMenu); + KWindowSystem::forceActiveWindow(m_statusNotifierItem->trayMenu()->winId()); +#endif + } else { + m_statusNotifierItem->trayMenu()->hide(); + } +} + +void StatusNotifierItemDBus::Activate(int x, int y) +{ + m_statusNotifierItem->activated(QPoint(x,y)); +} + +void StatusNotifierItemDBus::SecondaryActivate(int x, int y) +{ + Q_UNUSED(x) + Q_UNUSED(y) + // emit m_statusNotifierItem->secondaryActivateRequested(QPoint(x,y)); +} + +void StatusNotifierItemDBus::Scroll(int delta, const QString &orientation) +{ + Q_UNUSED(delta) + Q_UNUSED(orientation) + // Qt::Orientation dir = (orientation.toLower() == "horizontal" ? Qt::Horizontal : Qt::Vertical); + // emit m_statusNotifierItem->scrollRequested(delta, dir); +} diff --git a/src/qtui/statusnotifieritemdbus.h b/src/qtui/statusnotifieritemdbus.h new file mode 100644 index 00000000..670a7c76 --- /dev/null +++ b/src/qtui/statusnotifieritemdbus.h @@ -0,0 +1,225 @@ +/*************************************************************************** + * The original file is part of the KDE libraries * + * Copyright (C) 2009 by Marco Martin * + * Quasselfied 2010 by Manuel Nickschas * + * * + * This file is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef STATUSNOTIFIERITEMDBUS_H_ +#define STATUSNOTIFIERITEMDBUS_H_ + +#include +#include +#include +#include +#include + +//Custom message type for DBus +struct DBusImageStruct { + int width; + int height; + QByteArray data; +}; + +typedef QVector DBusImageVector; + +struct DBusToolTipStruct { + QString icon; + DBusImageVector image; + QString title; + QString subTitle; +}; + +class StatusNotifierItem; + +class StatusNotifierItemDBus : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QString Category READ Category) + Q_PROPERTY(QString Id READ Id) + Q_PROPERTY(QString Title READ Title) + Q_PROPERTY(QString Status READ Status) + Q_PROPERTY(int WindowId READ WindowId) + Q_PROPERTY(QString IconName READ IconName) + Q_PROPERTY(DBusImageVector IconPixmap READ IconPixmap) + Q_PROPERTY(QString OverlayIconName READ OverlayIconName) + Q_PROPERTY(DBusImageVector OverlayIconPixmap READ OverlayIconPixmap) + Q_PROPERTY(QString AttentionIconName READ AttentionIconName) + Q_PROPERTY(DBusImageVector AttentionIconPixmap READ AttentionIconPixmap) + Q_PROPERTY(QString AttentionMovieName READ AttentionMovieName) + Q_PROPERTY(DBusToolTipStruct ToolTip READ ToolTip) + + friend class StatusNotifierItem; +public: + StatusNotifierItemDBus(StatusNotifierItem *parent); + ~StatusNotifierItemDBus(); + + /** + * @return the service this object is registered on the bus under + */ + QString service() const; + + /** + * @return the category of the application associated to this item + * @see Category + */ + QString Category() const; + + /** + * @return the id of this item + */ + QString Id() const; + + /** + * @return the title of this item + */ + QString Title() const; + + /** + * @return The status of this item + * @see Status + */ + QString Status() const; + + /** + * @return The id of the main window of the application that controls the item + */ + int WindowId() const; + + /** + * @return the name of the main icon to be displayed + * if image() is not empty this will always return an empty string + */ + QString IconName() const; + + /** + * @return a serialization of the icon data + */ + DBusImageVector IconPixmap() const; + + /** + * @return the name of the overlay of the main icon to be displayed + * if image() is not empty this will always return an empty string + */ + QString OverlayIconName() const; + + /** + * @return a serialization of the icon data + */ + DBusImageVector OverlayIconPixmap() const; + + /** + * @return the name of the icon to be displayed when the application + * is requesting the user's attention + * if attentionImage() is not empty this will always return an empty string + */ + QString AttentionIconName() const; + + /** + * @return a serialization of the requesting attention icon data + */ + DBusImageVector AttentionIconPixmap() const; + + /** + * @return the name of the attention movie + */ + QString AttentionMovieName() const; + + /** + * all the data needed for a tooltip + */ + DBusToolTipStruct ToolTip() const; + + +public Q_SLOTS: + //interaction + /** + * Shows the context menu associated to this item + * at the desired screen position + */ + void ContextMenu(int x, int y); + + /** + * Shows the main widget and try to position it on top + * of the other windows, if the widget is already visible, hide it. + */ + void Activate(int x, int y); + + /** + * The user activated the item in an alternate way (for instance with middle mouse button, this depends from the systray implementation) + */ + void SecondaryActivate(int x, int y); + + /** + * Inform this item that the mouse wheel was used on its representation + */ + void Scroll(int delta, const QString &orientation); + +Q_SIGNALS: + /** + * Inform the systemtray that the own main icon has been changed, + * so should be reloaded + */ + void NewIcon(); + + /** + * Inform the systemtray that there is a new icon to be used as overlay + */ + void NewOverlayIcon(); + + /** + * Inform the systemtray that the requesting attention icon + * has been changed, so should be reloaded + */ + void NewAttentionIcon(); + + /** + * Inform the systemtray that something in the tooltip has been changed + */ + void NewToolTip(); + + /** + * Signal the new status when it has been changed + * @see Status + */ + void NewStatus(const QString &status); + +private: + StatusNotifierItem *m_statusNotifierItem; + QString m_service; + QDBusConnection m_dbus; + static int s_serviceCount; +}; + + +const QDBusArgument &operator<<(QDBusArgument &argument, const DBusImageStruct &icon); +const QDBusArgument &operator>>(const QDBusArgument &argument, DBusImageStruct &icon); + +Q_DECLARE_METATYPE(DBusImageStruct) + +const QDBusArgument &operator<<(QDBusArgument &argument, const DBusImageVector &iconVector); +const QDBusArgument &operator>>(const QDBusArgument &argument, DBusImageVector &iconVector); + +Q_DECLARE_METATYPE(DBusImageVector) + +const QDBusArgument &operator<<(QDBusArgument &argument, const DBusToolTipStruct &toolTip); +const QDBusArgument &operator>>(const QDBusArgument &argument, DBusToolTipStruct &toolTip); + +Q_DECLARE_METATYPE(DBusToolTipStruct) + +#endif -- 2.20.1