Unload auto-type plugins if they run in an unsupported environment.

Refs #351
This commit is contained in:
Felix Geyer 2015-09-26 12:21:22 +02:00
parent bcb54bc38a
commit 727094abc6
6 changed files with 57 additions and 16 deletions

View file

@ -79,9 +79,16 @@ void AutoType::loadPlugin(const QString& pluginPath)
QObject* pluginInstance = m_pluginLoader->instance(); QObject* pluginInstance = m_pluginLoader->instance();
if (pluginInstance) { if (pluginInstance) {
m_plugin = qobject_cast<AutoTypePlatformInterface*>(pluginInstance); m_plugin = qobject_cast<AutoTypePlatformInterface*>(pluginInstance);
m_executor = Q_NULLPTR;
if (m_plugin) { if (m_plugin) {
m_executor = m_plugin->createExecutor(); if (m_plugin->isAvailable()) {
connect(pluginInstance, SIGNAL(globalShortcutTriggered()), SIGNAL(globalShortcutTriggered())); m_executor = m_plugin->createExecutor();
connect(pluginInstance, SIGNAL(globalShortcutTriggered()), SIGNAL(globalShortcutTriggered()));
}
else {
unloadPlugin();
}
} }
} }

View file

@ -26,6 +26,7 @@ class AutoTypePlatformInterface
{ {
public: public:
virtual ~AutoTypePlatformInterface() {} virtual ~AutoTypePlatformInterface() {}
virtual bool isAvailable() = 0;
virtual QStringList windowTitles() = 0; virtual QStringList windowTitles() = 0;
virtual WId activeWindow() = 0; virtual WId activeWindow() = 0;
virtual QString activeWindowTitle() = 0; virtual QString activeWindowTitle() = 0;

View file

@ -17,6 +17,11 @@
#include "AutoTypeTest.h" #include "AutoTypeTest.h"
bool AutoTypePlatformTest::isAvailable()
{
return true;
}
QString AutoTypePlatformTest::keyToString(Qt::Key key) QString AutoTypePlatformTest::keyToString(Qt::Key key)
{ {
return QString("[Key0x%1]").arg(key, 0, 16); return QString("[Key0x%1]").arg(key, 0, 16);

View file

@ -35,6 +35,7 @@ class AutoTypePlatformTest : public QObject,
public: public:
QString keyToString(Qt::Key key) Q_DECL_OVERRIDE; QString keyToString(Qt::Key key) Q_DECL_OVERRIDE;
bool isAvailable() Q_DECL_OVERRIDE;
QStringList windowTitles() Q_DECL_OVERRIDE; QStringList windowTitles() Q_DECL_OVERRIDE;
WId activeWindow() Q_DECL_OVERRIDE; WId activeWindow() Q_DECL_OVERRIDE;
QString activeWindowTitle() Q_DECL_OVERRIDE; QString activeWindowTitle() Q_DECL_OVERRIDE;

View file

@ -57,6 +57,25 @@ AutoTypePlatformX11::AutoTypePlatformX11()
updateKeymap(); 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() void AutoTypePlatformX11::unload()
{ {
// Restore the KeyboardMapping to its original state. // Restore the KeyboardMapping to its original state.
@ -437,21 +456,10 @@ void AutoTypePlatformX11::updateKeymap()
int mod_index, mod_key; int mod_index, mod_key;
XModifierKeymap *modifiers; XModifierKeymap *modifiers;
if (m_xkb != NULL) XkbFreeKeyboard(m_xkb, XkbAllComponentsMask, True); if (m_xkb) {
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;
}
} }
m_xkb = getKeyboard();
m_xkb = XkbGetKeyboard(m_dpy, XkbCompatMapMask | XkbGeometryMask, keyboard_id);
XDisplayKeycodes(m_dpy, &m_minKeycode, &m_maxKeycode); XDisplayKeycodes(m_dpy, &m_minKeycode, &m_maxKeycode);
if (m_keysymTable != NULL) XFree(m_keysymTable); if (m_keysymTable != NULL) XFree(m_keysymTable);
@ -537,6 +545,23 @@ int AutoTypePlatformX11::x11ErrorHandler(Display* display, XErrorEvent* error)
return 1; 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. // The following code is taken from xvkbd 3.0 and has been slightly modified.
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------

View file

@ -42,6 +42,7 @@ class AutoTypePlatformX11 : public QObject, public AutoTypePlatformInterface
public: public:
AutoTypePlatformX11(); AutoTypePlatformX11();
bool isAvailable() Q_DECL_OVERRIDE;
void unload() Q_DECL_OVERRIDE; void unload() Q_DECL_OVERRIDE;
QStringList windowTitles() Q_DECL_OVERRIDE; QStringList windowTitles() Q_DECL_OVERRIDE;
WId activeWindow() Q_DECL_OVERRIDE; WId activeWindow() Q_DECL_OVERRIDE;
@ -72,6 +73,7 @@ private:
void stopCatchXErrors(); void stopCatchXErrors();
static int x11ErrorHandler(Display* display, XErrorEvent* error); static int x11ErrorHandler(Display* display, XErrorEvent* error);
XkbDescPtr getKeyboard();
void updateKeymap(); void updateKeymap();
bool isRemapKeycodeValid(); bool isRemapKeycodeValid();
int AddKeysym(KeySym keysym); int AddKeysym(KeySym keysym);