From 727094abc6305a21dec23f5c2552f4ab7dc4c5f6 Mon Sep 17 00:00:00 2001 From: Felix Geyer Date: Sat, 26 Sep 2015 12:21:22 +0200 Subject: [PATCH] Unload auto-type plugins if they run in an unsupported environment. Refs #351 --- src/autotype/AutoType.cpp | 11 +++++- src/autotype/AutoTypePlatformPlugin.h | 1 + src/autotype/test/AutoTypeTest.cpp | 5 +++ src/autotype/test/AutoTypeTest.h | 1 + src/autotype/x11/AutoTypeX11.cpp | 53 ++++++++++++++++++++------- src/autotype/x11/AutoTypeX11.h | 2 + 6 files changed, 57 insertions(+), 16 deletions(-) diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index 5c3cac065..19c8575f3 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -79,9 +79,16 @@ void AutoType::loadPlugin(const QString& pluginPath) QObject* pluginInstance = m_pluginLoader->instance(); if (pluginInstance) { m_plugin = qobject_cast(pluginInstance); + m_executor = Q_NULLPTR; + if (m_plugin) { - m_executor = m_plugin->createExecutor(); - connect(pluginInstance, SIGNAL(globalShortcutTriggered()), SIGNAL(globalShortcutTriggered())); + if (m_plugin->isAvailable()) { + m_executor = m_plugin->createExecutor(); + connect(pluginInstance, SIGNAL(globalShortcutTriggered()), SIGNAL(globalShortcutTriggered())); + } + else { + unloadPlugin(); + } } } diff --git a/src/autotype/AutoTypePlatformPlugin.h b/src/autotype/AutoTypePlatformPlugin.h index 614c8060b..dadc7a0d2 100644 --- a/src/autotype/AutoTypePlatformPlugin.h +++ b/src/autotype/AutoTypePlatformPlugin.h @@ -26,6 +26,7 @@ class AutoTypePlatformInterface { public: virtual ~AutoTypePlatformInterface() {} + virtual bool isAvailable() = 0; virtual QStringList windowTitles() = 0; virtual WId activeWindow() = 0; virtual QString activeWindowTitle() = 0; diff --git a/src/autotype/test/AutoTypeTest.cpp b/src/autotype/test/AutoTypeTest.cpp index f12014668..a8bcc71af 100644 --- a/src/autotype/test/AutoTypeTest.cpp +++ b/src/autotype/test/AutoTypeTest.cpp @@ -17,6 +17,11 @@ #include "AutoTypeTest.h" +bool AutoTypePlatformTest::isAvailable() +{ + return true; +} + QString AutoTypePlatformTest::keyToString(Qt::Key key) { return QString("[Key0x%1]").arg(key, 0, 16); diff --git a/src/autotype/test/AutoTypeTest.h b/src/autotype/test/AutoTypeTest.h index 940564166..c791c154c 100644 --- a/src/autotype/test/AutoTypeTest.h +++ b/src/autotype/test/AutoTypeTest.h @@ -35,6 +35,7 @@ class AutoTypePlatformTest : public QObject, public: QString keyToString(Qt::Key key) Q_DECL_OVERRIDE; + bool isAvailable() Q_DECL_OVERRIDE; QStringList windowTitles() Q_DECL_OVERRIDE; WId activeWindow() Q_DECL_OVERRIDE; QString activeWindowTitle() Q_DECL_OVERRIDE; diff --git a/src/autotype/x11/AutoTypeX11.cpp b/src/autotype/x11/AutoTypeX11.cpp index 98d68a163..9d5f7be48 100644 --- a/src/autotype/x11/AutoTypeX11.cpp +++ b/src/autotype/x11/AutoTypeX11.cpp @@ -57,6 +57,25 @@ AutoTypePlatformX11::AutoTypePlatformX11() updateKeymap(); } +bool AutoTypePlatformX11::isAvailable() +{ + int ignore; + + if (!XQueryExtension(m_dpy, "XInputExtension", &ignore, &ignore, &ignore)) { + return false; + } + + if (!XQueryExtension(m_dpy, "XTEST", &ignore, &ignore, &ignore)) { + return false; + } + + if (!m_xkb && !getKeyboard()) { + return false; + } + + return true; +} + void AutoTypePlatformX11::unload() { // Restore the KeyboardMapping to its original state. @@ -437,21 +456,10 @@ void AutoTypePlatformX11::updateKeymap() int mod_index, mod_key; XModifierKeymap *modifiers; - if (m_xkb != NULL) XkbFreeKeyboard(m_xkb, XkbAllComponentsMask, True); - - XDeviceInfo* devices; - int num_devices; - XID keyboard_id = XkbUseCoreKbd; - devices = XListInputDevices(m_dpy, &num_devices); - - for (int i = 0; i < num_devices; i++) { - if (QString(devices[i].name) == "Virtual core XTEST keyboard") { - keyboard_id = devices[i].id; - break; - } + if (m_xkb) { + XkbFreeKeyboard(m_xkb, XkbAllComponentsMask, True); } - - m_xkb = XkbGetKeyboard(m_dpy, XkbCompatMapMask | XkbGeometryMask, keyboard_id); + m_xkb = getKeyboard(); XDisplayKeycodes(m_dpy, &m_minKeycode, &m_maxKeycode); if (m_keysymTable != NULL) XFree(m_keysymTable); @@ -537,6 +545,23 @@ int AutoTypePlatformX11::x11ErrorHandler(Display* display, XErrorEvent* error) return 1; } +XkbDescPtr AutoTypePlatformX11::getKeyboard() +{ + XDeviceInfo* devices; + int num_devices; + XID keyboard_id = XkbUseCoreKbd; + devices = XListInputDevices(m_dpy, &num_devices); + + for (int i = 0; i < num_devices; i++) { + if (QString(devices[i].name) == "Virtual core XTEST keyboard") { + keyboard_id = devices[i].id; + break; + } + } + + return XkbGetKeyboard(m_dpy, XkbCompatMapMask | XkbGeometryMask, keyboard_id); +} + // -------------------------------------------------------------------------- // The following code is taken from xvkbd 3.0 and has been slightly modified. // -------------------------------------------------------------------------- diff --git a/src/autotype/x11/AutoTypeX11.h b/src/autotype/x11/AutoTypeX11.h index a2080a84a..99abb2308 100644 --- a/src/autotype/x11/AutoTypeX11.h +++ b/src/autotype/x11/AutoTypeX11.h @@ -42,6 +42,7 @@ class AutoTypePlatformX11 : public QObject, public AutoTypePlatformInterface public: AutoTypePlatformX11(); + bool isAvailable() Q_DECL_OVERRIDE; void unload() Q_DECL_OVERRIDE; QStringList windowTitles() Q_DECL_OVERRIDE; WId activeWindow() Q_DECL_OVERRIDE; @@ -72,6 +73,7 @@ private: void stopCatchXErrors(); static int x11ErrorHandler(Display* display, XErrorEvent* error); + XkbDescPtr getKeyboard(); void updateKeymap(); bool isRemapKeycodeValid(); int AddKeysym(KeySym keysym);