diff options
author | Robert Adam <dev@robert-adam.de> | 2022-07-29 20:48:50 +0300 |
---|---|---|
committer | Robert Adam <dev@robert-adam.de> | 2022-07-31 18:32:59 +0300 |
commit | 5d09f45f0fe171085f1d204272655f17ea44ce97 (patch) | |
tree | 6c6e0100cd6bc1924a750849021b8d71052e89b0 | |
parent | 49cc697c07e71c86484e3594fbb961a11787abcd (diff) |
FEAT(client, unix): Make shortcuts disablable
Previously the shortcut engine on Unix could not be disabled. Therefore,
the bEnableShortcut setting effectively had no effect on these systems,
making the change of its default value on Wayland (in order to prevent
CPU intensive polling) as done in 13c7ff5dd394d73bffde0e68fe0499ee7596ac6e
pointless.
This commit extends the engine's implementation such that it is now able
to disable shortcuts. This will automatically expose the enable shortcut
setting in the settings page. Thus, users can now explicitly re-enabled
the shortcut engine on Wayland systems.
-rw-r--r-- | src/mumble/GlobalShortcut.cpp | 2 | ||||
-rw-r--r-- | src/mumble/GlobalShortcut_unix.cpp | 81 | ||||
-rw-r--r-- | src/mumble/GlobalShortcut_unix.h | 16 |
3 files changed, 81 insertions, 18 deletions
diff --git a/src/mumble/GlobalShortcut.cpp b/src/mumble/GlobalShortcut.cpp index 23fe3a02b..b0998f20c 100644 --- a/src/mumble/GlobalShortcut.cpp +++ b/src/mumble/GlobalShortcut.cpp @@ -530,7 +530,7 @@ GlobalShortcutConfig::GlobalShortcutConfig(Settings &st) : ConfigWidget(st) { qlWaylandNote->setVisible(false); #ifdef Q_OS_LINUX if (EnvUtils::waylandIsUsed()) { - // Our global shortcut system doesn't work with Wayland + // Our global shortcut system doesn't work properly with Wayland qlWaylandNote->setVisible(true); } #endif diff --git a/src/mumble/GlobalShortcut_unix.cpp b/src/mumble/GlobalShortcut_unix.cpp index 2d3351cae..5c59f7947 100644 --- a/src/mumble/GlobalShortcut_unix.cpp +++ b/src/mumble/GlobalShortcut_unix.cpp @@ -53,6 +53,7 @@ GlobalShortcutEngine *GlobalShortcutEngine::platformInit() { GlobalShortcutX::GlobalShortcutX() { iXIopcode = -1; bRunning = false; + m_enabled = true; display = XOpenDisplay(nullptr); @@ -61,27 +62,56 @@ GlobalShortcutX::GlobalShortcutX() { return; } + init(); +} + +GlobalShortcutX::~GlobalShortcutX() { + stop(); + + if (display) { + XCloseDisplay(display); + } +} + +void GlobalShortcutX::stop() { + bRunning = false; + wait(); + + if (m_watcher) { + m_watcher->deleteLater(); + m_watcher = nullptr; + } + if (m_notifier) { + m_notifier->deleteLater(); + m_notifier = nullptr; + } +} + +bool GlobalShortcutX::init() { #ifdef Q_OS_LINUX if (Global::get().s.bEnableEvdev) { - QString dir = QLatin1String("/dev/input"); - QFileSystemWatcher *fsw = new QFileSystemWatcher(QStringList(dir), this); - connect(fsw, SIGNAL(directoryChanged(const QString &)), this, SLOT(directoryChanged(const QString &))); + QString dir = QLatin1String("/dev/input"); + m_watcher = new QFileSystemWatcher(QStringList(dir), this); + connect(m_watcher, SIGNAL(directoryChanged(const QString &)), this, SLOT(directoryChanged(const QString &))); directoryChanged(dir); if (qsKeyboards.isEmpty()) { - foreach (QFile *f, qmInputDevices) + for (QFile *f : qmInputDevices) { delete f; + } qmInputDevices.clear(); - delete fsw; + delete m_watcher; + m_watcher = nullptr; qWarning( "GlobalShortcutX: Unable to open any keyboard input devices under /dev/input, falling back to XInput"); } else { - return; + return false; } } #endif + qsRootWindows.clear(); for (int i = 0; i < ScreenCount(display); ++i) qsRootWindows.insert(RootWindow(display, i)); @@ -113,14 +143,15 @@ GlobalShortcutX::GlobalShortcutX() { evmask.mask_len = sizeof(mask); evmask.mask = mask; - foreach (Window w, qsRootWindows) + for (Window w : qsRootWindows) { XISelectEvents(display, w, &evmask, 1); + } XFlush(display); - connect(new QSocketNotifier(ConnectionNumber(display), QSocketNotifier::Read, this), SIGNAL(activated(int)), - this, SLOT(displayReadyRead(int))); + m_notifier = new QSocketNotifier(ConnectionNumber(display), QSocketNotifier::Read, this); + connect(m_notifier, SIGNAL(activated(int)), this, SLOT(displayReadyRead(int))); - return; + return true; } } #endif @@ -128,14 +159,8 @@ GlobalShortcutX::GlobalShortcutX() { "please enable one of the other methods."); bRunning = true; start(QThread::TimeCriticalPriority); -} -GlobalShortcutX::~GlobalShortcutX() { - bRunning = false; - wait(); - - if (display) - XCloseDisplay(display); + return true; } // Tight loop polling @@ -208,6 +233,28 @@ void GlobalShortcutX::queryXIMasterList() { #endif } +bool GlobalShortcutX::canDisable() { + return true; +} + +bool GlobalShortcutX::enabled() { + return m_enabled; +} + +void GlobalShortcutX::setEnabled(bool enabled) { + if (enabled == m_enabled && (enabled != bRunning)) { + return; + } + + m_enabled = enabled; + + if (!m_enabled) { + stop(); + } else { + m_enabled = init(); + } +} + // XInput2 event is ready on socketnotifier. void GlobalShortcutX::displayReadyRead(int) { #ifndef NO_XINPUT2 diff --git a/src/mumble/GlobalShortcut_unix.h b/src/mumble/GlobalShortcut_unix.h index d94185280..4e13eab8b 100644 --- a/src/mumble/GlobalShortcut_unix.h +++ b/src/mumble/GlobalShortcut_unix.h @@ -10,6 +10,7 @@ #include "Global.h" #include "GlobalShortcut.h" + #include <X11/X.h> #define NUM_BUTTONS 0x2ff @@ -17,6 +18,9 @@ struct _XDisplay; typedef _XDisplay Display; +class QFileSystemWatcher; +class QSocketNotifier; + class GlobalShortcutX : public GlobalShortcutEngine { private: Q_OBJECT @@ -37,10 +41,22 @@ public: ButtonInfo buttonInfo(const QVariant &) Q_DECL_OVERRIDE; void queryXIMasterList(); + + bool canDisable() override; + bool enabled() override; + void setEnabled(bool enabled) override; public slots: void displayReadyRead(int); void inputReadyRead(int); void directoryChanged(const QString &); + +protected: + bool m_enabled = true; + QFileSystemWatcher *m_watcher = nullptr; + QSocketNotifier *m_notifier = nullptr; + + bool init(); + void stop(); }; // These are macros that X11/X.h defines and that are causing problems in unity builds |