Auto-Type: Raise target window after showing the select dialog.

kwin >= 5.4 (since commit cfa1d61) prefers to focus the main window
instead of following the focus chain.

We ask the window manager nicely to focus the window we want to
type into. kwin seems to follow that (in the default configuration).
This commit is contained in:
Felix Geyer 2015-09-21 23:12:10 +02:00
parent bb38be40f6
commit 673dff2268
6 changed files with 48 additions and 0 deletions

View File

@ -218,6 +218,8 @@ void AutoType::performAutoTypeFromGlobal(Entry* entry, const QString& sequence)
{ {
Q_ASSERT(m_inAutoType); Q_ASSERT(m_inAutoType);
m_plugin->raiseWindow(m_windowFromGlobal);
m_inAutoType = false; m_inAutoType = false;
performAutoType(entry, Q_NULLPTR, sequence, m_windowFromGlobal); performAutoType(entry, Q_NULLPTR, sequence, m_windowFromGlobal);
} }

View File

@ -33,6 +33,7 @@ public:
virtual void unregisterGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers) = 0; virtual void unregisterGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers) = 0;
virtual int platformEventFilter(void* event) = 0; virtual int platformEventFilter(void* event) = 0;
virtual int initialTimeout() = 0; virtual int initialTimeout() = 0;
virtual bool raiseWindow(WId window) = 0;
virtual void unload() {} virtual void unload() {}
virtual AutoTypeExecutor* createExecutor() = 0; virtual AutoTypeExecutor* createExecutor() = 0;

View File

@ -103,6 +103,13 @@ int AutoTypePlatformTest::initialTimeout()
return 0; return 0;
} }
bool AutoTypePlatformTest::raiseWindow(WId window)
{
Q_UNUSED(window);
return false;
}
AutoTypeExecturorTest::AutoTypeExecturorTest(AutoTypePlatformTest* platform) AutoTypeExecturorTest::AutoTypeExecturorTest(AutoTypePlatformTest* platform)
: m_platform(platform) : m_platform(platform)
{ {

View File

@ -42,6 +42,7 @@ public:
void unregisterGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers); void unregisterGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers);
int platformEventFilter(void* event); int platformEventFilter(void* event);
int initialTimeout(); int initialTimeout();
bool raiseWindow(WId window);
AutoTypeExecutor* createExecutor(); AutoTypeExecutor* createExecutor();
void setActiveWindowTitle(const QString& title); void setActiveWindowTitle(const QString& title);

View File

@ -35,6 +35,7 @@ AutoTypePlatformX11::AutoTypePlatformX11()
m_atomNetWmName = XInternAtom(m_dpy, "_NET_WM_NAME", true); m_atomNetWmName = XInternAtom(m_dpy, "_NET_WM_NAME", true);
m_atomString = XInternAtom(m_dpy, "STRING", true); m_atomString = XInternAtom(m_dpy, "STRING", true);
m_atomUtf8String = XInternAtom(m_dpy, "UTF8_STRING", true); m_atomUtf8String = XInternAtom(m_dpy, "UTF8_STRING", true);
m_atomNetActiveWindow = XInternAtom(m_dpy, "_NET_ACTIVE_WINDOW", true);
m_classBlacklist << "desktop_window" << "gnome-panel"; // Gnome m_classBlacklist << "desktop_window" << "gnome-panel"; // Gnome
m_classBlacklist << "kdesktop" << "kicker"; // KDE 3 m_classBlacklist << "kdesktop" << "kicker"; // KDE 3
@ -770,4 +771,38 @@ int AutoTypePlatformX11::initialTimeout()
return 500; return 500;
} }
bool AutoTypePlatformX11::raiseWindow(WId window)
{
if (m_atomNetActiveWindow == None) {
return false;
}
XRaiseWindow(m_dpy, window);
XEvent event;
event.xclient.type = ClientMessage;
event.xclient.serial = 0;
event.xclient.send_event = True;
event.xclient.window = window;
event.xclient.message_type = m_atomNetActiveWindow;
event.xclient.format = 32;
event.xclient.data.l[0] = 1; // FromApplication
event.xclient.data.l[1] = QX11Info::appUserTime();
QWidget* activeWindow = QApplication::activeWindow();
if (activeWindow) {
event.xclient.data.l[2] = activeWindow->internalWinId();
}
else {
event.xclient.data.l[2] = 0;
}
event.xclient.data.l[3] = 0;
event.xclient.data.l[4] = 0;
XSendEvent(m_dpy, m_rootWindow, False,
SubstructureRedirectMask | SubstructureNotifyMask,
&event);
XFlush(m_dpy);
return true;
}
Q_EXPORT_PLUGIN2(keepassx-autotype-x11, AutoTypePlatformX11) Q_EXPORT_PLUGIN2(keepassx-autotype-x11, AutoTypePlatformX11)

View File

@ -50,6 +50,7 @@ public:
void unregisterGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers); void unregisterGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers);
int platformEventFilter(void* event); int platformEventFilter(void* event);
int initialTimeout(); int initialTimeout();
bool raiseWindow(WId window);
AutoTypeExecutor* createExecutor(); AutoTypeExecutor* createExecutor();
KeySym charToKeySym(const QChar& ch); KeySym charToKeySym(const QChar& ch);
@ -89,6 +90,7 @@ private:
Atom m_atomNetWmName; Atom m_atomNetWmName;
Atom m_atomString; Atom m_atomString;
Atom m_atomUtf8String; Atom m_atomUtf8String;
Atom m_atomNetActiveWindow;
QSet<QString> m_classBlacklist; QSet<QString> m_classBlacklist;
Qt::Key m_currentGlobalKey; Qt::Key m_currentGlobalKey;
Qt::KeyboardModifiers m_currentGlobalModifiers; Qt::KeyboardModifiers m_currentGlobalModifiers;