Do gnome global shortcut registration in a background thread

This commit is contained in:
David Sansome 2011-01-09 23:11:51 +00:00
parent 2d53db13c3
commit 380fa71e86
7 changed files with 91 additions and 20 deletions

View File

@ -247,6 +247,7 @@ set(HEADERS
core/database.h
core/deletefiles.h
core/globalshortcuts.h
core/globalshortcutbackend.h
core/gnomeglobalshortcutbackend.h
core/kittenloader.h
core/mergedproxymodel.h

View File

@ -18,26 +18,63 @@
#include "globalshortcutbackend.h"
#include "globalshortcuts.h"
#include <QFuture>
#include <QFutureWatcher>
#include <QtConcurrentRun>
GlobalShortcutBackend::GlobalShortcutBackend(GlobalShortcuts *parent)
: QObject(parent),
manager_(parent),
active_(false)
active_(false),
register_in_progress_(false),
should_unregister_(false)
{
}
bool GlobalShortcutBackend::Register() {
bool ret = DoRegister();
if (ret)
active_ = true;
return ret;
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);
}
}
void GlobalShortcutBackend::Unregister() {
if (register_in_progress_) {
should_unregister_ = true;
return;
}
DoUnregister();
active_ = false;
}
void GlobalShortcutBackend::Reregister() {
Unregister();
Register();
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);
}
}

View File

@ -23,22 +23,34 @@
class GlobalShortcuts;
class GlobalShortcutBackend : public QObject {
Q_OBJECT
public:
GlobalShortcutBackend(GlobalShortcuts* parent = 0);
virtual ~GlobalShortcutBackend() {}
bool is_active() const { return active_; }
bool Register();
void Register();
void Unregister();
void Reregister();
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

View File

@ -67,8 +67,7 @@ GlobalShortcuts::GlobalShortcuts(QObject *parent)
connect(rating_signals_mapper_, SIGNAL(mapped(int)), SIGNAL(RateCurrentSong(int)));
// Create backends - these do the actual shortcut registration
if (IsGsdAvailable())
gnome_backend_ = new GnomeGlobalShortcutBackend(this);
gnome_backend_ = new GnomeGlobalShortcutBackend(this);
#ifndef Q_OS_DARWIN
system_backend_ = new QxtGlobalShortcutBackend(this);
@ -76,6 +75,9 @@ 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();
}
@ -127,19 +129,27 @@ void GlobalShortcuts::ReloadSettings() {
}
void GlobalShortcuts::Unregister() {
if (gnome_backend_ && gnome_backend_->is_active())
if (gnome_backend_->is_active())
gnome_backend_->Unregister();
if (system_backend_ && system_backend_->is_active())
if (system_backend_->is_active())
system_backend_->Unregister();
}
void GlobalShortcuts::Register() {
if (gnome_backend_ && use_gnome_)
if (use_gnome_)
gnome_backend_->Register();
else if (system_backend_)
else
system_backend_->Register();
}
void GlobalShortcuts::RegisterFinished(bool success) {
GlobalShortcutBackend* backend = qobject_cast<GlobalShortcutBackend*>(sender());
if (backend == gnome_backend_ && !success) {
system_backend_->Register();
}
}
bool GlobalShortcuts::IsMacAccessibilityEnabled() const {
#ifdef Q_OS_MAC
return static_cast<MacGlobalShortcutBackend*>(system_backend_)->IsAccessibilityEnabled();

View File

@ -77,6 +77,9 @@ 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_;

View File

@ -36,22 +36,29 @@ GnomeGlobalShortcutBackend::GnomeGlobalShortcutBackend(GlobalShortcuts* parent)
}
bool GnomeGlobalShortcutBackend::DoRegister() {
qDebug() << __PRETTY_FUNCTION__;
#ifdef QT_DBUS_LIB
qDebug() << __PRETTY_FUNCTION__ << "- starting";
// Check if the GSD service is available
if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(kGsdService))
if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(kGsdService)) {
qDebug() << __PRETTY_FUNCTION__ << "- gnome settings daemon not registered";
return false;
}
if (!interface_) {
interface_ = new QDBusInterface(
kGsdService, kGsdPath, kGsdInterface, QDBusConnection::sessionBus(), this);
kGsdService, kGsdPath, kGsdInterface, QDBusConnection::sessionBus());
interface_->moveToThread(thread());
interface_->setParent(this);
}
connect(interface_, SIGNAL(MediaPlayerKeyPressed(QString,QString)),
this, SLOT(GnomeMediaKeyPressed(QString,QString)));
qDebug() << __PRETTY_FUNCTION__ << "- complete";
return true;
#else // QT_DBUS_LIB
qDebug() << __PRETTY_FUNCTION__ << "- dbus not available";
return false;
#endif
}

View File

@ -33,6 +33,7 @@ public:
static const char* kGsdInterface;
protected:
bool RegisterInNewThread() const { return true; }
bool DoRegister();
void DoUnregister();