parent
e8492940a5
commit
c258e5a3af
|
@ -559,8 +559,8 @@ if(HAVE_GLOBALSHORTCUTS)
|
|||
SOURCES globalshortcuts/globalshortcut-x11.cpp
|
||||
)
|
||||
optional_source(HAVE_DBUS
|
||||
SOURCES globalshortcuts/globalshortcutbackend-gsd.cpp
|
||||
HEADERS globalshortcuts/globalshortcutbackend-gsd.h
|
||||
SOURCES globalshortcuts/globalshortcutbackend-gsd.cpp globalshortcuts/globalshortcutbackend-kde.cpp
|
||||
HEADERS globalshortcuts/globalshortcutbackend-gsd.h globalshortcuts/globalshortcutbackend-kde.h
|
||||
)
|
||||
optional_source(WIN32
|
||||
SOURCES globalshortcuts/globalshortcut-win.cpp
|
||||
|
@ -634,6 +634,14 @@ if(UNIX AND HAVE_DBUS)
|
|||
dbus/org.gnome.SettingsDaemon.MediaKeys.xml
|
||||
dbus/gnomesettingsdaemon)
|
||||
|
||||
# org.kde.KGlobalAccel interface
|
||||
qt6_add_dbus_interface(SOURCES
|
||||
dbus/org.kde.KGlobalAccel.xml
|
||||
dbus/kglobalaccel)
|
||||
qt6_add_dbus_interface(SOURCES
|
||||
dbus/org.kde.KGlobalAccel.Component.xml
|
||||
dbus/kglobalaccelcomponent)
|
||||
|
||||
else()
|
||||
|
||||
# MPRIS 2.0 DBUS interfaces
|
||||
|
@ -662,6 +670,14 @@ if(UNIX AND HAVE_DBUS)
|
|||
dbus/org.gnome.SettingsDaemon.MediaKeys.xml
|
||||
dbus/gnomesettingsdaemon)
|
||||
|
||||
# org.kde.KGlobalAccel interface
|
||||
qt5_add_dbus_interface(SOURCES
|
||||
dbus/org.kde.KGlobalAccel.xml
|
||||
dbus/kglobalaccel)
|
||||
qt5_add_dbus_interface(SOURCES
|
||||
dbus/org.kde.KGlobalAccel.Component.xml
|
||||
dbus/kglobalaccelcomponent)
|
||||
|
||||
endif()
|
||||
|
||||
# org.freedesktop.Avahi.Server interface
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
<!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.kde.kglobalaccel.Component">
|
||||
<property name="friendlyName" type="s" access="read"/>
|
||||
<property name="uniqueName" type="s" access="read"/>
|
||||
<signal name="globalShortcutPressed">
|
||||
<arg name="componentUnique" type="s" direction="out"/>
|
||||
<arg name="actionUnique" type="s" direction="out"/>
|
||||
<arg name="timestamp" type="x" direction="out"/>
|
||||
</signal>
|
||||
<method name="cleanUp">
|
||||
<arg type="b" direction="out"/>
|
||||
</method>
|
||||
<method name="isActive">
|
||||
<arg type="b" direction="out"/>
|
||||
</method>
|
||||
<method name="shortcutNames">
|
||||
<arg type="as" direction="out"/>
|
||||
<arg name="context" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="shortcutNames">
|
||||
<arg type="as" direction="out"/>
|
||||
</method>
|
||||
<method name="getShortcutContexts">
|
||||
<arg type="as" direction="out"/>
|
||||
</method>
|
||||
<method name="invokeShortcut">
|
||||
<arg name="actionName" type="s" direction="in"/>
|
||||
</method>
|
||||
</interface>
|
||||
</node>
|
|
@ -0,0 +1,71 @@
|
|||
<!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.kde.KGlobalAccel">
|
||||
<signal name="yourShortcutGotChanged">
|
||||
<arg name="actionId" type="as" direction="out"/>
|
||||
<arg name="newKeys" type="ai" direction="out"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.Out1" value="QList<int>"/>
|
||||
</signal>
|
||||
<method name="allComponents">
|
||||
<arg type="ao" direction="out"/>
|
||||
</method>
|
||||
<method name="allMainComponents">
|
||||
<arg type="aas" direction="out"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QList<QStringList>"/>
|
||||
</method>
|
||||
<method name="allActionsForComponent">
|
||||
<arg type="aas" direction="out"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QList<QStringList>"/>
|
||||
<arg name="actionId" type="as" direction="in"/>
|
||||
</method>
|
||||
<method name="action">
|
||||
<arg type="as" direction="out"/>
|
||||
<arg name="key" type="i" direction="in"/>
|
||||
</method>
|
||||
<method name="getComponent">
|
||||
<arg type="o" direction="out"/>
|
||||
<arg name="componentUnique" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="shortcut">
|
||||
<arg type="ai" direction="out"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QList<int>"/>
|
||||
<arg name="actionId" type="as" direction="in"/>
|
||||
</method>
|
||||
<method name="defaultShortcut">
|
||||
<arg type="ai" direction="out"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QList<int>"/>
|
||||
<arg name="actionId" type="as" direction="in"/>
|
||||
</method>
|
||||
<method name="setShortcut">
|
||||
<arg type="ai" direction="out"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QList<int>"/>
|
||||
<arg name="actionId" type="as" direction="in"/>
|
||||
<arg name="keys" type="ai" direction="in"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="QList<int>"/>
|
||||
<arg name="flags" type="u" direction="in"/>
|
||||
</method>
|
||||
<method name="setForeignShortcut">
|
||||
<arg name="actionId" type="as" direction="in"/>
|
||||
<arg name="keys" type="ai" direction="in"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="QList<int>"/>
|
||||
</method>
|
||||
<method name="setInactive">
|
||||
<arg name="actionId" type="as" direction="in"/>
|
||||
</method>
|
||||
<method name="doRegister">
|
||||
<arg name="actionId" type="as" direction="in"/>
|
||||
</method>
|
||||
<method name="unRegister">
|
||||
<arg name="actionId" type="as" direction="in"/>
|
||||
</method>
|
||||
<method name="activateGlobalShortcutContext">
|
||||
<arg name="component" type="s" direction="in"/>
|
||||
<arg name="context" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="isGlobalShortcutAvailable">
|
||||
<arg type="b" direction="out"/>
|
||||
<arg name="key" type="i" direction="in"/>
|
||||
<arg name="component" type="s" direction="in"/>
|
||||
</method>
|
||||
</interface>
|
||||
</node>
|
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2020, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <dbus/kglobalaccel.h>
|
||||
#include <dbus/kglobalaccelcomponent.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QAction>
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusReply>
|
||||
#include <QDBusObjectPath>
|
||||
#include <QDBusPendingCallWatcher>
|
||||
#include <QKeySequence>
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
# include <QKeyCombination>
|
||||
#endif
|
||||
|
||||
#include "core/logging.h"
|
||||
#include "core/closure.h"
|
||||
|
||||
#include "globalshortcutbackend-kde.h"
|
||||
|
||||
const char *GlobalShortcutBackendKDE::kKdeService = "org.kde.kglobalaccel";
|
||||
const char *GlobalShortcutBackendKDE::kKdePath = "/kglobalaccel";
|
||||
|
||||
GlobalShortcutBackendKDE::GlobalShortcutBackendKDE(GlobalShortcuts *parent) : GlobalShortcutBackend(parent), interface_(nullptr), component_(nullptr) {}
|
||||
|
||||
bool GlobalShortcutBackendKDE::DoRegister() {
|
||||
|
||||
qLog(Debug) << "Registering";
|
||||
|
||||
if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(kKdeService)) {
|
||||
qLog(Warning) << "KGlobalAccel is not registered";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!interface_) {
|
||||
interface_ = new OrgKdeKGlobalAccelInterface(kKdeService, kKdePath, QDBusConnection::sessionBus(), this);
|
||||
}
|
||||
|
||||
for (const GlobalShortcuts::Shortcut &shortcut : manager_->shortcuts().values()) {
|
||||
RegisterShortcut(shortcut);
|
||||
}
|
||||
|
||||
QDBusPendingReply<QDBusObjectPath> reply = interface_->getComponent(QCoreApplication::applicationName());
|
||||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
|
||||
NewClosure(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(RegisterFinished(QDBusPendingCallWatcher*)), watcher);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
void GlobalShortcutBackendKDE::RegisterFinished(QDBusPendingCallWatcher *watcher) {
|
||||
|
||||
QDBusReply<QDBusObjectPath> reply = watcher->reply();
|
||||
watcher->deleteLater();
|
||||
|
||||
if (!reply.isValid()) {
|
||||
qLog(Error) << "Failed to register:" << reply.error().name() << reply.error().message();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!component_) {
|
||||
component_ = new org::kde::kglobalaccel::Component(kKdeService, reply.value().path(), QDBusConnection::sessionBus(), interface_);
|
||||
}
|
||||
|
||||
if (!component_->isValid()) {
|
||||
qLog(Error) << "Component is invalid:" << QDBusConnection::sessionBus().lastError();
|
||||
return;
|
||||
}
|
||||
|
||||
connect(component_, SIGNAL(globalShortcutPressed(QString, QString, qlonglong)), this, SLOT(GlobalShortcutPressed(QString, QString, qlonglong)), Qt::UniqueConnection);
|
||||
|
||||
qLog(Debug) << "Registered";
|
||||
|
||||
}
|
||||
|
||||
void GlobalShortcutBackendKDE::DoUnregister() {
|
||||
|
||||
if (!interface_ || !interface_->isValid()) return;
|
||||
|
||||
qLog(Debug) << "Unregistering";
|
||||
|
||||
for (const GlobalShortcuts::Shortcut &shortcut : manager_->shortcuts()) {
|
||||
if (actions_.contains(shortcut.id)) {
|
||||
interface_->unRegister(GetActionId(shortcut.id, shortcut.action));
|
||||
actions_.remove(shortcut.id, shortcut.action);
|
||||
qLog(Info) << "Unregistered shortcut" << shortcut.id << shortcut.action->shortcut();
|
||||
}
|
||||
}
|
||||
|
||||
disconnect(component_, nullptr, this, nullptr);
|
||||
|
||||
qLog(Debug) << "Unregistered";
|
||||
|
||||
}
|
||||
|
||||
bool GlobalShortcutBackendKDE::RegisterShortcut(const GlobalShortcuts::Shortcut &shortcut) {
|
||||
|
||||
if (!interface_ || !interface_->isValid() || shortcut.id.isEmpty() || !shortcut.action || shortcut.action->shortcut().isEmpty()) return false;
|
||||
|
||||
if (shortcut.action->shortcut() == QKeySequence(Qt::Key_MediaPlay) ||
|
||||
shortcut.action->shortcut() == QKeySequence(Qt::Key_MediaStop) ||
|
||||
shortcut.action->shortcut() == QKeySequence(Qt::Key_MediaNext) ||
|
||||
shortcut.action->shortcut() == QKeySequence(Qt::Key_MediaPrevious)) {
|
||||
qLog(Info) << "Media shortcut" << shortcut.id << shortcut.action->shortcut();
|
||||
return true;
|
||||
}
|
||||
|
||||
QStringList action_id = GetActionId(shortcut.id, shortcut.action);
|
||||
actions_.insert(shortcut.id, shortcut.action);
|
||||
interface_->doRegister(action_id);
|
||||
|
||||
QList<QKeySequence> active_shortcut = QList<QKeySequence>() << shortcut.action->shortcut();
|
||||
|
||||
const QList<int> result = interface_->setShortcut(action_id, ToIntList(active_shortcut), 0x2);
|
||||
const QList<QKeySequence> result_sequence = ToKeySequenceList(result);
|
||||
if (result_sequence != active_shortcut) {
|
||||
if (result_sequence.isEmpty()) {
|
||||
shortcut.action->setShortcut(QKeySequence());
|
||||
}
|
||||
else {
|
||||
shortcut.action->setShortcut(result_sequence[0]);
|
||||
}
|
||||
}
|
||||
|
||||
qLog(Info) << "Registered shortcut" << shortcut.id << shortcut.action->shortcut();
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
QStringList GlobalShortcutBackendKDE::GetActionId(const QString &id, const QAction *action) {
|
||||
|
||||
QStringList ret;
|
||||
ret << QCoreApplication::applicationName();
|
||||
ret << id;
|
||||
ret << QCoreApplication::applicationName();
|
||||
ret << action->text().remove('&');
|
||||
if (ret.back().isEmpty()) ret.back() = id;
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
QList<int> GlobalShortcutBackendKDE::ToIntList(const QList<QKeySequence> &sequence_list) {
|
||||
|
||||
QList<int> ret;
|
||||
for (const QKeySequence &sequence : sequence_list) {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
ret.append(sequence[0].toCombined());
|
||||
#else
|
||||
ret.append(sequence[0]);
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
QList<QKeySequence> GlobalShortcutBackendKDE::ToKeySequenceList(const QList<int> &sequence_list) {
|
||||
|
||||
QList<QKeySequence> ret;
|
||||
for (int sequence : sequence_list) {
|
||||
ret.append(sequence);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
void GlobalShortcutBackendKDE::GlobalShortcutPressed(const QString &component_unique, const QString &shortcut_unique, qlonglong) {
|
||||
|
||||
if (QCoreApplication::applicationName() == component_unique && actions_.contains(shortcut_unique)) {
|
||||
for (QAction *action : actions_.values(shortcut_unique)) {
|
||||
qLog(Debug) << "Key" << action->shortcut() << "pressed.";
|
||||
if (action->isEnabled()) action->trigger();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2020, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GLOBALSHORTCUTBACKEND_KDE_H
|
||||
#define GLOBALSHORTCUTBACKEND_KDE_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QMultiHash>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QKeySequence>
|
||||
|
||||
#include "globalshortcutbackend.h"
|
||||
#include "globalshortcuts.h"
|
||||
|
||||
class QDBusPendingCallWatcher;
|
||||
class QAction;
|
||||
|
||||
class OrgKdeKGlobalAccelInterface;
|
||||
class OrgKdeKglobalaccelComponentInterface;
|
||||
|
||||
class GlobalShortcutBackendKDE : public GlobalShortcutBackend {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GlobalShortcutBackendKDE(GlobalShortcuts *parent);
|
||||
|
||||
static const char *kKdeService;
|
||||
|
||||
protected:
|
||||
bool DoRegister() override;
|
||||
void DoUnregister() override;
|
||||
|
||||
private:
|
||||
bool RegisterShortcut(const GlobalShortcuts::Shortcut &shortcut);
|
||||
static QStringList GetActionId(const QString &id, const QAction *action);
|
||||
static QList<int> ToIntList(const QList<QKeySequence> &sequence_list);
|
||||
static QList<QKeySequence> ToKeySequenceList(const QList<int> &sequence_list);
|
||||
|
||||
private slots:
|
||||
void RegisterFinished(QDBusPendingCallWatcher *watcher);
|
||||
void GlobalShortcutPressed(const QString &component_unique, const QString &shortcut_unique, qlonglong);
|
||||
|
||||
private:
|
||||
static const char *kKdePath;
|
||||
|
||||
OrgKdeKGlobalAccelInterface *interface_;
|
||||
OrgKdeKglobalaccelComponentInterface *component_;
|
||||
QMultiHash<QString, QAction*> actions_;
|
||||
};
|
||||
|
||||
#endif // GLOBALSHORTCUTBACKEND_KDE_H
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
#ifdef HAVE_DBUS
|
||||
# include "globalshortcutbackend-gsd.h"
|
||||
# include "globalshortcutbackend-kde.h"
|
||||
#endif
|
||||
#if defined(HAVE_X11) || defined(Q_OS_WIN)
|
||||
# include "globalshortcutbackend-system.h"
|
||||
|
@ -51,9 +52,11 @@
|
|||
|
||||
GlobalShortcuts::GlobalShortcuts(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
dbus_backend_(nullptr),
|
||||
gsd_backend_(nullptr),
|
||||
kde_backend_(nullptr),
|
||||
system_backend_(nullptr),
|
||||
use_gsd_(true),
|
||||
use_kde_(true),
|
||||
use_x11_(false)
|
||||
{
|
||||
|
||||
|
@ -82,7 +85,8 @@ GlobalShortcuts::GlobalShortcuts(QWidget *parent)
|
|||
|
||||
// Create backends - these do the actual shortcut registration
|
||||
#ifdef HAVE_DBUS
|
||||
dbus_backend_ = new GlobalShortcutBackendGSD(this);
|
||||
gsd_backend_ = new GlobalShortcutBackendGSD(this);
|
||||
kde_backend_ = new GlobalShortcutBackendKDE(this);
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
|
@ -106,6 +110,7 @@ void GlobalShortcuts::ReloadSettings() {
|
|||
|
||||
// The actual shortcuts have been set in our actions for us by the config dialog already - we just need to reread the gnome settings.
|
||||
use_gsd_ = settings_.value("use_gsd", true).toBool();
|
||||
use_kde_ = settings_.value("use_kde", true).toBool();
|
||||
use_x11_ = settings_.value("use_x11", false).toBool();
|
||||
|
||||
Unregister();
|
||||
|
@ -149,6 +154,16 @@ bool GlobalShortcuts::IsGsdAvailable() const {
|
|||
|
||||
}
|
||||
|
||||
bool GlobalShortcuts::IsKdeAvailable() const {
|
||||
|
||||
#ifdef HAVE_DBUS
|
||||
return QDBusConnection::sessionBus().interface()->isServiceRegistered(GlobalShortcutBackendKDE::kKdeService);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
bool GlobalShortcuts::IsX11Available() const {
|
||||
|
||||
#ifdef HAVE_X11
|
||||
|
@ -160,7 +175,9 @@ bool GlobalShortcuts::IsX11Available() const {
|
|||
}
|
||||
|
||||
void GlobalShortcuts::Register() {
|
||||
if (use_gsd_ && dbus_backend_ && dbus_backend_->Register()) return;
|
||||
|
||||
if (use_gsd_ && gsd_backend_ && gsd_backend_->Register()) return;
|
||||
if (use_kde_ && kde_backend_ && kde_backend_->Register()) return;
|
||||
#ifdef HAVE_X11 // If this system has X11, only use the system backend if X11 is enabled in the global shortcut settings
|
||||
if (use_x11_) {
|
||||
#endif
|
||||
|
@ -169,11 +186,15 @@ void GlobalShortcuts::Register() {
|
|||
#ifdef HAVE_X11
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void GlobalShortcuts::Unregister() {
|
||||
if (dbus_backend_ && dbus_backend_->is_active()) dbus_backend_->Unregister();
|
||||
|
||||
if (gsd_backend_ && gsd_backend_->is_active()) gsd_backend_->Unregister();
|
||||
if (kde_backend_ && kde_backend_->is_active()) kde_backend_->Unregister();
|
||||
if (system_backend_ && system_backend_->is_active()) system_backend_->Unregister();
|
||||
|
||||
}
|
||||
|
||||
bool GlobalShortcuts::IsMacAccessibilityEnabled() const {
|
||||
|
|
|
@ -50,6 +50,7 @@ class GlobalShortcuts : public QWidget {
|
|||
|
||||
QMap<QString, Shortcut> shortcuts() const { return shortcuts_; }
|
||||
bool IsGsdAvailable() const;
|
||||
bool IsKdeAvailable() const;
|
||||
bool IsX11Available() const;
|
||||
bool IsMacAccessibilityEnabled() const;
|
||||
|
||||
|
@ -87,13 +88,15 @@ class GlobalShortcuts : public QWidget {
|
|||
Shortcut AddShortcut(const QString &id, const QString &name, const QKeySequence &default_key);
|
||||
|
||||
private:
|
||||
GlobalShortcutBackend *dbus_backend_;
|
||||
GlobalShortcutBackend *gsd_backend_;
|
||||
GlobalShortcutBackend *kde_backend_;
|
||||
GlobalShortcutBackend *system_backend_;
|
||||
|
||||
QMap<QString, Shortcut> shortcuts_;
|
||||
QSettings settings_;
|
||||
|
||||
bool use_gsd_;
|
||||
bool use_kde_;
|
||||
bool use_x11_;
|
||||
};
|
||||
|
||||
|
|
|
@ -73,11 +73,12 @@ GlobalShortcutsSettingsPage::GlobalShortcutsSettingsPage(SettingsDialog *dialog)
|
|||
|
||||
#if !defined(Q_OS_WIN) && !defined(Q_OS_MACOS)
|
||||
#ifdef HAVE_DBUS
|
||||
connect(ui_->checkbox_gsd, SIGNAL(clicked(bool)), SLOT(GSDChanged(bool)));
|
||||
connect(ui_->checkbox_gsd, SIGNAL(clicked(bool)), SLOT(ShortcutOptionsChanged()));
|
||||
connect(ui_->checkbox_kde, SIGNAL(clicked(bool)), SLOT(ShortcutOptionsChanged()));
|
||||
connect(ui_->button_gsd_open, SIGNAL(clicked()), SLOT(OpenGnomeKeybindingProperties()));
|
||||
#endif
|
||||
#ifdef HAVE_X11
|
||||
connect(ui_->checkbox_x11, SIGNAL(clicked(bool)), SLOT(X11Changed(bool)));
|
||||
connect(ui_->checkbox_x11, SIGNAL(clicked(bool)), SLOT(ShortcutOptionsChanged()));
|
||||
#endif
|
||||
#endif // !defined(Q_OS_WIN) && !defined(Q_OS_MACOS)
|
||||
|
||||
|
@ -114,14 +115,23 @@ void GlobalShortcutsSettingsPage::Load() {
|
|||
connect(ui_->button_macos_open, SIGNAL(clicked()), manager, SLOT(ShowMacAccessibilityDialog()));
|
||||
|
||||
if (manager->IsGsdAvailable()) {
|
||||
qLog(Debug) << "Gnome (GSD) D-Bus backend is available.";
|
||||
qLog(Debug) << "Gnome (GSD) backend is available.";
|
||||
ui_->widget_gsd->show();
|
||||
}
|
||||
else {
|
||||
qLog(Debug) << "Gnome (GSD) D-Bus backend is unavailable.";
|
||||
qLog(Debug) << "Gnome (GSD) backend is unavailable.";
|
||||
ui_->widget_gsd->hide();
|
||||
}
|
||||
|
||||
if (manager->IsKdeAvailable()) {
|
||||
qLog(Debug) << "KDE (KGlobalAccel) backend is available.";
|
||||
ui_->widget_kde->show();
|
||||
}
|
||||
else {
|
||||
qLog(Debug) << "KDE (KGlobalAccel) backend is unavailable.";
|
||||
ui_->widget_kde->hide();
|
||||
}
|
||||
|
||||
if (manager->IsX11Available()) {
|
||||
qLog(Debug) << "X11 backend is available.";
|
||||
ui_->widget_x11->show();
|
||||
|
@ -129,7 +139,6 @@ void GlobalShortcutsSettingsPage::Load() {
|
|||
else {
|
||||
qLog(Debug) << "X11 backend is unavailable.";
|
||||
ui_->widget_x11->hide();
|
||||
s.setValue("use_x11", false);
|
||||
}
|
||||
|
||||
for (const GlobalShortcuts::Shortcut &i : manager->shortcuts().values()) {
|
||||
|
@ -149,24 +158,19 @@ void GlobalShortcutsSettingsPage::Load() {
|
|||
SetShortcut(shortcut.s.id, shortcut.s.action->shortcut());
|
||||
}
|
||||
|
||||
bool use_gsd = s.value("use_gsd", true).toBool();
|
||||
if (ui_->widget_gsd->isVisibleTo(this)) {
|
||||
ui_->checkbox_gsd->setChecked(use_gsd);
|
||||
ui_->checkbox_gsd->setChecked(s.value("use_gsd", true).toBool());
|
||||
}
|
||||
|
||||
if (ui_->widget_kde->isVisibleTo(this)) {
|
||||
ui_->checkbox_kde->setChecked(s.value("use_kde", true).toBool());
|
||||
}
|
||||
|
||||
bool use_x11 = s.value("use_x11", false).toBool();
|
||||
if (ui_->widget_x11->isVisibleTo(this)) {
|
||||
ui_->checkbox_x11->setChecked(use_x11);
|
||||
ui_->checkbox_x11->setChecked(s.value("use_x11", false).toBool());
|
||||
}
|
||||
|
||||
#if !defined(Q_OS_WIN) && !defined(Q_OS_MACOS)
|
||||
#ifdef HAVE_DBUS
|
||||
GSDChanged(true);
|
||||
#endif
|
||||
#ifdef HAVE_X11
|
||||
X11Changed(true);
|
||||
#endif
|
||||
#endif
|
||||
ShortcutOptionsChanged();
|
||||
|
||||
ui_->widget_macos->setVisible(!manager->IsMacAccessibilityEnabled());
|
||||
#ifdef Q_OS_MACOS
|
||||
|
@ -195,6 +199,7 @@ void GlobalShortcutsSettingsPage::Save() {
|
|||
}
|
||||
|
||||
s.setValue("use_gsd", ui_->checkbox_gsd->isChecked());
|
||||
s.setValue("use_kde", ui_->checkbox_kde->isChecked());
|
||||
s.setValue("use_x11", ui_->checkbox_x11->isChecked());
|
||||
|
||||
s.endGroup();
|
||||
|
@ -203,50 +208,24 @@ void GlobalShortcutsSettingsPage::Save() {
|
|||
|
||||
}
|
||||
|
||||
void GlobalShortcutsSettingsPage::X11Changed(bool) {
|
||||
void GlobalShortcutsSettingsPage::ShortcutOptionsChanged() {
|
||||
|
||||
if (!ui_->widget_x11->isVisibleTo(this)) return;
|
||||
bool configure_shortcuts = (ui_->widget_kde->isVisibleTo(this) && ui_->checkbox_kde->isChecked()) ||
|
||||
(ui_->widget_x11->isVisibleTo(this) && ui_->checkbox_x11->isChecked());
|
||||
|
||||
if (ui_->checkbox_x11->isChecked()) {
|
||||
ui_->list->setEnabled(true);
|
||||
ui_->shortcut_options->setEnabled(true);
|
||||
ui_->list->setEnabled(configure_shortcuts);
|
||||
ui_->shortcut_options->setEnabled(configure_shortcuts);
|
||||
|
||||
if (ui_->widget_x11->isVisibleTo(this) && ui_->checkbox_x11->isChecked()) {
|
||||
ui_->widget_warning->show();
|
||||
X11Warning();
|
||||
}
|
||||
else {
|
||||
ui_->list->setEnabled(false);
|
||||
ui_->shortcut_options->setEnabled(false);
|
||||
ui_->widget_warning->hide();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GlobalShortcutsSettingsPage::GSDChanged(bool) {
|
||||
|
||||
if (!ui_->widget_gsd->isVisibleTo(this)) return;
|
||||
|
||||
if (ui_->checkbox_gsd->isChecked()) {
|
||||
if (ui_->checkbox_x11->isEnabled()) {
|
||||
ui_->checkbox_x11->setEnabled(false);
|
||||
}
|
||||
if (ui_->checkbox_x11->isChecked()) {
|
||||
ui_->checkbox_x11->setChecked(false);
|
||||
}
|
||||
ui_->list->setEnabled(false);
|
||||
ui_->shortcut_options->setEnabled(false);
|
||||
ui_->widget_warning->hide();
|
||||
}
|
||||
else {
|
||||
if (!ui_->checkbox_x11->isEnabled()) {
|
||||
ui_->checkbox_x11->setEnabled(true);
|
||||
if (ui_->checkbox_x11->isChecked()) {
|
||||
ui_->list->setEnabled(true);
|
||||
ui_->shortcut_options->setEnabled(true);
|
||||
X11Warning();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
void GlobalShortcutsSettingsPage::OpenGnomeKeybindingProperties() {
|
||||
|
||||
if (!QProcess::startDetached("gnome-keybinding-properties", QStringList())) {
|
||||
|
@ -324,13 +303,11 @@ void GlobalShortcutsSettingsPage::X11Warning() {
|
|||
if (de_.toLower() == "kde" || de_.toLower() == "gnome" || de_.toLower() == "x-cinnamon") {
|
||||
QString text(tr("Using X11 shortcuts on %1 is not recommended and can cause keyboard to become unresponsive!").arg(de_));
|
||||
if (de_.toLower() == "kde")
|
||||
text += tr(" Shortcuts on %1 are usually used through MPRIS D-Bus and should be configured in %1 settings instead.").arg(de_);
|
||||
text += tr(" Shortcuts on %1 are usually used through MPRIS and KGlobalAccel.").arg(de_);
|
||||
else if (de_.toLower() == "gnome")
|
||||
text += tr(" Shortcuts on %1 are usually used through GSD D-Bus and should be configured in gnome-settings-daemon instead.").arg(de_);
|
||||
text += tr(" Shortcuts on %1 are usually used through GSD and should be configured in gnome-settings-daemon instead.").arg(de_);
|
||||
else if (de_.toLower() == "x-cinnamon")
|
||||
text += tr(" Shortcuts on %1 are usually used through GSD D-Bus and should be configured in cinnamon-settings-daemon instead.").arg(de_);
|
||||
else
|
||||
text += tr(" Shortcuts should be configured in %1 settings instead.").arg(de_);
|
||||
text += tr(" Shortcuts on %1 are usually used through GSD and should be configured in cinnamon-settings-daemon instead.").arg(de_);
|
||||
ui_->label_warn_text->setText(text);
|
||||
ui_->widget_warning->show();
|
||||
}
|
||||
|
|
|
@ -55,8 +55,7 @@ class GlobalShortcutsSettingsPage : public SettingsPage {
|
|||
void Save() override;
|
||||
|
||||
private slots:
|
||||
void X11Changed(bool);
|
||||
void GSDChanged(bool);
|
||||
void ShortcutOptionsChanged();
|
||||
void OpenGnomeKeybindingProperties();
|
||||
|
||||
void ItemClicked(QTreeWidgetItem*);
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use Gnome (GSD) D-Bus shortcut keys</string>
|
||||
<string>Use Gnome (GSD) shortcuts when available</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -56,6 +56,31 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget_kde" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkbox_kde">
|
||||
<property name="text">
|
||||
<string>Use KDE (KGlobalAccel) shortcuts when available</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget_x11" native="true">
|
||||
<layout class="QHBoxLayout" name="layout_x11">
|
||||
|
@ -83,7 +108,7 @@
|
|||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use X11's shortcut keys</string>
|
||||
<string>Use X11 shortcuts when available</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
Loading…
Reference in New Issue