Windows: Set window style in correct order when reparenting foreign windows
The SetParent() documentation notes that when making a window a child window the window style should be set before calling SetParent(), while the opposite order should be used when making a window top level. We were exclusively doing the latter, which resulted in child windows getting activated and focused as part of the reparenting. Being the active window was resulting in the child window receiving WM_CLOSE and being destroyed if the user pressed Alt+F4, which was very surprising. The child window can still be focused later on, via e.g. an explicit call to SetFocus(), so it can receive keyboard input. The QWindowsWindow::setParent_sys() logic, used for non-foreign windows has the same fundamental issue with not respecting the order of the style update, but the interactions with the drop site logic makes it harder to update in similar fashion as this patch does for QWindowsForeignWindow. Pick-to: 6.8 6.8.0 Change-Id: Id88f5981daaf121a39aba9319d02aebefb6aa07b Reviewed-by: Jøger Hansegård <joger.hansegard@qt.io> Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
This commit is contained in:
parent
eff8e6b885
commit
a90d99d8da
@ -1357,10 +1357,12 @@ void QWindowsForeignWindow::setParent(const QPlatformWindow *newParentWindow)
|
||||
const HWND newParent = newParentWindow ? reinterpret_cast<HWND>(newParentWindow->winId()) : HWND(nullptr);
|
||||
const bool isTopLevel = !newParent;
|
||||
const DWORD oldStyle = style();
|
||||
|
||||
qCDebug(lcQpaWindow) << __FUNCTION__ << window() << "newParent="
|
||||
<< newParentWindow << newParent << "oldStyle=" << debugWinStyle(oldStyle);
|
||||
SetParent(m_hwnd, newParent);
|
||||
if (wasTopLevel != isTopLevel) { // Top level window flags need to be set/cleared manually.
|
||||
|
||||
auto updateWindowFlags = [=]{
|
||||
// Top level window flags need to be set/cleared manually.
|
||||
DWORD newStyle = oldStyle;
|
||||
if (isTopLevel) {
|
||||
newStyle = m_topLevelStyle;
|
||||
@ -1370,6 +1372,20 @@ void QWindowsForeignWindow::setParent(const QPlatformWindow *newParentWindow)
|
||||
newStyle |= WS_CHILD;
|
||||
}
|
||||
SetWindowLongPtr(m_hwnd, GWL_STYLE, newStyle);
|
||||
};
|
||||
|
||||
if (wasTopLevel && !isTopLevel) {
|
||||
// Becoming a child window requires the style
|
||||
// flags to be updated before reparenting.
|
||||
updateWindowFlags();
|
||||
}
|
||||
|
||||
SetParent(m_hwnd, newParent);
|
||||
|
||||
if (!wasTopLevel && isTopLevel) {
|
||||
// Becoming a top level window requires the style
|
||||
// flags to be updated after reparenting.
|
||||
updateWindowFlags();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user