diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a8c6087fc..d0973acea 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -607,6 +607,12 @@ if(HAVE_DBUS) dbus/org.freedesktop.Notifications.xml dbus/notification) + # org.gnome.SettingsDaemon interface + qt4_add_dbus_interface(SOURCES + dbus/org.gnome.SettingsDaemon.MediaKeys.xml + dbus/gnomesettingsdaemon) + + # DeviceKit DBUS interfaces if(HAVE_DEVICEKIT) qt4_add_dbus_interface(SOURCES @@ -785,6 +791,7 @@ if(HAVE_REMOTE) if(HAVE_DBUS) list(APPEND SOURCES remote/avahi.cpp) + list(APPEND HEADERS remote/avahi.h) endif(HAVE_DBUS) endif(HAVE_REMOTE) diff --git a/src/core/globalshortcutbackend.cpp b/src/core/globalshortcutbackend.cpp index bb3770299..d6ad42aed 100644 --- a/src/core/globalshortcutbackend.cpp +++ b/src/core/globalshortcutbackend.cpp @@ -25,56 +25,18 @@ GlobalShortcutBackend::GlobalShortcutBackend(GlobalShortcuts *parent) : QObject(parent), manager_(parent), - active_(false), - register_in_progress_(false), - should_unregister_(false) + active_(false) { } -void GlobalShortcutBackend::Register() { - if (register_in_progress_) { - should_unregister_ = false; - return; - } - - if (RegisterInNewThread()) { - register_in_progress_ = true; - QFuture future = QtConcurrent::run(this, &GlobalShortcutBackend::DoRegister); - - QFutureWatcher* watcher = new QFutureWatcher(this); - watcher->setFuture(future); - connect(watcher, SIGNAL(finished()), SLOT(RegisterFinishedSlot())); - } else { - bool ret = DoRegister(); - if (ret) - active_ = true; - emit RegisterFinished(ret); - } +bool GlobalShortcutBackend::Register() { + bool ret = DoRegister(); + if (ret) + active_ = true; + return ret; } void GlobalShortcutBackend::Unregister() { - if (register_in_progress_) { - should_unregister_ = true; - return; - } - DoUnregister(); active_ = false; } - -void GlobalShortcutBackend::RegisterFinishedSlot() { - QFutureWatcher* watcher = dynamic_cast*>(sender()); - const bool success = watcher->result(); - watcher->deleteLater(); - - register_in_progress_ = false; - if (success) - active_ = true; - - if (should_unregister_) { - Unregister(); - should_unregister_ = false; - } else { - emit RegisterFinished(success); - } -} diff --git a/src/core/globalshortcutbackend.h b/src/core/globalshortcutbackend.h index 3dd88dc52..5666dca17 100644 --- a/src/core/globalshortcutbackend.h +++ b/src/core/globalshortcutbackend.h @@ -31,26 +31,18 @@ public: bool is_active() const { return active_; } - void Register(); + bool Register(); void Unregister(); signals: void RegisterFinished(bool success); protected: - virtual bool RegisterInNewThread() const { return false; } virtual bool DoRegister() = 0; virtual void DoUnregister() = 0; GlobalShortcuts* manager_; bool active_; - -private slots: - void RegisterFinishedSlot(); - -private: - bool register_in_progress_; - bool should_unregister_; }; #endif // GLOBALSHORTCUTBACKEND_H diff --git a/src/core/globalshortcuts.cpp b/src/core/globalshortcuts.cpp index 04ad6a774..f971d3c38 100644 --- a/src/core/globalshortcuts.cpp +++ b/src/core/globalshortcuts.cpp @@ -75,9 +75,6 @@ GlobalShortcuts::GlobalShortcuts(QObject *parent) system_backend_ = new MacGlobalShortcutBackend(this); #endif - connect(gnome_backend_, SIGNAL(RegisterFinished(bool)), SLOT(RegisterFinished(bool))); - connect(system_backend_, SIGNAL(RegisterFinished(bool)), SLOT(RegisterFinished(bool))); - ReloadSettings(); } @@ -136,18 +133,9 @@ void GlobalShortcuts::Unregister() { } void GlobalShortcuts::Register() { - if (use_gnome_) - gnome_backend_->Register(); - else - system_backend_->Register(); -} - -void GlobalShortcuts::RegisterFinished(bool success) { - GlobalShortcutBackend* backend = qobject_cast(sender()); - - if (backend == gnome_backend_ && !success) { - system_backend_->Register(); - } + if (use_gnome_ && gnome_backend_->Register()) + return; + system_backend_->Register(); } bool GlobalShortcuts::IsMacAccessibilityEnabled() const { diff --git a/src/core/globalshortcuts.h b/src/core/globalshortcuts.h index bb53f280d..41bc0d490 100644 --- a/src/core/globalshortcuts.h +++ b/src/core/globalshortcuts.h @@ -77,9 +77,6 @@ private: int rating, const QKeySequence& default_key = QKeySequence(0)); Shortcut AddShortcut(const QString& id, const QString& name, const QKeySequence& default_key); -private slots: - void RegisterFinished(bool success); - private: GlobalShortcutBackend* gnome_backend_; GlobalShortcutBackend* system_backend_; diff --git a/src/core/gnomeglobalshortcutbackend.cpp b/src/core/gnomeglobalshortcutbackend.cpp index 7496cfc22..df64bca19 100644 --- a/src/core/gnomeglobalshortcutbackend.cpp +++ b/src/core/gnomeglobalshortcutbackend.cpp @@ -17,6 +17,7 @@ #include "gnomeglobalshortcutbackend.h" #include "globalshortcuts.h" +#include "dbus/gnomesettingsdaemon.h" #include #include @@ -45,10 +46,8 @@ bool GnomeGlobalShortcutBackend::DoRegister() { } if (!interface_) { - interface_ = new QDBusInterface( - kGsdService, kGsdPath, kGsdInterface, QDBusConnection::sessionBus()); - interface_->moveToThread(thread()); - interface_->setParent(this); + interface_ = new OrgGnomeSettingsDaemonMediaKeysInterface( + kGsdService, kGsdPath, QDBusConnection::sessionBus(), this); } connect(interface_, SIGNAL(MediaPlayerKeyPressed(QString,QString)), diff --git a/src/core/gnomeglobalshortcutbackend.h b/src/core/gnomeglobalshortcutbackend.h index c9ca93b41..8b7e33153 100644 --- a/src/core/gnomeglobalshortcutbackend.h +++ b/src/core/gnomeglobalshortcutbackend.h @@ -20,7 +20,7 @@ #include "globalshortcutbackend.h" -class QDBusInterface; +class OrgGnomeSettingsDaemonMediaKeysInterface; class GnomeGlobalShortcutBackend : public GlobalShortcutBackend { Q_OBJECT @@ -41,7 +41,7 @@ private slots: void GnomeMediaKeyPressed(const QString& application, const QString& key); private: - QDBusInterface* interface_; + OrgGnomeSettingsDaemonMediaKeysInterface* interface_; }; #endif // GNOMEGLOBALSHORTCUTBACKEND_H diff --git a/src/core/mpris.cpp b/src/core/mpris.cpp index ae169fbc2..4511aea68 100644 --- a/src/core/mpris.cpp +++ b/src/core/mpris.cpp @@ -27,41 +27,10 @@ namespace mpris { Mpris::Mpris(Player* player, ArtLoader* art_loader, QObject* parent) : QObject(parent), - player_(player), - art_loader_(art_loader), - mpris1_(NULL), - mpris2_(NULL) + mpris1_(new mpris::Mpris1(player, art_loader, this)), + mpris2_(new mpris::Mpris2(player, art_loader, mpris1_, this)) { - qDebug() << __PRETTY_FUNCTION__; - - QFuture future = QtConcurrent::run(this, &Mpris::Init); - - QFutureWatcher* watcher = new QFutureWatcher(this); - watcher->setFuture(future); - - connect(watcher, SIGNAL(finished()), SLOT(Initialised())); -} - -void Mpris::Init() { - qDebug() << __PRETTY_FUNCTION__ << "- starting"; - qDebug() << __PRETTY_FUNCTION__ << "- registering MPRIS1"; - mpris1_ = new mpris::Mpris1(player_, art_loader_); - qDebug() << __PRETTY_FUNCTION__ << "- registering MPRIS2"; - mpris2_ = new mpris::Mpris2(player_, art_loader_, mpris1_); - - mpris1_->moveToThread(thread()); - mpris2_->moveToThread(thread()); - - mpris1_->setParent(this); - mpris2_->setParent(this); - connect(mpris2_, SIGNAL(RaiseMainWindow()), SIGNAL(RaiseMainWindow())); - - qDebug() << __PRETTY_FUNCTION__ << "- complete"; -} - -void Mpris::Initialised() { - qDebug() << __PRETTY_FUNCTION__; mpris2_->InitLibIndicate(); } diff --git a/src/core/mpris.h b/src/core/mpris.h index a33091fe8..153a2e606 100644 --- a/src/core/mpris.h +++ b/src/core/mpris.h @@ -37,16 +37,7 @@ public: signals: void RaiseMainWindow(); -private slots: - void Initialised(); - private: - void Init(); - -private: - Player* player_; - ArtLoader* art_loader_; - Mpris1* mpris1_; Mpris2* mpris2_; }; diff --git a/src/dbus/org.gnome.SettingsDaemon.MediaKeys.xml b/src/dbus/org.gnome.SettingsDaemon.MediaKeys.xml new file mode 100644 index 000000000..ba9b084c6 --- /dev/null +++ b/src/dbus/org.gnome.SettingsDaemon.MediaKeys.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + +" diff --git a/src/main.cpp b/src/main.cpp index 628b4b73f..45ef46c4f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -313,9 +313,6 @@ int main(int argc, char *argv[]) { qDBusRegisterMetaType(); qDBusRegisterMetaType >(); - // Create the session bus here so it's sure to live in the main thread. - QDBusConnection::sessionBus(); - mpris::ArtLoader art_loader; mpris::Mpris mpris(&player, &art_loader); @@ -325,10 +322,6 @@ int main(int argc, char *argv[]) { #endif #ifdef HAVE_REMOTE - #ifdef HAVE_DBUS - // Create the system bus here so it's sure to live in the main thread. - QDBusConnection::systemBus(); - #endif Zeroconf* zeroconf = Zeroconf::GetZeroconf(); if (zeroconf) { HttpServer* server = new HttpServer(&player); diff --git a/src/remote/avahi.cpp b/src/remote/avahi.cpp index fd47e2cfe..d86c2e8d5 100644 --- a/src/remote/avahi.cpp +++ b/src/remote/avahi.cpp @@ -2,47 +2,94 @@ #include #include -#include #include #include "dbus/avahientrygroup.h" #include "dbus/avahiserver.h" -void Avahi::Publish( - const QString& domain, const QString& type, const QString& name, quint16 port) { - QtConcurrent::run(Avahi::SyncPublish, domain, type, name, port); +Avahi::Avahi() + : server_(NULL), + entry_group_(NULL) +{ } -void Avahi::SyncPublish(const QString& domain, const QString& type, const QString& name, quint16 port) { - OrgFreedesktopAvahiServerInterface server_interface( +void Avahi::Publish(const QString& domain, + const QString& type, + const QString& name, + quint16 port) { + if (server_) { + // Already published + return; + } + + domain_ = domain; + type_ = type; + name_ = name; + port_ = port; + + server_ = new OrgFreedesktopAvahiServerInterface( "org.freedesktop.Avahi", "/", - QDBusConnection::systemBus()); + QDBusConnection::systemBus(), + this); - QDBusPendingReply reply = server_interface.EntryGroupNew(); - reply.waitForFinished(); + QDBusPendingReply reply = server_->EntryGroupNew(); + QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(reply); + connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + SLOT(EntryGroupNewFinished(QDBusPendingCallWatcher*))); +} - OrgFreedesktopAvahiEntryGroupInterface entry_group_interface( +void Avahi::EntryGroupNewFinished(QDBusPendingCallWatcher* call) { + call->deleteLater(); + QDBusPendingReply reply = *call; + + if (reply.isError()) { + qWarning() << "Failed to create new Avahi entry group:" << call->error(); + return; + } + + entry_group_ = new OrgFreedesktopAvahiEntryGroupInterface( "org.freedesktop.Avahi", reply.value().path(), - QDBusConnection::systemBus()); + QDBusConnection::systemBus(), + this); - QDBusPendingReply<> add_reply = entry_group_interface.AddService( + QDBusPendingReply<> add_reply = entry_group_->AddService( -1, // Interface (Unspecified, ie. all interfaces) -1, // Protocol (Unspecified, ie. IPv4 & IPv6) 0, // Flags - name, // Service name - type, // Service type - domain, // Domain, ie. local + name_, // Service name + type_, // Service type + domain_, // Domain, ie. local QString::null, // Hostname (Avahi fills it if it's null) - port, // Port + port_, // Port QList()); // TXT record - add_reply.waitForFinished(); + QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(add_reply); + connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + SLOT(AddServiceFinished(QDBusPendingCallWatcher*))); +} - QDBusPendingReply<> commit_reply = entry_group_interface.Commit(); - commit_reply.waitForFinished(); - if (commit_reply.isValid()) { +void Avahi::AddServiceFinished(QDBusPendingCallWatcher* call) { + call->deleteLater(); + + if (call->isError()) { + qWarning() << "Failed to add Avahi service:" << call->error(); + return; + } + + QDBusPendingReply<> commit_reply = entry_group_->Commit(); + QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(commit_reply); + connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + SLOT(CommitFinished(QDBusPendingCallWatcher*))); +} + +void Avahi::CommitFinished(QDBusPendingCallWatcher* call) { + call->deleteLater(); + + if (call->isError()) { qDebug() << "Remote interface published on Avahi"; + } else { + qWarning() << "Failed to commit Avahi changes:" << call->error(); } } diff --git a/src/remote/avahi.h b/src/remote/avahi.h index ac31e2814..1496a98c2 100644 --- a/src/remote/avahi.h +++ b/src/remote/avahi.h @@ -3,13 +3,37 @@ #include "zeroconf.h" -class Avahi : public Zeroconf { - public: - virtual void Publish( - const QString& domain, const QString& type, const QString& name, quint16 port); +#include - private: - static void SyncPublish(const QString& domain, const QString& type, const QString& name, quint16 port); +class OrgFreedesktopAvahiEntryGroupInterface; +class OrgFreedesktopAvahiServerInterface; + +class QDBusPendingCallWatcher; + +class Avahi : public QObject, public Zeroconf { + Q_OBJECT + +public: + Avahi(); + + virtual void Publish(const QString& domain, + const QString& type, + const QString& name, + quint16 port); + +private slots: + void EntryGroupNewFinished(QDBusPendingCallWatcher* call); + void AddServiceFinished(QDBusPendingCallWatcher* call); + void CommitFinished(QDBusPendingCallWatcher* call); + +private: + OrgFreedesktopAvahiServerInterface* server_; + OrgFreedesktopAvahiEntryGroupInterface* entry_group_; + + QString domain_; + QString type_; + QString name_; + quint16 port_; }; #endif diff --git a/src/remote/zeroconf.cpp b/src/remote/zeroconf.cpp index cab2c00d9..d83c1475d 100644 --- a/src/remote/zeroconf.cpp +++ b/src/remote/zeroconf.cpp @@ -14,13 +14,11 @@ Zeroconf* Zeroconf::instance_ = NULL; Zeroconf* Zeroconf::GetZeroconf() { if (!instance_) { - #ifdef Q_OS_DARWIN - return new Bonjour(); - #endif - - #ifdef HAVE_DBUS - return new Avahi(); - #endif + #if defined(Q_OS_DARWIN) + instance_ = new Bonjour(); + #elif defined(HAVE_DBUS) + instance_ = new Avahi(); + #endif } return instance_; diff --git a/src/remote/zeroconf.h b/src/remote/zeroconf.h index c60c16109..94e565565 100644 --- a/src/remote/zeroconf.h +++ b/src/remote/zeroconf.h @@ -4,13 +4,17 @@ #include class Zeroconf { - public: - virtual void Publish( - const QString& domain, const QString& type, const QString& name, quint16 port) = 0; +public: + virtual ~Zeroconf() {} + + virtual void Publish(const QString& domain, + const QString& type, + const QString& name, + quint16 port) = 0; static Zeroconf* GetZeroconf(); - private: +private: static Zeroconf* instance_; };