summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2012-06-18 17:26:30 +0300
committerQt by Nokia <qt-info@nokia.com>2012-07-03 14:50:34 +0200
commit8368557b9c0010fb205969d010c9d8549fbee0ae (patch)
treeaa6a572b368c8084554ac84097925779346b433d /src
parent6b5bbc531b30d8ece25425e39843c6ae1af1d045 (diff)
Fix focus handling when the application has QAxWidgets.
Removed old defunct platform specific code from QWidget::isActiveWindow() and added call to QPlatformWindow::isActive() instead. This is done because the embedded native windows inside QAxWidgets can have focus but are not part of the parent application's Qt window hierarchy, so native methods are required to determine if they are part of the active window or not. QWidgetPrivate::setFocus_sys() was implemented to activate the window of the focused widget if the focus was elsewhere. This is required because embedded native windows can steal the focus from the main application window. Focus event handling in Windows platform adaptation plugin was fixed to correctly identify the active window in cases where the are embedded native widgets that can have focus. Also fixed three test cases that were affected by these changes. Task-number: QTBUG-25852 Task-number: QTBUG-23699 Change-Id: I817e0ce4317e88955bb49b034eacd630a876ccf0 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp20
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.h1
-rw-r--r--src/widgets/kernel/qwidget.cpp28
-rw-r--r--src/widgets/kernel/qwidget_qpa.cpp9
4 files changed, 38 insertions, 20 deletions
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 92c92676bb..2c9750a327 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -551,6 +551,22 @@ QWindowsWindow *QWindowsContext::findPlatformWindow(HWND hwnd) const
return d->m_windows.value(hwnd);
}
+QWindowsWindow *QWindowsContext::findClosestPlatformWindow(HWND hwnd) const
+{
+ QWindowsWindow *window = d->m_windows.value(hwnd);
+
+ // Requested hwnd may also be a child of a platform window in case of embedded native windows.
+ // Find the closest parent that has a platform window.
+ if (!window) {
+ for (HWND w = hwnd; w; w = GetParent(w)) {
+ if (window = d->m_windows.value(w))
+ return window;
+ }
+ }
+
+ return window;
+}
+
QWindow *QWindowsContext::findWindow(HWND hwnd) const
{
if (const QWindowsWindow *bw = findPlatformWindow(hwnd))
@@ -871,8 +887,8 @@ void QWindowsContext::handleFocusEvent(QtWindows::WindowsEventType et,
} else {
// Focus out: Is the next window known and different
// from the receiving the focus out.
- if (const HWND nextActiveHwnd = GetActiveWindow())
- if (QWindowsWindow *nextActivePlatformWindow = findPlatformWindow(nextActiveHwnd))
+ if (const HWND nextActiveHwnd = GetFocus())
+ if (QWindowsWindow *nextActivePlatformWindow = findClosestPlatformWindow(nextActiveHwnd))
if (nextActivePlatformWindow != platformWindow)
nextActiveWindow = nextActivePlatformWindow->window();
}
diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h
index 4b221bdba3..e95ea7f3f4 100644
--- a/src/plugins/platforms/windows/qwindowscontext.h
+++ b/src/plugins/platforms/windows/qwindowscontext.h
@@ -152,6 +152,7 @@ public:
void addWindow(HWND, QWindowsWindow *w);
void removeWindow(HWND);
+ QWindowsWindow *findClosestPlatformWindow(HWND) const;
QWindowsWindow *findPlatformWindow(HWND) const;
QWindow *findWindow(HWND) const;
QWindowsWindow *findPlatformWindowAt(HWND parent, const QPoint &screenPoint,
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 2fcf3e457c..8d57be1c42 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -6207,16 +6207,6 @@ bool QWidget::isActiveWindow() const
}
#endif
-#ifdef Q_WS_MAC
- extern bool qt_mac_is_macdrawer(const QWidget *); //qwidget_mac.cpp
- if(qt_mac_is_macdrawer(tlw) &&
- tlw->parentWidget() && tlw->parentWidget()->isActiveWindow())
- return true;
-
- extern bool qt_mac_insideKeyWindow(const QWidget *); //qwidget_mac.cpp
- if (QApplication::testAttribute(Qt::AA_MacPluginApplication) && qt_mac_insideKeyWindow(tlw))
- return true;
-#endif
if(style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, this)) {
if(tlw->windowType() == Qt::Tool &&
!tlw->isModal() &&
@@ -6230,14 +6220,18 @@ bool QWidget::isActiveWindow() const
return true;
}
}
-#if defined(Q_WS_WIN32)
- HWND active = GetActiveWindow();
- if (!tlw->testAttribute(Qt::WA_WState_Created))
- return false;
- return active == tlw->internalWinId() || ::IsChild(active, tlw->internalWinId());
-#else
+
+ // Check if platform adaptation thinks the window is active. This is necessary for
+ // example in case of ActiveQt servers that are embedded into another application.
+ // Those are separate processes that are not part of the parent application Qt window/widget
+ // hierarchy, so they need to rely on native methods to determine if they are part of the
+ // active window.
+ if (const QWindow *w = tlw->windowHandle()) {
+ if (w->handle())
+ return w->handle()->isActive();
+ }
+
return false;
-#endif
}
/*!
diff --git a/src/widgets/kernel/qwidget_qpa.cpp b/src/widgets/kernel/qwidget_qpa.cpp
index ef3d7a16d9..a4cbcefb83 100644
--- a/src/widgets/kernel/qwidget_qpa.cpp
+++ b/src/widgets/kernel/qwidget_qpa.cpp
@@ -667,7 +667,14 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
void QWidgetPrivate::setFocus_sys()
{
-
+ Q_Q(QWidget);
+ // Embedded native widget may have taken the focus; get it back to toplevel if that is the case
+ if (QWindow *nativeWindow = q->window()->windowHandle()) {
+ if (nativeWindow != QGuiApplication::focusWindow()
+ && q->testAttribute(Qt::WA_WState_Created)) {
+ nativeWindow->requestActivateWindow();
+ }
+ }
}
void QWidgetPrivate::raise_sys()