Do gnome global shortcut registration in a background thread
This commit is contained in:
parent
2d53db13c3
commit
380fa71e86
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ public:
|
|||
static const char* kGsdInterface;
|
||||
|
||||
protected:
|
||||
bool RegisterInNewThread() const { return true; }
|
||||
bool DoRegister();
|
||||
void DoUnregister();
|
||||
|
||||
|
|
Loading…
Reference in New Issue