parent
e8492940a5
commit
c258e5a3af
|
@ -559,8 +559,8 @@ if(HAVE_GLOBALSHORTCUTS)
|
||||||
SOURCES globalshortcuts/globalshortcut-x11.cpp
|
SOURCES globalshortcuts/globalshortcut-x11.cpp
|
||||||
)
|
)
|
||||||
optional_source(HAVE_DBUS
|
optional_source(HAVE_DBUS
|
||||||
SOURCES globalshortcuts/globalshortcutbackend-gsd.cpp
|
SOURCES globalshortcuts/globalshortcutbackend-gsd.cpp globalshortcuts/globalshortcutbackend-kde.cpp
|
||||||
HEADERS globalshortcuts/globalshortcutbackend-gsd.h
|
HEADERS globalshortcuts/globalshortcutbackend-gsd.h globalshortcuts/globalshortcutbackend-kde.h
|
||||||
)
|
)
|
||||||
optional_source(WIN32
|
optional_source(WIN32
|
||||||
SOURCES globalshortcuts/globalshortcut-win.cpp
|
SOURCES globalshortcuts/globalshortcut-win.cpp
|
||||||
|
@ -634,6 +634,14 @@ if(UNIX AND HAVE_DBUS)
|
||||||
dbus/org.gnome.SettingsDaemon.MediaKeys.xml
|
dbus/org.gnome.SettingsDaemon.MediaKeys.xml
|
||||||
dbus/gnomesettingsdaemon)
|
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()
|
else()
|
||||||
|
|
||||||
# MPRIS 2.0 DBUS interfaces
|
# MPRIS 2.0 DBUS interfaces
|
||||||
|
@ -662,6 +670,14 @@ if(UNIX AND HAVE_DBUS)
|
||||||
dbus/org.gnome.SettingsDaemon.MediaKeys.xml
|
dbus/org.gnome.SettingsDaemon.MediaKeys.xml
|
||||||
dbus/gnomesettingsdaemon)
|
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()
|
endif()
|
||||||
|
|
||||||
# org.freedesktop.Avahi.Server interface
|
# 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
|
#ifdef HAVE_DBUS
|
||||||
# include "globalshortcutbackend-gsd.h"
|
# include "globalshortcutbackend-gsd.h"
|
||||||
|
# include "globalshortcutbackend-kde.h"
|
||||||
#endif
|
#endif
|
||||||
#if defined(HAVE_X11) || defined(Q_OS_WIN)
|
#if defined(HAVE_X11) || defined(Q_OS_WIN)
|
||||||
# include "globalshortcutbackend-system.h"
|
# include "globalshortcutbackend-system.h"
|
||||||
|
@ -51,9 +52,11 @@
|
||||||
|
|
||||||
GlobalShortcuts::GlobalShortcuts(QWidget *parent)
|
GlobalShortcuts::GlobalShortcuts(QWidget *parent)
|
||||||
: QWidget(parent),
|
: QWidget(parent),
|
||||||
dbus_backend_(nullptr),
|
gsd_backend_(nullptr),
|
||||||
|
kde_backend_(nullptr),
|
||||||
system_backend_(nullptr),
|
system_backend_(nullptr),
|
||||||
use_gsd_(true),
|
use_gsd_(true),
|
||||||
|
use_kde_(true),
|
||||||
use_x11_(false)
|
use_x11_(false)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -82,7 +85,8 @@ GlobalShortcuts::GlobalShortcuts(QWidget *parent)
|
||||||
|
|
||||||
// Create backends - these do the actual shortcut registration
|
// Create backends - these do the actual shortcut registration
|
||||||
#ifdef HAVE_DBUS
|
#ifdef HAVE_DBUS
|
||||||
dbus_backend_ = new GlobalShortcutBackendGSD(this);
|
gsd_backend_ = new GlobalShortcutBackendGSD(this);
|
||||||
|
kde_backend_ = new GlobalShortcutBackendKDE(this);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Q_OS_MACOS
|
#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.
|
// 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_gsd_ = settings_.value("use_gsd", true).toBool();
|
||||||
|
use_kde_ = settings_.value("use_kde", true).toBool();
|
||||||
use_x11_ = settings_.value("use_x11", false).toBool();
|
use_x11_ = settings_.value("use_x11", false).toBool();
|
||||||
|
|
||||||
Unregister();
|
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 {
|
bool GlobalShortcuts::IsX11Available() const {
|
||||||
|
|
||||||
#ifdef HAVE_X11
|
#ifdef HAVE_X11
|
||||||
|
@ -160,7 +175,9 @@ bool GlobalShortcuts::IsX11Available() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalShortcuts::Register() {
|
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
|
#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_) {
|
if (use_x11_) {
|
||||||
#endif
|
#endif
|
||||||
|
@ -169,11 +186,15 @@ void GlobalShortcuts::Register() {
|
||||||
#ifdef HAVE_X11
|
#ifdef HAVE_X11
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalShortcuts::Unregister() {
|
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();
|
if (system_backend_ && system_backend_->is_active()) system_backend_->Unregister();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GlobalShortcuts::IsMacAccessibilityEnabled() const {
|
bool GlobalShortcuts::IsMacAccessibilityEnabled() const {
|
||||||
|
|
|
@ -50,6 +50,7 @@ class GlobalShortcuts : public QWidget {
|
||||||
|
|
||||||
QMap<QString, Shortcut> shortcuts() const { return shortcuts_; }
|
QMap<QString, Shortcut> shortcuts() const { return shortcuts_; }
|
||||||
bool IsGsdAvailable() const;
|
bool IsGsdAvailable() const;
|
||||||
|
bool IsKdeAvailable() const;
|
||||||
bool IsX11Available() const;
|
bool IsX11Available() const;
|
||||||
bool IsMacAccessibilityEnabled() const;
|
bool IsMacAccessibilityEnabled() const;
|
||||||
|
|
||||||
|
@ -87,13 +88,15 @@ class GlobalShortcuts : public QWidget {
|
||||||
Shortcut AddShortcut(const QString &id, const QString &name, const QKeySequence &default_key);
|
Shortcut AddShortcut(const QString &id, const QString &name, const QKeySequence &default_key);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GlobalShortcutBackend *dbus_backend_;
|
GlobalShortcutBackend *gsd_backend_;
|
||||||
|
GlobalShortcutBackend *kde_backend_;
|
||||||
GlobalShortcutBackend *system_backend_;
|
GlobalShortcutBackend *system_backend_;
|
||||||
|
|
||||||
QMap<QString, Shortcut> shortcuts_;
|
QMap<QString, Shortcut> shortcuts_;
|
||||||
QSettings settings_;
|
QSettings settings_;
|
||||||
|
|
||||||
bool use_gsd_;
|
bool use_gsd_;
|
||||||
|
bool use_kde_;
|
||||||
bool use_x11_;
|
bool use_x11_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -73,11 +73,12 @@ GlobalShortcutsSettingsPage::GlobalShortcutsSettingsPage(SettingsDialog *dialog)
|
||||||
|
|
||||||
#if !defined(Q_OS_WIN) && !defined(Q_OS_MACOS)
|
#if !defined(Q_OS_WIN) && !defined(Q_OS_MACOS)
|
||||||
#ifdef HAVE_DBUS
|
#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()));
|
connect(ui_->button_gsd_open, SIGNAL(clicked()), SLOT(OpenGnomeKeybindingProperties()));
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_X11
|
#ifdef HAVE_X11
|
||||||
connect(ui_->checkbox_x11, SIGNAL(clicked(bool)), SLOT(X11Changed(bool)));
|
connect(ui_->checkbox_x11, SIGNAL(clicked(bool)), SLOT(ShortcutOptionsChanged()));
|
||||||
#endif
|
#endif
|
||||||
#endif // !defined(Q_OS_WIN) && !defined(Q_OS_MACOS)
|
#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()));
|
connect(ui_->button_macos_open, SIGNAL(clicked()), manager, SLOT(ShowMacAccessibilityDialog()));
|
||||||
|
|
||||||
if (manager->IsGsdAvailable()) {
|
if (manager->IsGsdAvailable()) {
|
||||||
qLog(Debug) << "Gnome (GSD) D-Bus backend is available.";
|
qLog(Debug) << "Gnome (GSD) backend is available.";
|
||||||
ui_->widget_gsd->show();
|
ui_->widget_gsd->show();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
qLog(Debug) << "Gnome (GSD) D-Bus backend is unavailable.";
|
qLog(Debug) << "Gnome (GSD) backend is unavailable.";
|
||||||
ui_->widget_gsd->hide();
|
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()) {
|
if (manager->IsX11Available()) {
|
||||||
qLog(Debug) << "X11 backend is available.";
|
qLog(Debug) << "X11 backend is available.";
|
||||||
ui_->widget_x11->show();
|
ui_->widget_x11->show();
|
||||||
|
@ -129,7 +139,6 @@ void GlobalShortcutsSettingsPage::Load() {
|
||||||
else {
|
else {
|
||||||
qLog(Debug) << "X11 backend is unavailable.";
|
qLog(Debug) << "X11 backend is unavailable.";
|
||||||
ui_->widget_x11->hide();
|
ui_->widget_x11->hide();
|
||||||
s.setValue("use_x11", false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const GlobalShortcuts::Shortcut &i : manager->shortcuts().values()) {
|
for (const GlobalShortcuts::Shortcut &i : manager->shortcuts().values()) {
|
||||||
|
@ -149,24 +158,19 @@ void GlobalShortcutsSettingsPage::Load() {
|
||||||
SetShortcut(shortcut.s.id, shortcut.s.action->shortcut());
|
SetShortcut(shortcut.s.id, shortcut.s.action->shortcut());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool use_gsd = s.value("use_gsd", true).toBool();
|
|
||||||
if (ui_->widget_gsd->isVisibleTo(this)) {
|
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)) {
|
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)
|
ShortcutOptionsChanged();
|
||||||
#ifdef HAVE_DBUS
|
|
||||||
GSDChanged(true);
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_X11
|
|
||||||
X11Changed(true);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ui_->widget_macos->setVisible(!manager->IsMacAccessibilityEnabled());
|
ui_->widget_macos->setVisible(!manager->IsMacAccessibilityEnabled());
|
||||||
#ifdef Q_OS_MACOS
|
#ifdef Q_OS_MACOS
|
||||||
|
@ -195,6 +199,7 @@ void GlobalShortcutsSettingsPage::Save() {
|
||||||
}
|
}
|
||||||
|
|
||||||
s.setValue("use_gsd", ui_->checkbox_gsd->isChecked());
|
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.setValue("use_x11", ui_->checkbox_x11->isChecked());
|
||||||
|
|
||||||
s.endGroup();
|
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(configure_shortcuts);
|
||||||
ui_->list->setEnabled(true);
|
ui_->shortcut_options->setEnabled(configure_shortcuts);
|
||||||
ui_->shortcut_options->setEnabled(true);
|
|
||||||
|
if (ui_->widget_x11->isVisibleTo(this) && ui_->checkbox_x11->isChecked()) {
|
||||||
|
ui_->widget_warning->show();
|
||||||
X11Warning();
|
X11Warning();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ui_->list->setEnabled(false);
|
|
||||||
ui_->shortcut_options->setEnabled(false);
|
|
||||||
ui_->widget_warning->hide();
|
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() {
|
void GlobalShortcutsSettingsPage::OpenGnomeKeybindingProperties() {
|
||||||
|
|
||||||
if (!QProcess::startDetached("gnome-keybinding-properties", QStringList())) {
|
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") {
|
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_));
|
QString text(tr("Using X11 shortcuts on %1 is not recommended and can cause keyboard to become unresponsive!").arg(de_));
|
||||||
if (de_.toLower() == "kde")
|
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")
|
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")
|
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_);
|
text += tr(" Shortcuts on %1 are usually used through GSD and should be configured in cinnamon-settings-daemon instead.").arg(de_);
|
||||||
else
|
|
||||||
text += tr(" Shortcuts should be configured in %1 settings instead.").arg(de_);
|
|
||||||
ui_->label_warn_text->setText(text);
|
ui_->label_warn_text->setText(text);
|
||||||
ui_->widget_warning->show();
|
ui_->widget_warning->show();
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,8 +55,7 @@ class GlobalShortcutsSettingsPage : public SettingsPage {
|
||||||
void Save() override;
|
void Save() override;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void X11Changed(bool);
|
void ShortcutOptionsChanged();
|
||||||
void GSDChanged(bool);
|
|
||||||
void OpenGnomeKeybindingProperties();
|
void OpenGnomeKeybindingProperties();
|
||||||
|
|
||||||
void ItemClicked(QTreeWidgetItem*);
|
void ItemClicked(QTreeWidgetItem*);
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Use Gnome (GSD) D-Bus shortcut keys</string>
|
<string>Use Gnome (GSD) shortcuts when available</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -56,6 +56,31 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</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>
|
<item>
|
||||||
<widget class="QWidget" name="widget_x11" native="true">
|
<widget class="QWidget" name="widget_x11" native="true">
|
||||||
<layout class="QHBoxLayout" name="layout_x11">
|
<layout class="QHBoxLayout" name="layout_x11">
|
||||||
|
@ -83,7 +108,7 @@
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Use X11's shortcut keys</string>
|
<string>Use X11 shortcuts when available</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
Loading…
Reference in New Issue