diff --git a/src/infoplugins/linux/CMakeLists.txt b/src/infoplugins/linux/CMakeLists.txt index 7ab51bb26..7e02fa288 100644 --- a/src/infoplugins/linux/CMakeLists.txt +++ b/src/infoplugins/linux/CMakeLists.txt @@ -9,6 +9,8 @@ if(NOT Qt5Core_DIR) ${THIRDPARTY_DIR}/libqnetwm/libqnetwm/netwm.cpp ) SET(FDO_LINK_LIBRARIES ${LINK_LIBRARIES} ${X11_LIBRARIES}) + qt4_add_dbus_interface(fdo_srcs fdonotify/org.freedesktop.Notifications.xml + FreedesktopNotificationsProxy) tomahawk_add_plugin(fdonotify TYPE infoplugin EXPORT_MACRO INFOPLUGINDLLEXPORT_PRO diff --git a/src/infoplugins/linux/fdonotify/FdoNotifyPlugin.cpp b/src/infoplugins/linux/fdonotify/FdoNotifyPlugin.cpp index 425af986e..80d1044ae 100644 --- a/src/infoplugins/linux/fdonotify/FdoNotifyPlugin.cpp +++ b/src/infoplugins/linux/fdonotify/FdoNotifyPlugin.cpp @@ -40,6 +40,7 @@ #include "FdoNotifyPlugin.h" #include "utils/TomahawkUtils.h" #include "ImageConverter.h" +#include "FreedesktopNotificationsProxy.h" #include "TomahawkSettings.h" @@ -66,8 +67,12 @@ FdoNotifyPlugin::FdoNotifyPlugin() m_supportedPushTypes << InfoNotifyUser << InfoNowPlaying << InfoTrackUnresolved << InfoNowStopped << InfoInboxReceived; // Query the window manager for its capabilties in styling notifications. - QDBusMessage message = QDBusMessage::createMethodCall( "org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications", "GetCapabilities" ); - QDBusConnection::sessionBus().callWithCallback( message, this, SLOT( dbusCapabiltiesReplyReceived( QDBusMessage ) ) ); + notifications_interface = new org::freedesktop::Notifications("org.freedesktop.Notifications", "/org/freedesktop/Notifications", + QDBusConnection::sessionBus(), this); + QDBusPendingReply reply = notifications_interface->GetCapabilities(); + + QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(reply, this); + connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(dbusCapabilitiesReplyReceived(QDBusPendingCallWatcher*))); } @@ -78,24 +83,17 @@ FdoNotifyPlugin::~FdoNotifyPlugin() void -FdoNotifyPlugin::dbusCapabiltiesReplyReceived( const QDBusMessage& reply ) +FdoNotifyPlugin::dbusCapabilitiesReplyReceived( QDBusPendingCallWatcher* watcher ) { - if ( reply.type() != QDBusMessage::ReplyMessage ) - { - tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Did not receive a ReplyMessage"; + QDBusMessage reply = watcher->reply(); + watcher->deleteLater(); + + if (reply.type() == QDBusMessage::ErrorMessage) { + tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Failed to request capabilities of notifications"; } - const QStringList &list = reply.arguments().at( 0 ).toStringList(); - QListIterator iter( list ); - while ( iter.hasNext() ) - { - QString capabilty = iter.next(); - if ( capabilty.compare( "body-markup" ) == 0 ) - { - m_wmSupportsBodyMarkup = true; - break; - } - } + const QStringList &capability_list = reply.arguments().at( 0 ).toStringList(); + m_wmSupportsBodyMarkup = capability_list.contains("body-markup"); } @@ -151,23 +149,19 @@ FdoNotifyPlugin::getNotificationIconHeight() void FdoNotifyPlugin::notifyUser( const QString& messageText ) { - QDBusMessage message = QDBusMessage::createMethodCall( "org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications", "Notify" ); - - QList arguments; - arguments << QString( "Tomahawk" ); //app_name - arguments << quint32( 0 ); //notification_id - arguments << QString(); //app_icon - arguments << QString( "Tomahawk" ); //summary - arguments << QString( messageText ); //body - arguments << QStringList(); //actions - - QVariantMap dict; - dict["desktop-entry"] = QString( "tomahawk" ); - dict[ "image_data" ] = ImageConverter::variantForImage( QImage( RESPATH "icons/tomahawk-icon-512x512.png" ).scaledToHeight( getNotificationIconHeight() ) ); - arguments << dict; //hints - arguments << qint32( -1 ); //expire_timeout - message.setArguments( arguments ); - QDBusConnection::sessionBus().send( message ); + QVariantMap hints; + hints["desktop-entry"] = QString( "tomahawk" ); + hints[ "image_data" ] = ImageConverter::variantForImage( QImage( RESPATH "icons/tomahawk-icon-512x512.png" ).scaledToHeight( getNotificationIconHeight() ) ); + notifications_interface->Notify( + "Tomahawk", // app_name + 0, // notification_id + "", // app_icon + "Tomahawk", // summary + messageText, // body + QStringList(), // actions + hints, // hints + -1 // expire_timeout + ); } void FdoNotifyPlugin::inboxReceived(const QVariant &input) @@ -216,26 +210,21 @@ void FdoNotifyPlugin::inboxReceived(const QVariant &input) tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "sending message" << messageText; - QDBusMessage message = QDBusMessage::createMethodCall( "org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications", "Notify" ); - QList arguments; - arguments << QString( "Tomahawk" ); //app_name - arguments << m_nowPlayingId; //notification_id - arguments << QString(); //app_icon - arguments << QString( "Tomahawk - Track received" ); //summary - arguments << messageText; //body - arguments << QStringList(); //actions - QVariantMap dict; - dict["desktop-entry"] = QString( "tomahawk" ); + QVariantMap hints; + hints["desktop-entry"] = QString( "tomahawk" ); // Convert image to QVariant and scale to a consistent size. - dict[ "image_data" ] = ImageConverter::variantForImage( QImage( RESPATH "images/inbox-512x512.png" ).scaledToHeight( getNotificationIconHeight() ) ); - - arguments << dict; //hints - arguments << qint32( -1 ); //expire_timeout - message.setArguments( arguments ); - - // Handle reply in a callback, so that this a non-blocking call - QDBusConnection::sessionBus().send( message ); + hints[ "image_data" ] = ImageConverter::variantForImage( QImage( RESPATH "images/inbox-512x512.png" ).scaledToHeight( getNotificationIconHeight() ) ); + notifications_interface->Notify( + "Tomahawk", // app_name + m_nowPlayingId, // notification_id + "", // app_icon + "Tomahawk - Track received", // summary + messageText, // body + QStringList(), // actions + hints, // hints + -1 // expire_timeout + ); } void @@ -286,16 +275,8 @@ FdoNotifyPlugin::nowPlaying( const QVariant& input ) tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "sending message" << messageText; - QDBusMessage message = QDBusMessage::createMethodCall( "org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications", "Notify" ); - QList arguments; - arguments << QString( "Tomahawk" ); //app_name - arguments << m_nowPlayingId; //notification_id - arguments << QString(); //app_icon - arguments << QString( "Tomahawk - Now Playing" ); //summary - arguments << messageText; //body - arguments << QStringList(); //actions - QVariantMap dict; - dict["desktop-entry"] = QString( "tomahawk" ); + QVariantMap hints; + hints["desktop-entry"] = QString( "tomahawk" ); // If there is a cover availble use it, else use Tomahawk logo as default. QImage image; @@ -304,14 +285,24 @@ FdoNotifyPlugin::nowPlaying( const QVariant& input ) else image = QImage( RESPATH "icons/tomahawk-icon-512x512.png" ); // Convert image to QVariant and scale to a consistent size. - dict[ "image_data" ] = ImageConverter::variantForImage( image.scaledToHeight( getNotificationIconHeight() ) ); + hints[ "image_data" ] = ImageConverter::variantForImage( image.scaledToHeight( getNotificationIconHeight() ) ); - arguments << dict; //hints - arguments << qint32( -1 ); //expire_timeout - message.setArguments( arguments ); - // Handle reply in a callback, so that this a non-blocking call - QDBusConnection::sessionBus().callWithCallback( message, this, SLOT( dbusPlayingReplyReceived( QDBusMessage ) ) ); + QDBusPendingReply<> reply = notifications_interface->Notify( + "Tomahawk", // app_name + m_nowPlayingId, // notification_id + "", // app_icon + "Tomahawk - Now Playing", // summary + messageText, // body + QStringList(), // actions + hints, // hints + -1 // expire_timeout + ); + + QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(reply, this); + connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + this, SLOT(RegisterFinished(dbusPlayingReplyReceived*))); + } @@ -319,8 +310,15 @@ FdoNotifyPlugin::nowPlaying( const QVariant& input ) * Handle the DBus reply triggered by FdoNotifyPlugin::nowPlaying */ void -FdoNotifyPlugin::dbusPlayingReplyReceived( const QDBusMessage& reply ) +FdoNotifyPlugin::dbusPlayingReplyReceived( QDBusPendingCallWatcher* watcher ) { + QDBusMessage reply = watcher->reply(); + watcher->deleteLater(); + if (reply.type() == QDBusMessage::ErrorMessage) { + tLog(LOGVERBOSE) << "Failed to grab media keys" << reply.errorName() << reply.errorMessage(); + return; + } + const QVariantList& list = reply.arguments(); if ( list.count() > 0 ) m_nowPlayingId = list.at( 0 ).toInt(); diff --git a/src/infoplugins/linux/fdonotify/FdoNotifyPlugin.h b/src/infoplugins/linux/fdonotify/FdoNotifyPlugin.h index 32003633f..cd27ee6b8 100644 --- a/src/infoplugins/linux/fdonotify/FdoNotifyPlugin.h +++ b/src/infoplugins/linux/fdonotify/FdoNotifyPlugin.h @@ -23,8 +23,9 @@ #include "../../InfoPluginDllMacro.h" #include "infosystem/InfoSystem.h" +#include "FreedesktopNotificationsProxy.h" -#include +#include namespace Tomahawk { @@ -45,8 +46,8 @@ public: protected slots: virtual void init() {} - virtual void dbusPlayingReplyReceived( const QDBusMessage& reply ); - virtual void dbusCapabiltiesReplyReceived( const QDBusMessage& reply ); + virtual void dbusPlayingReplyReceived( QDBusPendingCallWatcher* watcher ); + virtual void dbusCapabilitiesReplyReceived( QDBusPendingCallWatcher* watcher ); virtual void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ) { @@ -72,6 +73,7 @@ private: // Does the window manger support basic XML-based markup (a small HTML subset), see Desktop Notifications specification bool m_wmSupportsBodyMarkup; + org::freedesktop::Notifications* notifications_interface; }; } diff --git a/src/infoplugins/linux/fdonotify/org.freedesktop.Notifications.xml b/src/infoplugins/linux/fdonotify/org.freedesktop.Notifications.xml new file mode 100644 index 000000000..bee75d68c --- /dev/null +++ b/src/infoplugins/linux/fdonotify/org.freedesktop.Notifications.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +