Remove dependency on libnotify and use dbus directly.
This commit is contained in:
parent
2e71390acd
commit
7250587c03
|
@ -30,19 +30,12 @@ if(WIN32)
|
|||
else(WIN32)
|
||||
pkg_check_modules(TAGLIB taglib)
|
||||
pkg_check_modules(XINE libxine)
|
||||
pkg_check_modules(LIBNOTIFY libnotify)
|
||||
endif(WIN32)
|
||||
|
||||
if (NOT Boost_FOUND)
|
||||
message(FATAL_ERROR "Boost not found")
|
||||
endif (NOT Boost_FOUND)
|
||||
|
||||
if (LIBNOTIFY_FOUND)
|
||||
add_definitions(-DHAVE_LIBNOTIFY)
|
||||
link_directories(${LIBNOTIFY_LIBRARY_DIRS})
|
||||
include_directories(${LIBNOTIFY_INCLUDE_DIRS})
|
||||
endif (LIBNOTIFY_FOUND)
|
||||
|
||||
if (TAGLIB_VERSION VERSION_LESS 1.6)
|
||||
message(FATAL_ERROR "Taglib version 1.6 or greater is required")
|
||||
endif (TAGLIB_VERSION VERSION_LESS 1.6)
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||
<node>
|
||||
<interface name="org.freedesktop.Notifications">
|
||||
<method name="GetServerInformation">
|
||||
<arg name="return_name" type="s" direction="out"/>
|
||||
<arg name="return_vendor" type="s" direction="out"/>
|
||||
<arg name="return_version" type="s" direction="out"/>
|
||||
<arg name="return_spec_version" type="s" direction="out"/>
|
||||
</method>
|
||||
<method name="GetCapabilities">
|
||||
<arg name="return_caps" type="as" direction="out"/>
|
||||
</method>
|
||||
<method name="CloseNotification">
|
||||
<arg name="id" type="u" direction="in"/>
|
||||
</method>
|
||||
<method name="Notify">
|
||||
<arg name="app_name" type="s" direction="in"/>
|
||||
<arg name="id" type="u" direction="in"/>
|
||||
<arg name="icon" type="s" direction="in"/>
|
||||
<arg name="summary" type="s" direction="in"/>
|
||||
<arg name="body" type="s" direction="in"/>
|
||||
<arg name="actions" type="as" direction="in"/>
|
||||
<arg name="hints" type="a{sv}" direction="in"/>
|
||||
<annotation name="com.trolltech.QtDBus.QtTypeName.In6" value="QVariantMap"/>
|
||||
<arg name="timeout" type="i" direction="in"/>
|
||||
<arg name="return_id" type="u" direction="out"/>
|
||||
</method>
|
||||
</interface>
|
||||
</node>
|
|
@ -184,6 +184,7 @@ else(APPLE)
|
|||
set(CLEMENTINE-SOURCES ${CLEMENTINE-SOURCES} osd_win.cpp)
|
||||
else(WIN32)
|
||||
set(CLEMENTINE-SOURCES ${CLEMENTINE-SOURCES} osd_x11.cpp)
|
||||
# MPRIS
|
||||
qt4_add_dbus_adaptor(MPRIS-PLAYER-SOURCES
|
||||
../data/org.freedesktop.MediaPlayer.player.xml
|
||||
player.h Player mpris_player MprisPlayer)
|
||||
|
@ -193,10 +194,16 @@ else(APPLE)
|
|||
qt4_add_dbus_adaptor(MPRIS-TRACKLIST-SOURCES
|
||||
../data/org.freedesktop.MediaPlayer.tracklist.xml
|
||||
player.h Player mpris_tracklist MprisTrackList)
|
||||
|
||||
# org.freedesktop.Notifications
|
||||
qt4_add_dbus_interface(NOTIFICATION-SOURCES
|
||||
../data/org.freedesktop.Notifications.xml
|
||||
notification)
|
||||
set(CLEMENTINE-SOURCES ${CLEMENTINE-SOURCES}
|
||||
${MPRIS-PLAYER-SOURCES}
|
||||
${MPRIS-ROOT-SOURCES}
|
||||
${MPRIS-TRACKLIST-SOURCES}
|
||||
${NOTIFICATION-SOURCES}
|
||||
mpris.cpp
|
||||
)
|
||||
set(CLEMENTINE-MOC-HEADERS ${CLEMENTINE-MOC-HEADERS} mpris.h)
|
||||
|
@ -231,7 +238,6 @@ target_link_libraries(clementine_lib
|
|||
qxt
|
||||
lastfm
|
||||
${XINE_LIBRARIES}
|
||||
${LIBNOTIFY_LIBRARIES}
|
||||
${TAGLIB_LIBRARIES}
|
||||
${QT_LIBRARIES}
|
||||
)
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
# include <QDBusConnection>
|
||||
# include <QDBusMetaType>
|
||||
# include "mpris.h"
|
||||
# include "osd.h"
|
||||
#endif
|
||||
|
||||
// Load sqlite plugin on windows
|
||||
|
@ -100,6 +101,7 @@ int main(int argc, char *argv[]) {
|
|||
#ifdef Q_WS_X11
|
||||
qDBusRegisterMetaType<DBusStatus>();
|
||||
qDBusRegisterMetaType<Version>();
|
||||
qDBusRegisterMetaType<QImage>();
|
||||
QDBusConnection::sessionBus().registerService("org.mpris.clementine");
|
||||
MPRIS mpris;
|
||||
#endif
|
||||
|
|
22
src/osd.h
22
src/osd.h
|
@ -25,10 +25,13 @@
|
|||
#include "song.h"
|
||||
|
||||
#ifdef Q_WS_X11
|
||||
# ifndef _NOTIFY_NOTIFICATION_H_
|
||||
struct GdkPixbuf;
|
||||
struct NotifyNotification;
|
||||
# endif
|
||||
#include <QDBusArgument>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include "notification.h"
|
||||
|
||||
QDBusArgument& operator<< (QDBusArgument& arg, const QImage& image);
|
||||
const QDBusArgument& operator>> (const QDBusArgument& arg, QImage& image);
|
||||
|
||||
#endif
|
||||
|
||||
class OSD : public QObject {
|
||||
|
@ -79,15 +82,16 @@ class OSD : public QObject {
|
|||
bool show_on_volume_change_;
|
||||
bool show_art_;
|
||||
|
||||
#ifdef Q_WS_X11
|
||||
NotifyNotification* notification_;
|
||||
GdkPixbuf* pixbuf_;
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_DARWIN
|
||||
class GrowlNotificationWrapper;
|
||||
GrowlNotificationWrapper* wrapper_;
|
||||
#endif // Q_OS_DARWIN
|
||||
|
||||
#ifdef Q_WS_X11
|
||||
boost::scoped_ptr<org::freedesktop::Notifications> interface_;
|
||||
private slots:
|
||||
void CallFinished(QDBusPendingCallWatcher* watcher);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // OSD_H
|
||||
|
|
134
src/osd_x11.cpp
134
src/osd_x11.cpp
|
@ -14,34 +14,55 @@
|
|||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Libnotify headers need to go before Qt ones because they use "signals" as
|
||||
// a variable name
|
||||
#ifdef HAVE_LIBNOTIFY
|
||||
# include <libnotify/notify.h>
|
||||
# include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
# include <glib.h>
|
||||
#endif // HAVE_LIBNOTIFY
|
||||
|
||||
#include "osd.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QtDebug>
|
||||
#include <QTextDocument>
|
||||
|
||||
using boost::scoped_ptr;
|
||||
|
||||
QDBusArgument& operator<< (QDBusArgument& arg, const QImage& image) {
|
||||
if (image.isNull()) {
|
||||
// Sometimes this gets called with a null QImage for no obvious reason.
|
||||
arg.beginStructure();
|
||||
arg << 0 << 0 << 0 << false << 0 << 0 << QByteArray();
|
||||
arg.endStructure();
|
||||
return arg;
|
||||
}
|
||||
QImage scaled = image.scaledToHeight(100, Qt::SmoothTransformation);
|
||||
QImage i = scaled.convertToFormat(QImage::Format_ARGB32).rgbSwapped();
|
||||
arg.beginStructure();
|
||||
arg << i.width();
|
||||
arg << i.height();
|
||||
arg << i.bytesPerLine();
|
||||
arg << i.hasAlphaChannel();
|
||||
int channels = i.isGrayscale() ? 1 : (i.hasAlphaChannel() ? 4 : 3);
|
||||
arg << i.depth() / channels;
|
||||
arg << channels;
|
||||
arg << QByteArray(reinterpret_cast<const char*>(i.bits()), i.numBytes());
|
||||
arg.endStructure();
|
||||
return arg;
|
||||
}
|
||||
|
||||
const QDBusArgument& operator>> (const QDBusArgument& arg, QImage& image) {
|
||||
// This is needed to link but shouldn't be called.
|
||||
Q_ASSERT(0);
|
||||
return arg;
|
||||
}
|
||||
|
||||
void OSD::Init() {
|
||||
notification_ = NULL;
|
||||
pixbuf_ = NULL;
|
||||
#ifdef HAVE_LIBNOTIFY
|
||||
notify_init(QCoreApplication::applicationName().toUtf8().constData());
|
||||
#endif
|
||||
interface_.reset(new org::freedesktop::Notifications(
|
||||
"org.freedesktop.Notifications",
|
||||
"/org/freedesktop/Notifications",
|
||||
QDBusConnection::sessionBus()));
|
||||
if (!interface_->isValid()) {
|
||||
qWarning() << "Error connecting to notifications service.";
|
||||
}
|
||||
}
|
||||
|
||||
bool OSD::SupportsNativeNotifications() {
|
||||
#ifdef HAVE_LIBNOTIFY
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool OSD::SupportsTrayPopups() {
|
||||
|
@ -50,50 +71,45 @@ bool OSD::SupportsTrayPopups() {
|
|||
|
||||
void OSD::ShowMessageNative(const QString& summary, const QString& message,
|
||||
const QString& icon) {
|
||||
#ifdef HAVE_LIBNOTIFY
|
||||
if (summary.isNull())
|
||||
return;
|
||||
|
||||
#define STR(x) (x.isNull() ? NULL : x.toUtf8().constData())
|
||||
|
||||
notification_ = notify_notification_new(
|
||||
STR(summary), STR(Qt::escape(message)), STR(icon), NULL);
|
||||
|
||||
#undef STR
|
||||
|
||||
notify_notification_set_urgency(notification_, NOTIFY_URGENCY_LOW);
|
||||
notify_notification_set_timeout(notification_, timeout_);
|
||||
|
||||
if (pixbuf_) {
|
||||
notify_notification_set_icon_from_pixbuf(notification_, pixbuf_);
|
||||
}
|
||||
|
||||
GError* error = NULL;
|
||||
notify_notification_show(notification_, &error);
|
||||
if (error) {
|
||||
qDebug() << "Error from notify_notification_show:" << error->message;
|
||||
g_error_free(error);
|
||||
}
|
||||
|
||||
pixbuf_ = NULL;
|
||||
#endif // HAVE_LIBNOTIFY
|
||||
QDBusPendingReply<uint> reply = interface_->Notify(
|
||||
QCoreApplication::applicationName(),
|
||||
0,
|
||||
icon,
|
||||
summary,
|
||||
message,
|
||||
QStringList(),
|
||||
QVariantMap(),
|
||||
timeout_);
|
||||
QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(reply, this);
|
||||
connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
|
||||
SLOT(CallFinished(QDBusPendingCallWatcher*)));
|
||||
}
|
||||
|
||||
void OSD::ShowMessageNative(const QString& summary, const QString& message,
|
||||
const QImage& image) {
|
||||
#ifdef HAVE_LIBNOTIFY
|
||||
QImage happy_gdk_image = image.scaledToHeight(100, Qt::SmoothTransformation)
|
||||
.convertToFormat(QImage::Format_RGB888);
|
||||
pixbuf_ = gdk_pixbuf_new_from_data(
|
||||
happy_gdk_image.bits(),
|
||||
GDK_COLORSPACE_RGB,
|
||||
false, // has_alpha
|
||||
8, // bits_per_sample
|
||||
happy_gdk_image.width(),
|
||||
happy_gdk_image.height(),
|
||||
happy_gdk_image.bytesPerLine(),
|
||||
NULL, NULL);
|
||||
|
||||
ShowMessageNative(summary, message, QString());
|
||||
#endif // HAVE_LIBNOTIFY
|
||||
QVariantMap hints;
|
||||
if (!image.isNull()) {
|
||||
hints["image_data"] = QVariant(image);
|
||||
}
|
||||
QDBusPendingReply<uint> reply = interface_->Notify(
|
||||
QCoreApplication::applicationName(),
|
||||
0,
|
||||
QString(),
|
||||
summary,
|
||||
message,
|
||||
QStringList(),
|
||||
hints,
|
||||
timeout_);
|
||||
QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(reply, this);
|
||||
connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
|
||||
SLOT(CallFinished(QDBusPendingCallWatcher*)));
|
||||
}
|
||||
|
||||
void OSD::CallFinished(QDBusPendingCallWatcher* watcher) {
|
||||
scoped_ptr<QDBusPendingCallWatcher> w(watcher);
|
||||
|
||||
QDBusPendingReply<uint> reply = *watcher;
|
||||
if (reply.isError()) {
|
||||
qWarning() << "Error sending notification" << reply.error();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue