Move everything DBus related back to the main thread and use synchronous method calls everywhere
This commit is contained in:
parent
7880026767
commit
2ecf61a57e
@ -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)
|
||||
|
||||
|
@ -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<bool> future = QtConcurrent::run(this, &GlobalShortcutBackend::DoRegister);
|
||||
|
||||
QFutureWatcher<bool>* watcher = new QFutureWatcher<bool>(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<bool>* watcher = dynamic_cast<QFutureWatcher<bool>*>(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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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<GlobalShortcutBackend*>(sender());
|
||||
|
||||
if (backend == gnome_backend_ && !success) {
|
||||
system_backend_->Register();
|
||||
}
|
||||
if (use_gnome_ && gnome_backend_->Register())
|
||||
return;
|
||||
system_backend_->Register();
|
||||
}
|
||||
|
||||
bool GlobalShortcuts::IsMacAccessibilityEnabled() const {
|
||||
|
@ -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_;
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "gnomeglobalshortcutbackend.h"
|
||||
#include "globalshortcuts.h"
|
||||
#include "dbus/gnomesettingsdaemon.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QtDebug>
|
||||
@ -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)),
|
||||
|
@ -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
|
||||
|
@ -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<void> future = QtConcurrent::run(this, &Mpris::Init);
|
||||
|
||||
QFutureWatcher<void>* watcher = new QFutureWatcher<void>(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();
|
||||
}
|
||||
|
||||
|
@ -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_;
|
||||
};
|
||||
|
18
src/dbus/org.gnome.SettingsDaemon.MediaKeys.xml
Normal file
18
src/dbus/org.gnome.SettingsDaemon.MediaKeys.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<!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.gnome.SettingsDaemon.MediaKeys">
|
||||
<method name="ReleaseMediaPlayerKeys">
|
||||
<arg name="application" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="GrabMediaPlayerKeys">
|
||||
<arg name="application" type="s" direction="in"/>
|
||||
<arg name="time" type="u" direction="in"/>
|
||||
</method>
|
||||
<signal name="MediaPlayerKeyPressed">
|
||||
<arg type="s"/>
|
||||
<arg type="s"/>
|
||||
</signal>
|
||||
</interface>
|
||||
</node>
|
||||
"
|
@ -313,9 +313,6 @@ int main(int argc, char *argv[]) {
|
||||
qDBusRegisterMetaType<TrackIds>();
|
||||
qDBusRegisterMetaType<QList<QByteArray> >();
|
||||
|
||||
// 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);
|
||||
|
@ -2,47 +2,94 @@
|
||||
|
||||
#include <QDBusConnection>
|
||||
#include <QHostInfo>
|
||||
#include <QtConcurrentRun>
|
||||
|
||||
#include <QtDebug>
|
||||
|
||||
#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<QDBusObjectPath> reply = server_interface.EntryGroupNew();
|
||||
reply.waitForFinished();
|
||||
QDBusPendingReply<QDBusObjectPath> 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<QDBusObjectPath> 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<QByteArray>()); // 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();
|
||||
}
|
||||
}
|
||||
|
@ -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 <QObject>
|
||||
|
||||
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
|
||||
|
@ -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_;
|
||||
|
@ -4,13 +4,17 @@
|
||||
#include <QString>
|
||||
|
||||
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_;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user