From 673dff2268a3cef5aab5d9a97505a995fd795a4c Mon Sep 17 00:00:00 2001 From: Felix Geyer Date: Mon, 21 Sep 2015 23:12:10 +0200 Subject: [PATCH] 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). --- src/autotype/AutoType.cpp | 2 ++ src/autotype/AutoTypePlatformPlugin.h | 1 + src/autotype/test/AutoTypeTest.cpp | 7 ++++++ src/autotype/test/AutoTypeTest.h | 1 + src/autotype/x11/AutoTypeX11.cpp | 35 +++++++++++++++++++++++++++ src/autotype/x11/AutoTypeX11.h | 2 ++ 6 files changed, 48 insertions(+) diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index ce68ae47..5c3cac06 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -218,6 +218,8 @@ void AutoType::performAutoTypeFromGlobal(Entry* entry, const QString& sequence) { Q_ASSERT(m_inAutoType); + m_plugin->raiseWindow(m_windowFromGlobal); + m_inAutoType = false; performAutoType(entry, Q_NULLPTR, sequence, m_windowFromGlobal); } diff --git a/src/autotype/AutoTypePlatformPlugin.h b/src/autotype/AutoTypePlatformPlugin.h index 1e78f0d2..614c8060 100644 --- a/src/autotype/AutoTypePlatformPlugin.h +++ b/src/autotype/AutoTypePlatformPlugin.h @@ -33,6 +33,7 @@ public: virtual void unregisterGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers) = 0; virtual int platformEventFilter(void* event) = 0; virtual int initialTimeout() = 0; + virtual bool raiseWindow(WId window) = 0; virtual void unload() {} virtual AutoTypeExecutor* createExecutor() = 0; diff --git a/src/autotype/test/AutoTypeTest.cpp b/src/autotype/test/AutoTypeTest.cpp index d48d17fe..f1201466 100644 --- a/src/autotype/test/AutoTypeTest.cpp +++ b/src/autotype/test/AutoTypeTest.cpp @@ -103,6 +103,13 @@ int AutoTypePlatformTest::initialTimeout() return 0; } +bool AutoTypePlatformTest::raiseWindow(WId window) +{ + Q_UNUSED(window); + + return false; +} + AutoTypeExecturorTest::AutoTypeExecturorTest(AutoTypePlatformTest* platform) : m_platform(platform) { diff --git a/src/autotype/test/AutoTypeTest.h b/src/autotype/test/AutoTypeTest.h index a39269b0..c21ff3be 100644 --- a/src/autotype/test/AutoTypeTest.h +++ b/src/autotype/test/AutoTypeTest.h @@ -42,6 +42,7 @@ public: void unregisterGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers); int platformEventFilter(void* event); int initialTimeout(); + bool raiseWindow(WId window); AutoTypeExecutor* createExecutor(); void setActiveWindowTitle(const QString& title); diff --git a/src/autotype/x11/AutoTypeX11.cpp b/src/autotype/x11/AutoTypeX11.cpp index 876be3fd..87000222 100644 --- a/src/autotype/x11/AutoTypeX11.cpp +++ b/src/autotype/x11/AutoTypeX11.cpp @@ -35,6 +35,7 @@ AutoTypePlatformX11::AutoTypePlatformX11() m_atomNetWmName = XInternAtom(m_dpy, "_NET_WM_NAME", true); m_atomString = XInternAtom(m_dpy, "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 << "kdesktop" << "kicker"; // KDE 3 @@ -770,4 +771,38 @@ int AutoTypePlatformX11::initialTimeout() 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) diff --git a/src/autotype/x11/AutoTypeX11.h b/src/autotype/x11/AutoTypeX11.h index 1fa45503..a1d6e9ff 100644 --- a/src/autotype/x11/AutoTypeX11.h +++ b/src/autotype/x11/AutoTypeX11.h @@ -50,6 +50,7 @@ public: void unregisterGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers); int platformEventFilter(void* event); int initialTimeout(); + bool raiseWindow(WId window); AutoTypeExecutor* createExecutor(); KeySym charToKeySym(const QChar& ch); @@ -89,6 +90,7 @@ private: Atom m_atomNetWmName; Atom m_atomString; Atom m_atomUtf8String; + Atom m_atomNetActiveWindow; QSet m_classBlacklist; Qt::Key m_currentGlobalKey; Qt::KeyboardModifiers m_currentGlobalModifiers;