diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ee0ad98a9..03e2c7394 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -580,16 +580,14 @@ if(HAVE_GLOBALSHORTCUTS) 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) - SET(X11_OR_WIN ON) - optional_source(X11_OR_WIN - SOURCES globalshortcuts/globalshortcutsbackend-system.cpp globalshortcuts/globalshortcut.cpp - HEADERS globalshortcuts/globalshortcutsbackend-system.h globalshortcuts/globalshortcut.h - ) - optional_source(HAVE_X11_GLOBALSHORTCUTS SOURCES globalshortcuts/globalshortcut-x11.cpp) - optional_source(WIN32 SOURCES globalshortcuts/globalshortcut-win.cpp) - endif() + optional_source(HAVE_X11_GLOBALSHORTCUTS + SOURCES globalshortcuts/globalshortcutsbackend-x11.cpp globalshortcuts/globalshortcut.cpp globalshortcuts/globalshortcut-x11.cpp + HEADERS globalshortcuts/globalshortcutsbackend-x11.h globalshortcuts/globalshortcut.h + ) + optional_source(WIN32 + SOURCES globalshortcuts/globalshortcutsbackend-win.cpp globalshortcuts/globalshortcut.cpp globalshortcuts/globalshortcut-win.cpp + HEADERS globalshortcuts/globalshortcutsbackend-win.h globalshortcuts/globalshortcut.h + ) endif(HAVE_GLOBALSHORTCUTS) # ALSA diff --git a/src/globalshortcuts/globalshortcutsbackend-gnome.cpp b/src/globalshortcuts/globalshortcutsbackend-gnome.cpp index addcbe4c4..1f86e8a79 100644 --- a/src/globalshortcuts/globalshortcutsbackend-gnome.cpp +++ b/src/globalshortcuts/globalshortcutsbackend-gnome.cpp @@ -43,11 +43,15 @@ const char *GlobalShortcutsBackendGnome::kService2 = "org.gnome.SettingsDaemon"; const char *GlobalShortcutsBackendGnome::kPath = "/org/gnome/SettingsDaemon/MediaKeys"; GlobalShortcutsBackendGnome::GlobalShortcutsBackendGnome(GlobalShortcutsManager *manager, QObject *parent) - : GlobalShortcutsBackend(manager, parent), + : GlobalShortcutsBackend(manager, GlobalShortcutsBackend::Type_Gnome, parent), interface_(nullptr), is_connected_(false) {} -bool GlobalShortcutsBackendGnome::IsAvailable() { +bool GlobalShortcutsBackendGnome::IsAvailable() const { + return IsGnomeAvailable(); +} + +bool GlobalShortcutsBackendGnome::IsGnomeAvailable() { return QDBusConnection::sessionBus().interface()->isServiceRegistered(kService1) || QDBusConnection::sessionBus().interface()->isServiceRegistered(kService2); diff --git a/src/globalshortcuts/globalshortcutsbackend-gnome.h b/src/globalshortcuts/globalshortcutsbackend-gnome.h index d725b7a32..eedd91e3e 100644 --- a/src/globalshortcuts/globalshortcutsbackend-gnome.h +++ b/src/globalshortcuts/globalshortcutsbackend-gnome.h @@ -39,7 +39,8 @@ class GlobalShortcutsBackendGnome : public GlobalShortcutsBackend { public: explicit GlobalShortcutsBackendGnome(GlobalShortcutsManager *manager, QObject *parent = nullptr); - bool IsAvailable() override; + bool IsAvailable() const override; + static bool IsGnomeAvailable(); protected: bool DoRegister() override; diff --git a/src/globalshortcuts/globalshortcutsbackend-kde.cpp b/src/globalshortcuts/globalshortcutsbackend-kde.cpp index d3d543d4f..9e4025bec 100644 --- a/src/globalshortcuts/globalshortcutsbackend-kde.cpp +++ b/src/globalshortcuts/globalshortcutsbackend-kde.cpp @@ -42,16 +42,22 @@ const char *GlobalShortcutsBackendKDE::kKdeService = "org.kde.kglobalaccel"; const char *GlobalShortcutsBackendKDE::kKdePath = "/kglobalaccel"; GlobalShortcutsBackendKDE::GlobalShortcutsBackendKDE(GlobalShortcutsManager *manager, QObject *parent) - : GlobalShortcutsBackend(manager, parent), + : GlobalShortcutsBackend(manager, GlobalShortcutsBackend::Type_KDE, parent), interface_(nullptr), component_(nullptr) {} -bool GlobalShortcutsBackendKDE::IsAvailable() { +bool GlobalShortcutsBackendKDE::IsKDEAvailable() { return QDBusConnection::sessionBus().interface()->isServiceRegistered(kKdeService); } +bool GlobalShortcutsBackendKDE::IsAvailable() const { + + return IsKDEAvailable(); + +} + bool GlobalShortcutsBackendKDE::DoRegister() { qLog(Debug) << "Registering"; diff --git a/src/globalshortcuts/globalshortcutsbackend-kde.h b/src/globalshortcuts/globalshortcutsbackend-kde.h index 58c7a52ad..aa5a24479 100644 --- a/src/globalshortcuts/globalshortcutsbackend-kde.h +++ b/src/globalshortcuts/globalshortcutsbackend-kde.h @@ -43,7 +43,8 @@ class GlobalShortcutsBackendKDE : public GlobalShortcutsBackend { public: explicit GlobalShortcutsBackendKDE(GlobalShortcutsManager *manager, QObject *parent = nullptr); - bool IsAvailable() override; + bool IsAvailable() const override; + static bool IsKDEAvailable(); protected: bool DoRegister() override; diff --git a/src/globalshortcuts/globalshortcutsbackend-macos.h b/src/globalshortcuts/globalshortcutsbackend-macos.h index 43d7eb510..d0015cbfb 100644 --- a/src/globalshortcuts/globalshortcutsbackend-macos.h +++ b/src/globalshortcuts/globalshortcutsbackend-macos.h @@ -2,6 +2,7 @@ * Strawberry Music Player * This file was part of Clementine. * Copyright 2010, David Sansome + * Copyright 2018-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 @@ -32,8 +33,6 @@ #include #include -class GlobalShortcut; - class GlobalShortcutsBackendMacOSPrivate; class GlobalShortcutsBackendMacOS : public GlobalShortcutsBackend { @@ -43,12 +42,12 @@ class GlobalShortcutsBackendMacOS : public GlobalShortcutsBackend { explicit GlobalShortcutsBackendMacOS(GlobalShortcutsManager *manager, QObject *parent = nullptr); virtual ~GlobalShortcutsBackendMacOS(); - bool IsAvailable() override { return true; } + bool IsAvailable() const override { return true; } - bool IsAccessibilityEnabled() const; - void ShowAccessibilityDialog(); + static bool IsAccessibilityEnabled(); + static void ShowAccessibilityDialog(); - void MacMediaKeyPressed(int key); + void MacMediaKeyPressed(const int key); protected: bool DoRegister() override; diff --git a/src/globalshortcuts/globalshortcutsbackend-macos.mm b/src/globalshortcuts/globalshortcutsbackend-macos.mm index e88917a63..b40753daf 100644 --- a/src/globalshortcuts/globalshortcutsbackend-macos.mm +++ b/src/globalshortcuts/globalshortcutsbackend-macos.mm @@ -2,6 +2,7 @@ * Strawberry Music Player * This file was part of Clementine. * Copyright 2010, David Sansome + * Copyright 2018-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 @@ -78,7 +79,7 @@ class GlobalShortcutsBackendMacOSPrivate : boost::noncopyable { }; GlobalShortcutsBackendMacOS::GlobalShortcutsBackendMacOS(GlobalShortcutsManager *manager, QObject *parent) - : GlobalShortcutsBackend(manager, parent), + : GlobalShortcutsBackend(manager, GlobalShortcutsBackend::Type_MacOS, parent), p_(new GlobalShortcutsBackendMacOSPrivate(this)) {} GlobalShortcutsBackendMacOS::~GlobalShortcutsBackendMacOS() {} @@ -104,7 +105,7 @@ void GlobalShortcutsBackendMacOS::DoUnregister() { } -void GlobalShortcutsBackendMacOS::MacMediaKeyPressed(int key) { +void GlobalShortcutsBackendMacOS::MacMediaKeyPressed(const int key) { switch (key) { case NX_KEYTYPE_PLAY: @@ -134,7 +135,7 @@ bool GlobalShortcutsBackendMacOS::KeyPressed(const QKeySequence &sequence) { } -bool GlobalShortcutsBackendMacOS::IsAccessibilityEnabled() const { +bool GlobalShortcutsBackendMacOS::IsAccessibilityEnabled() { NSDictionary *options = @{(id)kAXTrustedCheckOptionPrompt: @YES}; return AXIsProcessTrustedWithOptions((CFDictionaryRef)options); @@ -165,4 +166,5 @@ void GlobalShortcutsBackendMacOS::ShowAccessibilityDialog() { } } } + } diff --git a/src/globalshortcuts/globalshortcutsbackend-mate.cpp b/src/globalshortcuts/globalshortcutsbackend-mate.cpp index 639e808fd..dd728d3de 100644 --- a/src/globalshortcuts/globalshortcutsbackend-mate.cpp +++ b/src/globalshortcuts/globalshortcutsbackend-mate.cpp @@ -41,11 +41,17 @@ const char *GlobalShortcutsBackendMate::kService2 = "org.mate.SettingsDaemon"; const char *GlobalShortcutsBackendMate::kPath = "/org/mate/SettingsDaemon/MediaKeys"; GlobalShortcutsBackendMate::GlobalShortcutsBackendMate(GlobalShortcutsManager *manager, QObject *parent) - : GlobalShortcutsBackend(manager, parent), + : GlobalShortcutsBackend(manager, GlobalShortcutsBackend::Type_Mate, parent), interface_(nullptr), is_connected_(false) {} -bool GlobalShortcutsBackendMate::IsAvailable() { +bool GlobalShortcutsBackendMate::IsAvailable() const { + + return IsMateAvailable(); + +} + +bool GlobalShortcutsBackendMate::IsMateAvailable() { return QDBusConnection::sessionBus().interface()->isServiceRegistered(kService1) || QDBusConnection::sessionBus().interface()->isServiceRegistered(kService2); diff --git a/src/globalshortcuts/globalshortcutsbackend-mate.h b/src/globalshortcuts/globalshortcutsbackend-mate.h index c801c6af8..a9abc301e 100644 --- a/src/globalshortcuts/globalshortcutsbackend-mate.h +++ b/src/globalshortcuts/globalshortcutsbackend-mate.h @@ -37,7 +37,8 @@ class GlobalShortcutsBackendMate : public GlobalShortcutsBackend { public: explicit GlobalShortcutsBackendMate(GlobalShortcutsManager *manager, QObject *parent = nullptr); - bool IsAvailable() override; + bool IsAvailable() const override; + static bool IsMateAvailable(); protected: bool DoRegister() override; diff --git a/src/globalshortcuts/globalshortcutsbackend-system.cpp b/src/globalshortcuts/globalshortcutsbackend-win.cpp similarity index 76% rename from src/globalshortcuts/globalshortcutsbackend-system.cpp rename to src/globalshortcuts/globalshortcutsbackend-win.cpp index 443824586..204396a83 100644 --- a/src/globalshortcuts/globalshortcutsbackend-system.cpp +++ b/src/globalshortcuts/globalshortcutsbackend-win.cpp @@ -19,7 +19,7 @@ #include "config.h" -#include "globalshortcutsbackend-system.h" +#include "globalshortcutsbackend-win.h" #include "core/logging.h" @@ -33,13 +33,19 @@ #include "globalshortcutsbackend.h" #include "globalshortcut.h" -GlobalShortcutsBackendSystem::GlobalShortcutsBackendSystem(GlobalShortcutsManager *manager, QObject *parent) - : GlobalShortcutsBackend(manager, parent), +GlobalShortcutsBackendWin::GlobalShortcutsBackendWin(GlobalShortcutsManager *manager, QObject *parent) + : GlobalShortcutsBackend(manager, GlobalShortcutsBackend::Type_Win, parent), gshortcut_init_(nullptr) {} -GlobalShortcutsBackendSystem::~GlobalShortcutsBackendSystem() { GlobalShortcutsBackendSystem::DoUnregister(); } +GlobalShortcutsBackendWin::~GlobalShortcutsBackendWin() { + GlobalShortcutsBackendWin::DoUnregister(); +} -bool GlobalShortcutsBackendSystem::DoRegister() { +bool GlobalShortcutsBackendWin::IsAvailable() const { + return true; +} + +bool GlobalShortcutsBackendWin::DoRegister() { qLog(Debug) << "Registering"; @@ -54,7 +60,7 @@ bool GlobalShortcutsBackendSystem::DoRegister() { } -bool GlobalShortcutsBackendSystem::AddShortcut(QAction *action) { +bool GlobalShortcutsBackendWin::AddShortcut(QAction *action) { if (action->shortcut().isEmpty()) return false; @@ -65,7 +71,7 @@ bool GlobalShortcutsBackendSystem::AddShortcut(QAction *action) { } -void GlobalShortcutsBackendSystem::DoUnregister() { +void GlobalShortcutsBackendWin::DoUnregister() { qLog(Debug) << "Unregistering"; diff --git a/src/globalshortcuts/globalshortcutsbackend-system.h b/src/globalshortcuts/globalshortcutsbackend-win.h similarity index 74% rename from src/globalshortcuts/globalshortcutsbackend-system.h rename to src/globalshortcuts/globalshortcutsbackend-win.h index cb8492323..a00a41ab2 100644 --- a/src/globalshortcuts/globalshortcutsbackend-system.h +++ b/src/globalshortcuts/globalshortcutsbackend-win.h @@ -17,13 +17,11 @@ * */ -#ifndef GLOBALSHORTCUTSBACKEND_SYSTEM_H -#define GLOBALSHORTCUTSBACKEND_SYSTEM_H +#ifndef GLOBALSHORTCUTSBACKEND_WIN_H +#define GLOBALSHORTCUTSBACKEND_WIN_H #include "config.h" -#include "core/logging.h" - #include #include #include @@ -34,14 +32,14 @@ class QAction; class GlobalShortcutsManager; class GlobalShortcut; -class GlobalShortcutsBackendSystem : public GlobalShortcutsBackend { +class GlobalShortcutsBackendWin : public GlobalShortcutsBackend { Q_OBJECT public: - explicit GlobalShortcutsBackendSystem(GlobalShortcutsManager *manager, QObject *parent = nullptr); - ~GlobalShortcutsBackendSystem() override; + explicit GlobalShortcutsBackendWin(GlobalShortcutsManager *manager, QObject *parent = nullptr); + ~GlobalShortcutsBackendWin() override; - bool IsAvailable() override { return true; } + bool IsAvailable() const override; protected: bool DoRegister() override; @@ -56,4 +54,4 @@ class GlobalShortcutsBackendSystem : public GlobalShortcutsBackend { }; -#endif // GLOBALSHORTCUTSBACKEND_SYSTEM_H +#endif // GLOBALSHORTCUTSBACKEND_WIN_H diff --git a/src/globalshortcuts/globalshortcutsbackend-x11.cpp b/src/globalshortcuts/globalshortcutsbackend-x11.cpp new file mode 100644 index 000000000..d9d6bf359 --- /dev/null +++ b/src/globalshortcuts/globalshortcutsbackend-x11.cpp @@ -0,0 +1,91 @@ +/* + * Strawberry Music Player + * Copyright 2018-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 "globalshortcutsbackend-x11.h" + +#include "core/logging.h" + +#include +#include +#include +#include +#include +#include + +#include "globalshortcutsmanager.h" +#include "globalshortcutsbackend.h" +#include "globalshortcut.h" + +GlobalShortcutsBackendX11::GlobalShortcutsBackendX11(GlobalShortcutsManager *manager, QObject *parent) + : GlobalShortcutsBackend(manager, GlobalShortcutsBackend::Type_X11, parent), + gshortcut_init_(nullptr) {} + +GlobalShortcutsBackendX11::~GlobalShortcutsBackendX11() { GlobalShortcutsBackendX11::DoUnregister(); } + +bool GlobalShortcutsBackendX11::IsAvailable() const { + return IsX11Available(); +} + +bool GlobalShortcutsBackendX11::IsX11Available() { + + return QApplication::platformName() == "xcb"; + +} + +bool GlobalShortcutsBackendX11::DoRegister() { + + qLog(Debug) << "Registering"; + + if (!gshortcut_init_) gshortcut_init_ = new GlobalShortcut(this); + + QList shortcuts = manager_->shortcuts().values(); + for (const GlobalShortcutsManager::Shortcut &shortcut : shortcuts) { + AddShortcut(shortcut.action); + } + + return true; + +} + +bool GlobalShortcutsBackendX11::AddShortcut(QAction *action) { + + if (action->shortcut().isEmpty()) return false; + + GlobalShortcut *shortcut = new GlobalShortcut(action->shortcut(), this, this); + QObject::connect(shortcut, &GlobalShortcut::activated, action, &QAction::trigger); + shortcuts_ << shortcut; + return true; + +} + +void GlobalShortcutsBackendX11::DoUnregister() { + + qLog(Debug) << "Unregistering"; + + qDeleteAll(shortcuts_); + shortcuts_.clear(); + + if (gshortcut_init_) { + delete gshortcut_init_; + gshortcut_init_ = nullptr; + } + +} diff --git a/src/globalshortcuts/globalshortcutsbackend-x11.h b/src/globalshortcuts/globalshortcutsbackend-x11.h new file mode 100644 index 000000000..a2d1ce0cc --- /dev/null +++ b/src/globalshortcuts/globalshortcutsbackend-x11.h @@ -0,0 +1,58 @@ +/* + * Strawberry Music Player + * Copyright 2018-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_X11_H +#define GLOBALSHORTCUTSBACKEND_X11_H + +#include "config.h" + +#include +#include +#include + +#include "globalshortcutsbackend.h" + +class QAction; +class GlobalShortcutsManager; +class GlobalShortcut; + +class GlobalShortcutsBackendX11 : public GlobalShortcutsBackend { + Q_OBJECT + + public: + explicit GlobalShortcutsBackendX11(GlobalShortcutsManager *manager, QObject *parent = nullptr); + ~GlobalShortcutsBackendX11() override; + + bool IsAvailable() const override; + static bool IsX11Available(); + + protected: + bool DoRegister() override; + void DoUnregister() override; + + private: + bool AddShortcut(QAction *action); + bool RemoveShortcut(QAction *action); + + QList shortcuts_; + GlobalShortcut *gshortcut_init_; + +}; + +#endif // GLOBALSHORTCUTSBACKEND_X11_H diff --git a/src/globalshortcuts/globalshortcutsbackend.cpp b/src/globalshortcuts/globalshortcutsbackend.cpp index 7a65c7f37..6ef1165fe 100644 --- a/src/globalshortcuts/globalshortcutsbackend.cpp +++ b/src/globalshortcuts/globalshortcutsbackend.cpp @@ -25,18 +25,46 @@ #include "globalshortcutsbackend.h" #include "globalshortcutsmanager.h" -GlobalShortcutsBackend::GlobalShortcutsBackend(GlobalShortcutsManager *manager, QObject *parent) +GlobalShortcutsBackend::GlobalShortcutsBackend(GlobalShortcutsManager *manager, const Type type, QObject *parent) : QObject(parent), manager_(manager), + type_(type), active_(false) {} +QString GlobalShortcutsBackend::name() const { + + switch(type_) { + case Type_None: + return "None"; + case Type_KDE: + return "KDE"; + case Type_Gnome: + return "Gnome"; + case Type_Mate: + return "Mate"; + case Type_X11: + return "X11"; + case Type_MacOS: + return "macOS"; + case Type_Win: + return "Windows"; + } + + return QString(); + +} + bool GlobalShortcutsBackend::Register() { + bool ret = DoRegister(); if (ret) active_ = true; return ret; + } void GlobalShortcutsBackend::Unregister() { + DoUnregister(); active_ = false; + } diff --git a/src/globalshortcuts/globalshortcutsbackend.h b/src/globalshortcuts/globalshortcutsbackend.h index f119bc7dc..a07795ea0 100644 --- a/src/globalshortcuts/globalshortcutsbackend.h +++ b/src/globalshortcuts/globalshortcutsbackend.h @@ -32,14 +32,27 @@ class GlobalShortcutsBackend : public QObject { Q_OBJECT public: - explicit GlobalShortcutsBackend(GlobalShortcutsManager *manager, QObject *parent = nullptr); + enum Type { + Type_None = 0, + Type_KDE, + Type_Gnome, + Type_Mate, + Type_X11, + Type_MacOS, + Type_Win + }; - bool is_active() const { return active_; } + explicit GlobalShortcutsBackend(GlobalShortcutsManager *manager, const Type type, QObject *parent = nullptr); + + bool type() const { return type_; } + QString name() const; + + virtual bool IsAvailable() const = 0; bool Register(); void Unregister(); - virtual bool IsAvailable() = 0; + bool is_active() const { return active_; } signals: void RegisterFinished(bool success); @@ -49,6 +62,7 @@ class GlobalShortcutsBackend : public QObject { virtual void DoUnregister() = 0; GlobalShortcutsManager *manager_; + Type type_; bool active_; }; diff --git a/src/globalshortcuts/globalshortcutsmanager.cpp b/src/globalshortcuts/globalshortcutsmanager.cpp index 7adbdeae7..b366ea0e9 100644 --- a/src/globalshortcuts/globalshortcutsmanager.cpp +++ b/src/globalshortcuts/globalshortcutsmanager.cpp @@ -30,37 +30,32 @@ #include #include #include -#ifdef HAVE_DBUS -# include -#endif +#include #include "globalshortcutsmanager.h" #include "globalshortcutsbackend.h" -#ifdef HAVE_DBUS +#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) && defined(HAVE_DBUS) # include "globalshortcutsbackend-kde.h" # include "globalshortcutsbackend-gnome.h" # include "globalshortcutsbackend-mate.h" #endif -#if defined(HAVE_X11_GLOBALSHORTCUTS) || defined(Q_OS_WIN) -# include "globalshortcutsbackend-system.h" + +#ifdef HAVE_X11_GLOBALSHORTCUTS +# include "globalshortcutsbackend-x11.h" #endif + +#ifdef Q_OS_WIN +# include "globalshortcutsbackend-win.h" +#endif + #ifdef Q_OS_MACOS # include "globalshortcutsbackend-macos.h" #endif #include "settings/globalshortcutssettingspage.h" -GlobalShortcutsManager::GlobalShortcutsManager(QWidget *parent) - : QWidget(parent), - kde_backend_(nullptr), - gnome_backend_(nullptr), - mate_backend_(nullptr), - system_backend_(nullptr), - use_kde_(true), - use_gnome_(true), - use_mate_(true), - use_x11_(false) { +GlobalShortcutsManager::GlobalShortcutsManager(QWidget *parent) : QWidget(parent) { settings_.beginGroup(GlobalShortcutsSettingsPage::kSettingsGroup); @@ -86,26 +81,23 @@ GlobalShortcutsManager::GlobalShortcutsManager(QWidget *parent) AddShortcut("love", "Love", std::bind(&GlobalShortcutsManager::Love, this)); // Create backends - these do the actual shortcut registration -#ifdef HAVE_DBUS - kde_backend_ = new GlobalShortcutsBackendKDE(this, this); - gnome_backend_ = new GlobalShortcutsBackendGnome(this, this); - mate_backend_ = new GlobalShortcutsBackendMate(this, this); + +#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) && defined(HAVE_DBUS) + backends_ << new GlobalShortcutsBackendKDE(this, this); + backends_ << new GlobalShortcutsBackendGnome(this, this); + backends_ << new GlobalShortcutsBackendMate(this, this); #endif #ifdef Q_OS_MACOS - if (!system_backend_) { - system_backend_ = new GlobalShortcutsBackendMacOS(this, this); - } + backends_ << new GlobalShortcutsBackendMacOS(this, this); #endif + #ifdef Q_OS_WIN - if (!system_backend_) { - system_backend_ = new GlobalShortcutsBackendSystem(this, this); - } + backends_ << new GlobalShortcutsBackendWin(this, this); #endif + #ifdef HAVE_X11_GLOBALSHORTCUTS - if (!system_backend_ && IsX11Available()) { - system_backend_ = new GlobalShortcutsBackendSystem(this, this); - } + backends_ << new GlobalShortcutsBackendX11(this, this); #endif ReloadSettings(); @@ -114,11 +106,35 @@ 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_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(); + backends_enabled_.clear(); + +#ifdef Q_OS_MACOS + backends_enabled_ << GlobalShortcutsBackend::Type_MacOS; +#endif + +#ifdef Q_OS_WIN + backends_enabled_ << GlobalShortcutsBackend::Type_Win; +#endif + + settings_.beginGroup(GlobalShortcutsSettingsPage::kSettingsGroup); + +#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) && defined(HAVE_DBUS) + if (settings_.value("use_kde", true).toBool()) { + backends_enabled_ << GlobalShortcutsBackend::Type_KDE; + } + if (settings_.value("use_gnome", true).toBool()) { + backends_enabled_ << GlobalShortcutsBackend::Type_Gnome; + } + if (settings_.value("use_mate", true).toBool()) { + backends_enabled_ << GlobalShortcutsBackend::Type_Mate; + } +#endif + +#ifdef HAVE_X11_GLOBALSHORTCUTS + if (settings_.value("use_x11", false).toBool()) { + backends_enabled_ << GlobalShortcutsBackend::Type_X11; + } +#endif Unregister(); Register(); @@ -151,80 +167,75 @@ GlobalShortcutsManager::Shortcut GlobalShortcutsManager::AddShortcut(const QStri } -bool GlobalShortcutsManager::IsKdeAvailable() const { +#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) && defined(HAVE_DBUS) -#ifdef HAVE_DBUS - return kde_backend_->IsAvailable(); -#else - return false; -#endif +bool GlobalShortcutsManager::IsKdeAvailable() { + + return GlobalShortcutsBackendKDE::IsKDEAvailable(); } -bool GlobalShortcutsManager::IsGnomeAvailable() const { +bool GlobalShortcutsManager::IsGnomeAvailable() { -#ifdef HAVE_DBUS - return gnome_backend_->IsAvailable(); -#else - return false; -#endif + return GlobalShortcutsBackendGnome::IsGnomeAvailable(); } -bool GlobalShortcutsManager::IsMateAvailable() const { +bool GlobalShortcutsManager::IsMateAvailable() { -#ifdef HAVE_DBUS - return mate_backend_->IsAvailable(); -#else - return false; -#endif + return GlobalShortcutsBackendMate::IsMateAvailable(); } +# endif // defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) && defined(HAVE_DBUS) + +#ifdef HAVE_X11_GLOBALSHORTCUTS + bool GlobalShortcutsManager::IsX11Available() { - return QApplication::platformName() == "xcb"; + return GlobalShortcutsBackendX11::IsX11Available(); } -void GlobalShortcutsManager::Register() { +#endif // HAVE_X11_GLOBALSHORTCUTS - 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; +bool GlobalShortcutsManager::Register() { -#ifdef HAVE_X11_GLOBALSHORTCUTS - if (use_x11_) { -#endif - if (system_backend_) { - system_backend_->Register(); + for (GlobalShortcutsBackend *backend : backends_) { + if (backend && backend->IsAvailable() && !backend->is_active() && backends_enabled_.contains(backend->type())) { + qLog(Info) << "Using" << backend->name() << "backend for global shortcuts."; + return backend->Register(); } -#ifdef HAVE_X11_GLOBALSHORTCUTS - } -#endif + } + + return false; } void GlobalShortcutsManager::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(); + for (GlobalShortcutsBackend *backend : backends_) { + if (backend && backend->is_active()) { + backend->Unregister(); + } + } } -bool GlobalShortcutsManager::IsMacAccessibilityEnabled() const { #ifdef Q_OS_MACOS - if (system_backend_) return qobject_cast(system_backend_)->IsAccessibilityEnabled(); - else return false; -#else - return true; -#endif + +bool GlobalShortcutsManager::IsMacAccessibilityEnabled() { + + return GlobalShortcutsBackendMacOS::IsAccessibilityEnabled(); + } -void GlobalShortcutsManager::ShowMacAccessibilityDialog() const { +#endif // Q_OS_MACOS + +void GlobalShortcutsManager::ShowMacAccessibilityDialog() { + #ifdef Q_OS_MACOS - if (system_backend_) qobject_cast(system_backend_)->ShowAccessibilityDialog(); + GlobalShortcutsBackendMacOS::ShowAccessibilityDialog(); #endif + } diff --git a/src/globalshortcuts/globalshortcutsmanager.h b/src/globalshortcuts/globalshortcutsmanager.h index f38b04b78..2787f8a09 100644 --- a/src/globalshortcuts/globalshortcutsmanager.h +++ b/src/globalshortcuts/globalshortcutsmanager.h @@ -28,14 +28,16 @@ #include #include +#include #include #include #include #include +#include "globalshortcutsbackend.h" + class QShortcut; class QAction; -class GlobalShortcutsBackend; class GlobalShortcutsManager : public QWidget { Q_OBJECT @@ -51,18 +53,27 @@ class GlobalShortcutsManager : public QWidget { }; QMap shortcuts() const { return shortcuts_; } - bool IsKdeAvailable() const; + +#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) && defined(HAVE_DBUS) + static bool IsKdeAvailable(); + static bool IsGnomeAvailable(); + static bool IsMateAvailable(); +#endif // defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) && defined(HAVE_DBUS) + +#ifdef HAVE_X11_GLOBALSHORTCUTS static bool IsX11Available(); - bool IsGnomeAvailable() const; - bool IsMateAvailable() const; - bool IsMacAccessibilityEnabled() const; +#endif // HAVE_X11_GLOBALSHORTCUTS + +#ifdef Q_OS_MACOS + static bool IsMacAccessibilityEnabled(); +#endif // Q_OS_MACOS + + bool Register(); + void Unregister(); public slots: void ReloadSettings(); - void ShowMacAccessibilityDialog() const; - - void Unregister(); - void Register(); + void ShowMacAccessibilityDialog(); signals: void Play(); @@ -91,18 +102,10 @@ class GlobalShortcutsManager : public QWidget { Shortcut AddShortcut(const QString &id, const QString &name, const QKeySequence &default_key); private: - GlobalShortcutsBackend *kde_backend_; - GlobalShortcutsBackend *gnome_backend_; - GlobalShortcutsBackend *mate_backend_; - GlobalShortcutsBackend *system_backend_; - - QMap shortcuts_; + QList backends_; QSettings settings_; - - bool use_kde_; - bool use_gnome_; - bool use_mate_; - bool use_x11_; + QList backends_enabled_; + QMap shortcuts_; }; #endif // GLOBALSHORTCUTSMANAGER_H diff --git a/src/settings/globalshortcutssettingspage.cpp b/src/settings/globalshortcutssettingspage.cpp index 51dd09b9b..00e466746 100644 --- a/src/settings/globalshortcutssettingspage.cpp +++ b/src/settings/globalshortcutssettingspage.cpp @@ -42,9 +42,6 @@ #include "core/iconloader.h" #include "core/logging.h" #include "core/utilities.h" -#ifdef Q_OS_MACOS -# include "core/mac_utilities.h" -#endif #include "globalshortcuts/globalshortcutgrabber.h" #include "globalshortcuts/globalshortcutsmanager.h" #include "settingspage.h" @@ -71,41 +68,32 @@ GlobalShortcutsSettingsPage::GlobalShortcutsSettingsPage(SettingsDialog *dialog, QObject::connect(ui_->radio_custom, &QRadioButton::clicked, this, &GlobalShortcutsSettingsPage::ChangeClicked); QObject::connect(ui_->button_change, &QPushButton::clicked, this, &GlobalShortcutsSettingsPage::ChangeClicked); -#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) -# ifdef HAVE_DBUS +#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) && defined(HAVE_DBUS) QObject::connect(ui_->checkbox_kde, &QCheckBox::toggled, this, &GlobalShortcutsSettingsPage::ShortcutOptionsChanged); 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 -# ifdef HAVE_X11_GLOBALSHORTCUTS - QObject::connect(ui_->checkbox_x11, &QCheckBox::toggled, this, &GlobalShortcutsSettingsPage::ShortcutOptionsChanged); -# endif #else ui_->widget_kde->hide(); ui_->widget_gnome->hide(); ui_->widget_mate->hide(); +#endif // defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) && defined(HAVE_DBUS) + +#ifdef HAVE_X11_GLOBALSHORTCUTS + QObject::connect(ui_->checkbox_x11, &QCheckBox::toggled, this, &GlobalShortcutsSettingsPage::ShortcutOptionsChanged); +#else ui_->widget_x11->hide(); -#endif // defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) +#endif // HAVE_X11_GLOBALSHORTCUTS + +#ifndef Q_OS_MACOS + ui_->widget_macos_access->hide(); +#endif // Q_OS_MACOS } GlobalShortcutsSettingsPage::~GlobalShortcutsSettingsPage() { delete ui_; } -bool GlobalShortcutsSettingsPage::IsEnabled() const { - -#ifdef Q_OS_MACOS - qLog(Debug) << Utilities::GetMacOsVersion(); - if (Utilities::GetMacOsVersion() < 6) { // Leopard and earlier. - return false; - } -#endif - - return true; - -} - void GlobalShortcutsSettingsPage::Load() { QSettings s; @@ -119,10 +107,13 @@ void GlobalShortcutsSettingsPage::Load() { de_ = Utilities::DesktopEnvironment(); ui_->widget_warning->hide(); - QObject::connect(ui_->button_macos_open, &QPushButton::clicked, manager, &GlobalShortcutsManager::ShowMacAccessibilityDialog); +#ifdef Q_OS_MACOS + QObject::connect(ui_->button_macos_preferences, &QPushButton::clicked, manager, &GlobalShortcutsManager::ShowMacAccessibilityDialog); +#endif -#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) - if (manager->IsKdeAvailable()) { +#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) && defined(HAVE_DBUS) + + if (GlobalShortcutsManager::IsKdeAvailable()) { qLog(Debug) << "KDE (KGlobalAccel) backend is available."; ui_->widget_kde->show(); } @@ -131,7 +122,7 @@ void GlobalShortcutsSettingsPage::Load() { ui_->widget_kde->hide(); } - if (manager->IsGnomeAvailable()) { + if (GlobalShortcutsManager::IsGnomeAvailable()) { qLog(Debug) << "Gnome (GSD) backend is available."; ui_->widget_gnome->show(); } @@ -140,7 +131,7 @@ void GlobalShortcutsSettingsPage::Load() { ui_->widget_gnome->hide(); } - if (manager->IsMateAvailable()) { + if (GlobalShortcutsManager::IsMateAvailable()) { qLog(Debug) << "MATE backend is available."; ui_->widget_mate->show(); } @@ -149,7 +140,10 @@ void GlobalShortcutsSettingsPage::Load() { ui_->widget_mate->hide(); } - if (manager->IsX11Available()) { +#endif // defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) && defined(HAVE_DBUS) + +#ifdef HAVE_X11_GLOBALSHORTCUTS + if (GlobalShortcutsManager::IsX11Available()) { qLog(Debug) << "X11 backend is available."; ui_->widget_x11->show(); } @@ -157,7 +151,7 @@ void GlobalShortcutsSettingsPage::Load() { qLog(Debug) << "X11 backend is unavailable."; ui_->widget_x11->hide(); } -#endif +#endif // HAVE_X11_GLOBALSHORTCUTS QList shortcuts = manager->shortcuts().values(); for (const GlobalShortcutsManager::Shortcut &i : shortcuts) { @@ -178,7 +172,7 @@ void GlobalShortcutsSettingsPage::Load() { SetShortcut(shortcut.s.id, shortcut.s.action->shortcut()); } -#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) +#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) && defined(HAVE_DBUS) if (ui_->widget_kde->isVisibleTo(this)) { ui_->checkbox_kde->setChecked(s.value("use_kde", true).toBool()); @@ -192,20 +186,20 @@ void GlobalShortcutsSettingsPage::Load() { ui_->checkbox_mate->setChecked(s.value("use_mate", true).toBool()); } +#endif // defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) && defined(HAVE_DBUS) + +#ifdef HAVE_X11_GLOBALSHORTCUTS if (ui_->widget_x11->isVisibleTo(this)) { ui_->checkbox_x11->setChecked(s.value("use_x11", false).toBool()); } -#endif +#endif // HAVE_X11_GLOBALSHORTCUTS -#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) +#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) && (defined(HAVE_DBUS) || defined(HAVE_X11_GLOBALSHORTCUTS)) ShortcutOptionsChanged(); #endif - ui_->widget_macos->setVisible(!manager->IsMacAccessibilityEnabled()); #ifdef Q_OS_MACOS - qint32 macos_version = Utilities::GetMacOsVersion(); - ui_->label_macos->setVisible(macos_version < 9); - ui_->label_macos_mavericks->setVisible(macos_version >= 9); + ui_->widget_macos_access->setVisible(!GlobalShortcutsManager::IsMacAccessibilityEnabled()); #endif // Q_OS_MACOS s.endGroup(); @@ -228,12 +222,15 @@ void GlobalShortcutsSettingsPage::Save() { s.setValue(shortcut.s.id, shortcut.key.toString()); } -#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) +#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) && defined(HAVE_DBUS) s.setValue("use_kde", ui_->checkbox_kde->isChecked()); s.setValue("use_gnome", ui_->checkbox_gnome->isChecked()); s.setValue("use_mate", ui_->checkbox_mate->isChecked()); +#endif // defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) && defined(HAVE_DBUS) + +#ifdef HAVE_X11_GLOBALSHORTCUTS s.setValue("use_x11", ui_->checkbox_x11->isChecked()); -#endif +#endif // HAVE_X11_GLOBALSHORTCUTS s.endGroup(); diff --git a/src/settings/globalshortcutssettingspage.h b/src/settings/globalshortcutssettingspage.h index 723e0a42f..0ec7f12c2 100644 --- a/src/settings/globalshortcutssettingspage.h +++ b/src/settings/globalshortcutssettingspage.h @@ -49,8 +49,6 @@ class GlobalShortcutsSettingsPage : public SettingsPage { static const char *kSettingsGroup; - bool IsEnabled() const override; - void Load() override; void Save() override; diff --git a/src/settings/globalshortcutssettingspage.ui b/src/settings/globalshortcutssettingspage.ui index b88a78bfb..2d86d5e09 100644 --- a/src/settings/globalshortcutssettingspage.ui +++ b/src/settings/globalshortcutssettingspage.ui @@ -156,6 +156,18 @@ + + 0 + + + 0 + + + 0 + + + 0 + @@ -210,11 +222,8 @@ - + - - 0 - 0 @@ -228,23 +237,41 @@ 0 - + 0 0 - - You need to launch System Preferences and turn on "<span style=" font-style:italic;">Enable access for assistive devices</span>" to use global shortcuts in Strawberry. + + + 48 + 48 + - - true + + + 48 + 48 + + + + + 64 + 64 + + + + + + + :/icons/48x48/dialog-warning.png - + 0 @@ -260,7 +287,7 @@ - + Open... @@ -360,7 +387,7 @@ checkbox_gnome button_gnome_open checkbox_x11 - button_macos_open + button_macos_preferences list radio_none radio_default