From 1ced4e277b8c7b96e47b3af397af47d05abeb5da Mon Sep 17 00:00:00 2001 From: Jonas Kvinge Date: Sat, 29 May 2021 20:35:55 +0200 Subject: [PATCH] Add global shortcuts support on MATE --- src/CMakeLists.txt | 9 +- .../org.mate.SettingsDaemon.MediaKeys.xml | 17 +++ ...d.cpp => globalshortcutsbackend-gnome.cpp} | 46 +++---- ...d-gsd.h => globalshortcutsbackend-gnome.h} | 19 +-- .../globalshortcutsbackend-kde.cpp | 8 +- .../globalshortcutsbackend-kde.h | 4 +- .../globalshortcutsbackend-mate.cpp | 119 ++++++++++++++++++ .../globalshortcutsbackend-mate.h | 61 +++++++++ .../globalshortcutsbackend-system.h | 2 + src/globalshortcuts/globalshortcutsbackend.h | 2 + .../globalshortcutsmanager.cpp | 39 ++++-- src/globalshortcuts/globalshortcutsmanager.h | 9 +- src/settings/globalshortcutssettingspage.cpp | 79 ++++++++---- src/settings/globalshortcutssettingspage.h | 1 + src/settings/globalshortcutssettingspage.ui | 48 ++++++- 15 files changed, 386 insertions(+), 77 deletions(-) create mode 100644 src/dbus/org.mate.SettingsDaemon.MediaKeys.xml rename src/globalshortcuts/{globalshortcutsbackend-gsd.cpp => globalshortcutsbackend-gnome.cpp} (69%) rename src/globalshortcuts/{globalshortcutsbackend-gsd.h => globalshortcutsbackend-gnome.h} (77%) create mode 100644 src/globalshortcuts/globalshortcutsbackend-mate.cpp create mode 100644 src/globalshortcuts/globalshortcutsbackend-mate.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6ab782be..c3a14df4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -552,8 +552,8 @@ if(HAVE_GLOBALSHORTCUTS) UI globalshortcuts/globalshortcutgrabber.ui settings/globalshortcutssettingspage.ui ) optional_source(HAVE_DBUS - SOURCES globalshortcuts/globalshortcutsbackend-gsd.cpp globalshortcuts/globalshortcutsbackend-kde.cpp - HEADERS globalshortcuts/globalshortcutsbackend-gsd.h globalshortcuts/globalshortcutsbackend-kde.h + SOURCES globalshortcuts/globalshortcutsbackend-kde.cpp globalshortcuts/globalshortcutsbackend-gnome.cpp globalshortcuts/globalshortcutsbackend-mate.cpp + HEADERS globalshortcuts/globalshortcutsbackend-kde.h globalshortcuts/globalshortcutsbackend-gnome.h globalshortcuts/globalshortcutsbackend-mate.h ) # Native shortcuts for X11 and Windows if(HAVE_X11_GLOBALSHORTCUTS OR WIN32) @@ -639,6 +639,11 @@ if(UNIX AND HAVE_DBUS) dbus/org.gnome.SettingsDaemon.MediaKeys.xml dbus/gnomesettingsdaemon) + # org.mate.SettingsDaemon interface + qt6_add_dbus_interface(SOURCES + dbus/org.mate.SettingsDaemon.MediaKeys.xml + dbus/matesettingsdaemon) + # org.kde.KGlobalAccel interface qt6_add_dbus_interface(SOURCES dbus/org.kde.KGlobalAccel.xml diff --git a/src/dbus/org.mate.SettingsDaemon.MediaKeys.xml b/src/dbus/org.mate.SettingsDaemon.MediaKeys.xml new file mode 100644 index 00000000..b313a36e --- /dev/null +++ b/src/dbus/org.mate.SettingsDaemon.MediaKeys.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + diff --git a/src/globalshortcuts/globalshortcutsbackend-gsd.cpp b/src/globalshortcuts/globalshortcutsbackend-gnome.cpp similarity index 69% rename from src/globalshortcuts/globalshortcutsbackend-gsd.cpp rename to src/globalshortcuts/globalshortcutsbackend-gnome.cpp index 0558032c..64fcdd19 100644 --- a/src/globalshortcuts/globalshortcutsbackend-gsd.cpp +++ b/src/globalshortcuts/globalshortcutsbackend-gnome.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -37,27 +36,33 @@ #include "core/logging.h" #include "globalshortcutsmanager.h" #include "globalshortcutsbackend.h" -#include "globalshortcutsbackend-gsd.h" +#include "globalshortcutsbackend-gnome.h" -const char *GlobalShortcutsBackendGSD::kGsdService = "org.gnome.SettingsDaemon.MediaKeys"; -const char *GlobalShortcutsBackendGSD::kGsdService2 = "org.gnome.SettingsDaemon"; -const char *GlobalShortcutsBackendGSD::kGsdPath = "/org/gnome/SettingsDaemon/MediaKeys"; +const char *GlobalShortcutsBackendGnome::kService1 = "org.gnome.SettingsDaemon.MediaKeys"; +const char *GlobalShortcutsBackendGnome::kService2 = "org.gnome.SettingsDaemon"; +const char *GlobalShortcutsBackendGnome::kPath = "/org/gnome/SettingsDaemon/MediaKeys"; -GlobalShortcutsBackendGSD::GlobalShortcutsBackendGSD(GlobalShortcutsManager *parent) +GlobalShortcutsBackendGnome::GlobalShortcutsBackendGnome(GlobalShortcutsManager *parent) : GlobalShortcutsBackend(parent), interface_(nullptr), is_connected_(false) {} -bool GlobalShortcutsBackendGSD::DoRegister() { +bool GlobalShortcutsBackendGnome::IsAvailable() { + + return QDBusConnection::sessionBus().interface()->isServiceRegistered(kService1) || QDBusConnection::sessionBus().interface()->isServiceRegistered(kService2); + +} + +bool GlobalShortcutsBackendGnome::DoRegister() { qLog(Debug) << "Registering"; if (!interface_) { - if (QDBusConnection::sessionBus().interface()->isServiceRegistered(kGsdService)) { - interface_ = new OrgGnomeSettingsDaemonMediaKeysInterface(kGsdService, kGsdPath, QDBusConnection::sessionBus(), this); + if (QDBusConnection::sessionBus().interface()->isServiceRegistered(kService1)) { + interface_ = new OrgGnomeSettingsDaemonMediaKeysInterface(kService1, kPath, QDBusConnection::sessionBus(), this); } - else if (QDBusConnection::sessionBus().interface()->isServiceRegistered(kGsdService2)) { - interface_ = new OrgGnomeSettingsDaemonMediaKeysInterface(kGsdService2, kGsdPath, QDBusConnection::sessionBus(), this); + else if (QDBusConnection::sessionBus().interface()->isServiceRegistered(kService2)) { + interface_ = new OrgGnomeSettingsDaemonMediaKeysInterface(kService2, kPath, QDBusConnection::sessionBus(), this); } } @@ -69,13 +74,13 @@ bool GlobalShortcutsBackendGSD::DoRegister() { QDBusPendingReply<> reply = interface_->GrabMediaPlayerKeys(QCoreApplication::applicationName(), QDateTime::currentDateTime().toSecsSinceEpoch()); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); - QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, &GlobalShortcutsBackendGSD::RegisterFinished); + QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, &GlobalShortcutsBackendGnome::RegisterFinished); return true; } -void GlobalShortcutsBackendGSD::RegisterFinished(QDBusPendingCallWatcher *watcher) { +void GlobalShortcutsBackendGnome::RegisterFinished(QDBusPendingCallWatcher *watcher) { QDBusMessage reply = watcher->reply(); watcher->deleteLater(); @@ -85,30 +90,27 @@ void GlobalShortcutsBackendGSD::RegisterFinished(QDBusPendingCallWatcher *watche return; } - QObject::connect(interface_, &OrgGnomeSettingsDaemonMediaKeysInterface::MediaPlayerKeyPressed, this, &GlobalShortcutsBackendGSD::GnomeMediaKeyPressed); + QObject::connect(interface_, &OrgGnomeSettingsDaemonMediaKeysInterface::MediaPlayerKeyPressed, this, &GlobalShortcutsBackendGnome::GnomeMediaKeyPressed); is_connected_ = true; - qLog(Debug) << "Registered"; + qLog(Debug) << "Registered."; } -void GlobalShortcutsBackendGSD::DoUnregister() { +void GlobalShortcutsBackendGnome::DoUnregister() { qLog(Debug) << "Unregister"; - // Check if the GSD service is available - if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(kGsdService)) - return; - if (!interface_ || !is_connected_) return; + if (!IsAvailable() || !interface_ || !is_connected_) return; is_connected_ = false; interface_->ReleaseMediaPlayerKeys(QCoreApplication::applicationName()); - QObject::disconnect(interface_, &OrgGnomeSettingsDaemonMediaKeysInterface::MediaPlayerKeyPressed, this, &GlobalShortcutsBackendGSD::GnomeMediaKeyPressed); + QObject::disconnect(interface_, &OrgGnomeSettingsDaemonMediaKeysInterface::MediaPlayerKeyPressed, this, &GlobalShortcutsBackendGnome::GnomeMediaKeyPressed); } -void GlobalShortcutsBackendGSD::GnomeMediaKeyPressed(const QString&, const QString &key) { +void GlobalShortcutsBackendGnome::GnomeMediaKeyPressed(const QString&, const QString &key) { auto shortcuts = manager_->shortcuts(); if (key == "Play") shortcuts["play_pause"].action->trigger(); diff --git a/src/globalshortcuts/globalshortcutsbackend-gsd.h b/src/globalshortcuts/globalshortcutsbackend-gnome.h similarity index 77% rename from src/globalshortcuts/globalshortcutsbackend-gsd.h rename to src/globalshortcuts/globalshortcutsbackend-gnome.h index 179ff5dd..1327319b 100644 --- a/src/globalshortcuts/globalshortcutsbackend-gsd.h +++ b/src/globalshortcuts/globalshortcutsbackend-gnome.h @@ -19,8 +19,8 @@ * */ -#ifndef GLOBALSHORTCUTSBACKEND_GSD_H -#define GLOBALSHORTCUTSBACKEND_GSD_H +#ifndef GLOBALSHORTCUTSBACKEND_GNOME_H +#define GLOBALSHORTCUTSBACKEND_GNOME_H #include "config.h" @@ -33,18 +33,15 @@ class QDBusPendingCallWatcher; class GlobalShortcutsManager; class OrgGnomeSettingsDaemonMediaKeysInterface; -class GlobalShortcutsBackendGSD : public GlobalShortcutsBackend { +class GlobalShortcutsBackendGnome : public GlobalShortcutsBackend { Q_OBJECT public: - explicit GlobalShortcutsBackendGSD(GlobalShortcutsManager *parent); + explicit GlobalShortcutsBackendGnome(GlobalShortcutsManager *parent); - static const char *kGsdService; - static const char *kGsdService2; - static const char *kGsdPath; + bool IsAvailable() override; protected: - bool RegisterInNewThread() const { return true; } bool DoRegister() override; void DoUnregister() override; @@ -54,9 +51,13 @@ class GlobalShortcutsBackendGSD : public GlobalShortcutsBackend { void GnomeMediaKeyPressed(const QString &application, const QString &key); private: + static const char *kService1; + static const char *kService2; + static const char *kPath; + OrgGnomeSettingsDaemonMediaKeysInterface *interface_; bool is_connected_; }; -#endif // GLOBALSHORTCUTSBACKEND_GSD_H +#endif // GLOBALSHORTCUTSBACKEND_GNOME_H diff --git a/src/globalshortcuts/globalshortcutsbackend-kde.cpp b/src/globalshortcuts/globalshortcutsbackend-kde.cpp index b34928aa..256ace0a 100644 --- a/src/globalshortcuts/globalshortcutsbackend-kde.cpp +++ b/src/globalshortcuts/globalshortcutsbackend-kde.cpp @@ -43,6 +43,12 @@ const char *GlobalShortcutsBackendKDE::kKdePath = "/kglobalaccel"; GlobalShortcutsBackendKDE::GlobalShortcutsBackendKDE(GlobalShortcutsManager *parent) : GlobalShortcutsBackend(parent), interface_(nullptr), component_(nullptr) {} +bool GlobalShortcutsBackendKDE::IsAvailable() { + + return QDBusConnection::sessionBus().interface()->isServiceRegistered(kKdeService); + +} + bool GlobalShortcutsBackendKDE::DoRegister() { qLog(Debug) << "Registering"; @@ -92,7 +98,7 @@ void GlobalShortcutsBackendKDE::RegisterFinished(QDBusPendingCallWatcher *watche QObject::connect(component_, &org::kde::kglobalaccel::Component::globalShortcutPressed, this, &GlobalShortcutsBackendKDE::GlobalShortcutPressed, Qt::UniqueConnection); - qLog(Debug) << "Registered"; + qLog(Debug) << "registered."; } diff --git a/src/globalshortcuts/globalshortcutsbackend-kde.h b/src/globalshortcuts/globalshortcutsbackend-kde.h index 0e7ab2da..a434ece9 100644 --- a/src/globalshortcuts/globalshortcutsbackend-kde.h +++ b/src/globalshortcuts/globalshortcutsbackend-kde.h @@ -43,9 +43,8 @@ class GlobalShortcutsBackendKDE : public GlobalShortcutsBackend { public: explicit GlobalShortcutsBackendKDE(GlobalShortcutsManager *parent); - static const char *kKdeService; - protected: + bool IsAvailable() override; bool DoRegister() override; void DoUnregister() override; @@ -60,6 +59,7 @@ class GlobalShortcutsBackendKDE : public GlobalShortcutsBackend { void GlobalShortcutPressed(const QString &component_unique, const QString &shortcut_unique, qint64); private: + static const char *kKdeService; static const char *kKdePath; OrgKdeKGlobalAccelInterface *interface_; diff --git a/src/globalshortcuts/globalshortcutsbackend-mate.cpp b/src/globalshortcuts/globalshortcutsbackend-mate.cpp new file mode 100644 index 00000000..91dd2969 --- /dev/null +++ b/src/globalshortcuts/globalshortcutsbackend-mate.cpp @@ -0,0 +1,119 @@ +/* + * Strawberry Music Player + * Copyright 2021, Jonas Kvinge + * + * 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 . + * + */ + +#include "config.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "core/logging.h" +#include "globalshortcutsmanager.h" +#include "globalshortcutsbackend.h" +#include "globalshortcutsbackend-mate.h" + +const char *GlobalShortcutsBackendMate::kService1 = "org.mate.SettingsDaemon.MediaKeys"; +const char *GlobalShortcutsBackendMate::kService2 = "org.mate.SettingsDaemon"; +const char *GlobalShortcutsBackendMate::kPath = "/org/mate/SettingsDaemon/MediaKeys"; + +GlobalShortcutsBackendMate::GlobalShortcutsBackendMate(GlobalShortcutsManager *parent) + : GlobalShortcutsBackend(parent), + interface_(nullptr), + is_connected_(false) {} + +bool GlobalShortcutsBackendMate::IsAvailable() { + + return QDBusConnection::sessionBus().interface()->isServiceRegistered(kService1) || QDBusConnection::sessionBus().interface()->isServiceRegistered(kService2); + +} + +bool GlobalShortcutsBackendMate::DoRegister() { + + qLog(Debug) << "Registering"; + + if (!interface_) { + if (QDBusConnection::sessionBus().interface()->isServiceRegistered(kService1)) { + interface_ = new OrgMateSettingsDaemonMediaKeysInterface(kService1, kPath, QDBusConnection::sessionBus(), this); + } + else if (QDBusConnection::sessionBus().interface()->isServiceRegistered(kService2)) { + interface_ = new OrgMateSettingsDaemonMediaKeysInterface(kService2, kPath, QDBusConnection::sessionBus(), this); + } + } + + if (!interface_) { + qLog(Warning) << "Mate settings daemon not registered"; + return false; + } + + QDBusPendingReply<> reply = interface_->GrabMediaPlayerKeys(QCoreApplication::applicationName(), QDateTime::currentDateTime().toSecsSinceEpoch()); + + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); + QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, &GlobalShortcutsBackendMate::RegisterFinished); + + return true; + +} + +void GlobalShortcutsBackendMate::RegisterFinished(QDBusPendingCallWatcher *watcher) { + + QDBusMessage reply = watcher->reply(); + watcher->deleteLater(); + + if (reply.type() == QDBusMessage::ErrorMessage) { + qLog(Warning) << "Failed to grab media keys" << reply.errorName() <ReleaseMediaPlayerKeys(QCoreApplication::applicationName()); + QObject::disconnect(interface_, &OrgMateSettingsDaemonMediaKeysInterface::MediaPlayerKeyPressed, this, &GlobalShortcutsBackendMate::MateMediaKeyPressed); + +} + +void GlobalShortcutsBackendMate::MateMediaKeyPressed(const QString&, const QString &key) { + + auto shortcuts = manager_->shortcuts(); + if (key == "Play") shortcuts["play_pause"].action->trigger(); + if (key == "Stop") shortcuts["stop"].action->trigger(); + if (key == "Next") shortcuts["next_track"].action->trigger(); + if (key == "Previous") shortcuts["prev_track"].action->trigger(); + +} diff --git a/src/globalshortcuts/globalshortcutsbackend-mate.h b/src/globalshortcuts/globalshortcutsbackend-mate.h new file mode 100644 index 00000000..fdea64cf --- /dev/null +++ b/src/globalshortcuts/globalshortcutsbackend-mate.h @@ -0,0 +1,61 @@ +/* + * Strawberry Music Player + * Copyright 2021, Jonas Kvinge + * + * 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 . + * + */ + +#ifndef GLOBALSHORTCUTSBACKEND_MATE_H +#define GLOBALSHORTCUTSBACKEND_MATE_H + +#include "config.h" + +#include +#include + +#include "globalshortcutsbackend.h" + +class QDBusPendingCallWatcher; +class GlobalShortcutsManager; +class OrgMateSettingsDaemonMediaKeysInterface; + +class GlobalShortcutsBackendMate : public GlobalShortcutsBackend { + Q_OBJECT + + public: + explicit GlobalShortcutsBackendMate(GlobalShortcutsManager *parent); + + bool IsAvailable() override; + + protected: + bool DoRegister() override; + void DoUnregister() override; + + private slots: + void RegisterFinished(QDBusPendingCallWatcher *watcher); + + void MateMediaKeyPressed(const QString &application, const QString &key); + + private: + static const char *kService1; + static const char *kService2; + static const char *kPath; + + OrgMateSettingsDaemonMediaKeysInterface *interface_; + bool is_connected_; + +}; + +#endif // GLOBALSHORTCUTSBACKEND_Mate_H diff --git a/src/globalshortcuts/globalshortcutsbackend-system.h b/src/globalshortcuts/globalshortcutsbackend-system.h index f0920602..fcdfe078 100644 --- a/src/globalshortcuts/globalshortcutsbackend-system.h +++ b/src/globalshortcuts/globalshortcutsbackend-system.h @@ -41,6 +41,8 @@ class GlobalShortcutsBackendSystem : public GlobalShortcutsBackend { explicit GlobalShortcutsBackendSystem(GlobalShortcutsManager *parent = nullptr); ~GlobalShortcutsBackendSystem() override; + bool IsAvailable() override { return true; } + protected: bool DoRegister() override; void DoUnregister() override; diff --git a/src/globalshortcuts/globalshortcutsbackend.h b/src/globalshortcuts/globalshortcutsbackend.h index 66e968b2..51b0d4b2 100644 --- a/src/globalshortcuts/globalshortcutsbackend.h +++ b/src/globalshortcuts/globalshortcutsbackend.h @@ -39,6 +39,8 @@ class GlobalShortcutsBackend : public QObject { bool Register(); void Unregister(); + virtual bool IsAvailable() = 0; + signals: void RegisterFinished(bool success); diff --git a/src/globalshortcuts/globalshortcutsmanager.cpp b/src/globalshortcuts/globalshortcutsmanager.cpp index 5b1d2090..13b09c98 100644 --- a/src/globalshortcuts/globalshortcutsmanager.cpp +++ b/src/globalshortcuts/globalshortcutsmanager.cpp @@ -38,8 +38,9 @@ #include "globalshortcutsbackend.h" #ifdef HAVE_DBUS -# include "globalshortcutsbackend-gsd.h" # include "globalshortcutsbackend-kde.h" +# include "globalshortcutsbackend-gnome.h" +# include "globalshortcutsbackend-mate.h" #endif #if (defined(HAVE_X11) && defined(HAVE_QPA_QPLATFORMNATIVEINTERFACE_H)) || defined(Q_OS_WIN) # include "globalshortcutsbackend-system.h" @@ -52,11 +53,13 @@ GlobalShortcutsManager::GlobalShortcutsManager(QWidget *parent) : QWidget(parent), - gsd_backend_(nullptr), kde_backend_(nullptr), + gnome_backend_(nullptr), + mate_backend_(nullptr), system_backend_(nullptr), - use_gsd_(true), use_kde_(true), + use_gnome_(true), + use_mate_(true), use_x11_(false) { @@ -85,8 +88,9 @@ GlobalShortcutsManager::GlobalShortcutsManager(QWidget *parent) // Create backends - these do the actual shortcut registration #ifdef HAVE_DBUS - gsd_backend_ = new GlobalShortcutsBackendGSD(this); kde_backend_ = new GlobalShortcutsBackendKDE(this); + gnome_backend_ = new GlobalShortcutsBackendGnome(this); + mate_backend_ = new GlobalShortcutsBackendMate(this); #endif #ifdef Q_OS_MACOS @@ -109,8 +113,9 @@ GlobalShortcutsManager::GlobalShortcutsManager(QWidget *parent) void GlobalShortcutsManager::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_gnome_ = settings_.value("use_gnome", true).toBool(); + use_mate_ = settings_.value("use_mate", true).toBool(); use_x11_ = settings_.value("use_x11", false).toBool(); Unregister(); @@ -144,20 +149,30 @@ GlobalShortcutsManager::Shortcut GlobalShortcutsManager::AddShortcut(const QStri } -bool GlobalShortcutsManager::IsGsdAvailable() const { +bool GlobalShortcutsManager::IsKdeAvailable() const { #ifdef HAVE_DBUS - return QDBusConnection::sessionBus().interface()->isServiceRegistered(GlobalShortcutsBackendGSD::kGsdService) || QDBusConnection::sessionBus().interface()->isServiceRegistered(GlobalShortcutsBackendGSD::kGsdService2); + return kde_backend_->IsAvailable(); #else return false; #endif } -bool GlobalShortcutsManager::IsKdeAvailable() const { +bool GlobalShortcutsManager::IsGnomeAvailable() const { #ifdef HAVE_DBUS - return QDBusConnection::sessionBus().interface()->isServiceRegistered(GlobalShortcutsBackendKDE::kKdeService); + return gnome_backend_->IsAvailable(); +#else + return false; +#endif + +} + +bool GlobalShortcutsManager::IsMateAvailable() const { + +#ifdef HAVE_DBUS + return mate_backend_->IsAvailable(); #else return false; #endif @@ -172,8 +187,9 @@ bool GlobalShortcutsManager::IsX11Available() const { void GlobalShortcutsManager::Register() { - if (use_gsd_ && gsd_backend_ && gsd_backend_->Register()) return; if (use_kde_ && kde_backend_ && kde_backend_->Register()) return; + if (use_gnome_ && gnome_backend_ && gnome_backend_->Register()) return; + if (use_mate_ && mate_backend_ && mate_backend_->Register()) return; #if defined(HAVE_X11) && defined(HAVE_QPA_QPLATFORMNATIVEINTERFACE_H) // If this system has X11, only use the system backend if X11 is enabled in the global shortcut settings if (use_x11_) { #endif @@ -187,8 +203,9 @@ void GlobalShortcutsManager::Register() { void GlobalShortcutsManager::Unregister() { - if (gsd_backend_ && gsd_backend_->is_active()) gsd_backend_->Unregister(); if (kde_backend_ && kde_backend_->is_active()) kde_backend_->Unregister(); + if (gnome_backend_ && gnome_backend_->is_active()) gnome_backend_->Unregister(); + if (mate_backend_ && mate_backend_->is_active()) mate_backend_->Unregister(); if (system_backend_ && system_backend_->is_active()) system_backend_->Unregister(); } diff --git a/src/globalshortcuts/globalshortcutsmanager.h b/src/globalshortcuts/globalshortcutsmanager.h index 5d15d3fc..73eb0fcb 100644 --- a/src/globalshortcuts/globalshortcutsmanager.h +++ b/src/globalshortcuts/globalshortcutsmanager.h @@ -51,9 +51,10 @@ class GlobalShortcutsManager : public QWidget { }; QMap shortcuts() const { return shortcuts_; } - bool IsGsdAvailable() const; bool IsKdeAvailable() const; bool IsX11Available() const; + bool IsGnomeAvailable() const; + bool IsMateAvailable() const; bool IsMacAccessibilityEnabled() const; public slots: @@ -90,15 +91,17 @@ class GlobalShortcutsManager : public QWidget { Shortcut AddShortcut(const QString &id, const QString &name, const QKeySequence &default_key); private: - GlobalShortcutsBackend *gsd_backend_; GlobalShortcutsBackend *kde_backend_; + GlobalShortcutsBackend *gnome_backend_; + GlobalShortcutsBackend *mate_backend_; GlobalShortcutsBackend *system_backend_; QMap shortcuts_; QSettings settings_; - bool use_gsd_; bool use_kde_; + bool use_gnome_; + bool use_mate_; bool use_x11_; }; diff --git a/src/settings/globalshortcutssettingspage.cpp b/src/settings/globalshortcutssettingspage.cpp index d6194c8e..3ee0f323 100644 --- a/src/settings/globalshortcutssettingspage.cpp +++ b/src/settings/globalshortcutssettingspage.cpp @@ -73,16 +73,19 @@ GlobalShortcutsSettingsPage::GlobalShortcutsSettingsPage(SettingsDialog *dialog) #if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) # ifdef HAVE_DBUS - QObject::connect(ui_->checkbox_gsd, &QCheckBox::toggled, this, &GlobalShortcutsSettingsPage::ShortcutOptionsChanged); QObject::connect(ui_->checkbox_kde, &QCheckBox::toggled, this, &GlobalShortcutsSettingsPage::ShortcutOptionsChanged); - QObject::connect(ui_->button_gsd_open, &QPushButton::clicked, this, &GlobalShortcutsSettingsPage::OpenGnomeKeybindingProperties); + QObject::connect(ui_->checkbox_gnome, &QCheckBox::toggled, this, &GlobalShortcutsSettingsPage::ShortcutOptionsChanged); + QObject::connect(ui_->checkbox_mate, &QCheckBox::toggled, this, &GlobalShortcutsSettingsPage::ShortcutOptionsChanged); + QObject::connect(ui_->button_gnome_open, &QPushButton::clicked, this, &GlobalShortcutsSettingsPage::OpenGnomeKeybindingProperties); + QObject::connect(ui_->button_mate_open, &QPushButton::clicked, this, &GlobalShortcutsSettingsPage::OpenMateKeybindingProperties); # endif # if defined(HAVE_X11) && defined(HAVE_QPA_QPLATFORMNATIVEINTERFACE_H) QObject::connect(ui_->checkbox_x11, &QCheckBox::toggled, this, &GlobalShortcutsSettingsPage::ShortcutOptionsChanged); # endif #else - ui_->widget_gsd->hide(); ui_->widget_kde->hide(); + ui_->widget_gnome->hide(); + ui_->widget_mate->hide(); ui_->widget_x11->hide(); #endif // defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) @@ -119,15 +122,6 @@ void GlobalShortcutsSettingsPage::Load() { QObject::connect(ui_->button_macos_open, &QPushButton::clicked, manager, &GlobalShortcutsManager::ShowMacAccessibilityDialog); #if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) - if (manager->IsGsdAvailable()) { - qLog(Debug) << "Gnome (GSD) backend is available."; - ui_->widget_gsd->show(); - } - else { - 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(); @@ -137,6 +131,24 @@ void GlobalShortcutsSettingsPage::Load() { ui_->widget_kde->hide(); } + if (manager->IsGnomeAvailable()) { + qLog(Debug) << "Gnome (GSD) backend is available."; + ui_->widget_gnome->show(); + } + else { + qLog(Debug) << "Gnome (GSD) backend is unavailable."; + ui_->widget_gnome->hide(); + } + + if (manager->IsMateAvailable()) { + qLog(Debug) << "MATE backend is available."; + ui_->widget_mate->show(); + } + else { + qLog(Debug) << "MATE backend is unavailable."; + ui_->widget_mate->hide(); + } + if (manager->IsX11Available()) { qLog(Debug) << "X11 backend is available."; ui_->widget_x11->show(); @@ -167,14 +179,19 @@ void GlobalShortcutsSettingsPage::Load() { } #if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) - if (ui_->widget_gsd->isVisibleTo(this)) { - 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()); } + if (ui_->widget_gnome->isVisibleTo(this)) { + ui_->checkbox_gnome->setChecked(s.value("use_gnome", true).toBool()); + } + + if (ui_->widget_mate->isVisibleTo(this)) { + ui_->checkbox_mate->setChecked(s.value("use_mate", true).toBool()); + } + if (ui_->widget_x11->isVisibleTo(this)) { ui_->checkbox_x11->setChecked(s.value("use_x11", false).toBool()); } @@ -212,8 +229,9 @@ void GlobalShortcutsSettingsPage::Save() { } #if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) - s.setValue("use_gsd", ui_->checkbox_gsd->isChecked()); s.setValue("use_kde", ui_->checkbox_kde->isChecked()); + s.setValue("use_gnome", ui_->checkbox_gnome->isChecked()); + s.setValue("use_mate", ui_->checkbox_mate->isChecked()); s.setValue("use_x11", ui_->checkbox_x11->isChecked()); #endif @@ -251,6 +269,16 @@ void GlobalShortcutsSettingsPage::OpenGnomeKeybindingProperties() { } +void GlobalShortcutsSettingsPage::OpenMateKeybindingProperties() { + + if (!QProcess::startDetached("mate-keybinding-properties", QStringList())) { + if (!QProcess::startDetached("mate-control-center", QStringList() << "keyboard")) { + QMessageBox::warning(this, "Error", tr("The \"%1\" command could not be started.").arg("mate-keybinding-properties")); + } + } + +} + void GlobalShortcutsSettingsPage::SetShortcut(const QString &id, const QKeySequence &key) { Shortcut &shortcut = shortcuts_[id]; @@ -316,14 +344,21 @@ void GlobalShortcutsSettingsPage::ChangeClicked() { void GlobalShortcutsSettingsPage::X11Warning() { - if (de_.toLower() == "kde" || de_.toLower() == "gnome" || de_.toLower() == "x-cinnamon") { + QString de = de_.toLower(); + if (de == "kde" || de == "gnome" || de == "x-cinnamon" || de == "mate") { 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 == "kde") { 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 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 and should be configured in cinnamon-settings-daemon instead.").arg(de_); + } + else if (de == "gnome") { + text += tr(" Shortcuts on %1 are usually used through Gnome Settings Daemon and should be configured in gnome-settings-daemon instead.").arg(de_); + } + else if (de == "x-cinnamon") { + text += tr(" Shortcuts on %1 are usually used through Gnome Settings Daemon and should be configured in cinnamon-settings-daemon instead.").arg(de_); + } + else if (de == "mate") { + text += tr(" Shortcuts on %1 are usually used through MATE Settings Daemon and should be configured there instead.").arg(de_); + } ui_->label_warn_text->setText(text); ui_->widget_warning->show(); } diff --git a/src/settings/globalshortcutssettingspage.h b/src/settings/globalshortcutssettingspage.h index fd6de751..b582f855 100644 --- a/src/settings/globalshortcutssettingspage.h +++ b/src/settings/globalshortcutssettingspage.h @@ -57,6 +57,7 @@ class GlobalShortcutsSettingsPage : public SettingsPage { private slots: void ShortcutOptionsChanged(); void OpenGnomeKeybindingProperties(); + void OpenMateKeybindingProperties(); void ItemClicked(QTreeWidgetItem*); void NoneClicked(); diff --git a/src/settings/globalshortcutssettingspage.ui b/src/settings/globalshortcutssettingspage.ui index 8cf1bd72..b88a78bf 100644 --- a/src/settings/globalshortcutssettingspage.ui +++ b/src/settings/globalshortcutssettingspage.ui @@ -19,7 +19,7 @@ - + 0 @@ -34,7 +34,7 @@ 0 - + 0 @@ -47,7 +47,45 @@ - + + + Open... + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + Use MATE shortcuts when available + + + + + Open... @@ -319,8 +357,8 @@ - checkbox_gsd - button_gsd_open + checkbox_gnome + button_gnome_open checkbox_x11 button_macos_open list