summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/windows
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@theqtcompany.com>2015-12-21 15:06:40 +0100
committerFriedemann Kleint <Friedemann.Kleint@theqtcompany.com>2016-02-25 07:17:43 +0000
commit28ee76fd0b9ce59291341c8a9937a6c98fcb926d (patch)
treecd385d6a5b771c7e88639e05cef1630bba7458e3 /src/plugins/platforms/windows
parent97965a0908b8fbf7f01d0880410929a4ea61b48d (diff)
QtPlatformHeaders/Windows: Add function to set window activation behavior.
The Windows OS by default does not activate windows when the calling process is not active; only the taskbar entry is flashed as not to distract the user. Nevertheless, for some use cases, it is desirable to activate the window also in the inactive state. Introduce an enumeration specifying the behavior to QtPlatformHeaders and employ a workaround using the Win32 API AttachThreadInput() to attach to other processes while setting the foreground window to achieve the AlwaysActivateWindow behavior. Task-number: QTBUG-14062 Task-number: QTBUG-37435 Change-Id: I79cb6cd3fab29d55b5d3db7f9af01bbaa5096a37 Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
Diffstat (limited to 'src/plugins/platforms/windows')
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeinterface.cpp5
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeinterface.h9
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp23
3 files changed, 37 insertions, 0 deletions
diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
index ac7c22fb7e..babca35149 100644
--- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
+++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
@@ -84,6 +84,9 @@ static int resourceType(const QByteArray &key)
return int(result - names);
}
+QWindowsWindowFunctions::WindowActivationBehavior QWindowsNativeInterface::m_windowActivationBehavior =
+ QWindowsWindowFunctions::DefaultActivateWindow;
+
void *QWindowsNativeInterface::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
{
if (!window || !window->handle()) {
@@ -253,6 +256,8 @@ QFunctionPointer QWindowsNativeInterface::platformFunction(const QByteArray &fun
return QFunctionPointer(QWindowsWindow::setTouchWindowTouchTypeStatic);
else if (function == QWindowsWindowFunctions::setHasBorderInFullScreenIdentifier())
return QFunctionPointer(QWindowsWindow::setHasBorderInFullScreenStatic);
+ else if (function == QWindowsWindowFunctions::setWindowActivationBehaviorIdentifier())
+ return QFunctionPointer(QWindowsNativeInterface::setWindowActivationBehavior);
return Q_NULLPTR;
}
diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.h b/src/plugins/platforms/windows/qwindowsnativeinterface.h
index 3a0d3398d9..9fc43ddcce 100644
--- a/src/plugins/platforms/windows/qwindowsnativeinterface.h
+++ b/src/plugins/platforms/windows/qwindowsnativeinterface.h
@@ -42,6 +42,7 @@
#include <QtGui/qfont.h>
#include <QtGui/qpa/qplatformnativeinterface.h>
+#include <QtPlatformHeaders/qwindowswindowfunctions.h>
QT_BEGIN_NAMESPACE
@@ -96,7 +97,15 @@ public:
QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const Q_DECL_OVERRIDE;
void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value) Q_DECL_OVERRIDE;
+ static QWindowsWindowFunctions::WindowActivationBehavior windowActivationBehavior()
+ { return QWindowsNativeInterface::m_windowActivationBehavior; }
+ static void setWindowActivationBehavior(QWindowsWindowFunctions::WindowActivationBehavior b)
+ { QWindowsNativeInterface::m_windowActivationBehavior = b; }
+
QFunctionPointer platformFunction(const QByteArray &function) const Q_DECL_OVERRIDE;
+
+private:
+ static QWindowsWindowFunctions::WindowActivationBehavior m_windowActivationBehavior;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 4c503a2c48..c1a047e276 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -43,6 +43,7 @@
#include "qwindowsdrag.h"
#include "qwindowsscreen.h"
#include "qwindowsintegration.h"
+#include "qwindowsnativeinterface.h"
#include "qwindowsopenglcontext.h"
#ifdef QT_NO_CURSOR
# include "qwindowscursor.h"
@@ -2083,8 +2084,30 @@ void QWindowsWindow::requestActivateWindow()
// 'Active' state handling is based in focus since it needs to work for
// child windows as well.
if (m_data.hwnd) {
+#ifndef Q_OS_WINCE
+ const DWORD currentThread = GetCurrentThreadId();
+ bool attached = false;
+ DWORD foregroundThread = 0;
+
+ // QTBUG-14062, QTBUG-37435: Windows normally only flashes the taskbar entry
+ // when activating windows of inactive applications. Attach to the input of the
+ // currently active window while setting the foreground window to always activate
+ // the window when desired.
+ if (QGuiApplication::applicationState() != Qt::ApplicationActive
+ && QWindowsNativeInterface::windowActivationBehavior() == QWindowsWindowFunctions::AlwaysActivateWindow) {
+ if (const HWND foregroundWindow = GetForegroundWindow()) {
+ foregroundThread = GetWindowThreadProcessId(foregroundWindow, NULL);
+ if (foregroundThread && foregroundThread != currentThread)
+ attached = AttachThreadInput(foregroundThread, currentThread, TRUE) == TRUE;
+ }
+ }
+#endif // !Q_OS_WINCE
SetForegroundWindow(m_data.hwnd);
SetFocus(m_data.hwnd);
+#ifndef Q_OS_WINCE
+ if (attached)
+ AttachThreadInput(foregroundThread, currentThread, FALSE);
+#endif // !Q_OS_WINCE
}
}