win32: fix restore geometry bug
The upstream fix has not been merged yet, however, it will be in 6.5.1 for sure. Fixes: #20 Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
parent
8930ea128f
commit
a203e2c3ca
|
@ -161,10 +161,10 @@ if(NOT FRAMELESSHELPER_NO_SUMMARY)
|
|||
message("Toolchain file: ${CMAKE_TOOLCHAIN_FILE}")
|
||||
message("------------------------------ Qt -------------------------------")
|
||||
query_qt_paths(SDK_DIR __qt_inst_dir)
|
||||
query_qt_library_info(VERSION __qt_version STATIC __qt_static_lib)
|
||||
message("Qt SDK installation directory: ${__qt_inst_dir}")
|
||||
message("Qt SDK version: ${QT_VERSION}")
|
||||
query_qt_library_info(STATIC __qt_lib_type)
|
||||
if(__qt_lib_type)
|
||||
message("Qt SDK version: ${__qt_version}")
|
||||
if(__qt_static_lib)
|
||||
message("Qt SDK library type: static")
|
||||
else()
|
||||
message("Qt SDK library type: shared")
|
||||
|
|
2
cmake
2
cmake
|
@ -1 +1 @@
|
|||
Subproject commit 60329b55dcfaf41da63f134a90ddce82dc9b6c4a
|
||||
Subproject commit be821fca7e90858343540a487d663dca52bf0cd5
|
|
@ -135,6 +135,8 @@ FRAMELESSHELPER_CORE_API void fixupChildWindowsDpiMessage(const WId windowId);
|
|||
FRAMELESSHELPER_CORE_API void fixupDialogsDpiScaling();
|
||||
FRAMELESSHELPER_CORE_API void setDarkModeAllowedForApp(const bool allow = true);
|
||||
FRAMELESSHELPER_CORE_API void bringWindowToFront(const WId windowId);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API QPoint getWindowPlacementOffset(const WId windowId);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API QRect getWindowRestoreFrameGeometry(const WId windowId);
|
||||
#endif // Q_OS_WINDOWS
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
|
|
|
@ -84,6 +84,8 @@ FRAMELESSHELPER_STRING_CONSTANT(TrackMouseEvent)
|
|||
FRAMELESSHELPER_STRING_CONSTANT(FindWindowW)
|
||||
FRAMELESSHELPER_STRING_CONSTANT(UnregisterClassW)
|
||||
FRAMELESSHELPER_STRING_CONSTANT(DestroyWindow)
|
||||
FRAMELESSHELPER_STRING_CONSTANT(GetWindowPlacement)
|
||||
FRAMELESSHELPER_STRING_CONSTANT(SetWindowPlacement)
|
||||
[[maybe_unused]] static constexpr const char kFallbackTitleBarErrorMessage[] =
|
||||
"FramelessHelper is unable to create the fallback title bar window, and thus the snap layout feature will be disabled"
|
||||
" unconditionally. You can ignore this error and continue running your application, nothing else will be affected, "
|
||||
|
@ -98,6 +100,7 @@ struct Win32HelperData
|
|||
bool trackingMouse = false;
|
||||
WId fallbackTitleBarWindowId = 0;
|
||||
Dpi dpi = {};
|
||||
QRect restoreGeometry = {};
|
||||
};
|
||||
|
||||
struct Win32Helper
|
||||
|
@ -1184,10 +1187,11 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
#if (QT_VERSION <= QT_VERSION_CHECK(6, 4, 2))
|
||||
// We need to wait until Qt has handled this message, otherwise everything
|
||||
// we have done here will always be overwritten.
|
||||
QTimer::singleShot(0, qApp, [data](){ // Copy the variables intentionally, otherwise they'll go out of scope when Qt finally use them.
|
||||
QWindow *window = data.params.getWindowHandle();
|
||||
QTimer::singleShot(0, qApp, [window](){
|
||||
// Sync the internal window frame margins with the latest DPI, otherwise
|
||||
// we will get wrong window sizes after the DPI change.
|
||||
Utils::updateInternalWindowFrameMargins(data.params.getWindowHandle(), true);
|
||||
Utils::updateInternalWindowFrameMargins(window, true);
|
||||
});
|
||||
#endif // (QT_VERSION <= QT_VERSION_CHECK(6, 4, 2))
|
||||
} break;
|
||||
|
@ -1195,6 +1199,50 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
// Re-apply the custom window frame if recovered from the basic theme.
|
||||
Utils::updateWindowFrameMargins(windowId, false);
|
||||
} break;
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 5, 1))
|
||||
case WM_ENTERSIZEMOVE:
|
||||
case WM_EXITSIZEMOVE: {
|
||||
if (!Utils::isWindowNoState(windowId)) {
|
||||
break;
|
||||
}
|
||||
const QRect rect = Utils::getWindowRestoreFrameGeometry(windowId);
|
||||
if (rect.isNull() || !rect.isValid()) {
|
||||
WARNING << "The calculated restore geometry is invalid.";
|
||||
break;
|
||||
}
|
||||
const QMutexLocker locker(&g_win32Helper()->mutex);
|
||||
g_win32Helper()->data[windowId].restoreGeometry = rect;
|
||||
} break;
|
||||
case WM_SIZE: {
|
||||
if (wParam != SIZE_MAXIMIZED) {
|
||||
break;
|
||||
}
|
||||
if (data.restoreGeometry.isNull() || !data.restoreGeometry.isValid()) {
|
||||
const QRect rect = Utils::getWindowRestoreFrameGeometry(windowId);
|
||||
if (rect.isValid() && !rect.isNull()) {
|
||||
const QMutexLocker locker(&g_win32Helper()->mutex);
|
||||
g_win32Helper()->data[windowId].restoreGeometry = rect;
|
||||
} else {
|
||||
WARNING << "The calculated restore geometry is invalid.";
|
||||
}
|
||||
break;
|
||||
}
|
||||
WINDOWPLACEMENT wp;
|
||||
SecureZeroMemory(&wp, sizeof(wp));
|
||||
wp.length = sizeof(wp);
|
||||
if (GetWindowPlacement(hWnd, &wp) == FALSE) {
|
||||
WARNING << Utils::getSystemErrorMessage(kGetWindowPlacement);
|
||||
break;
|
||||
}
|
||||
wp.rcNormalPosition = {
|
||||
data.restoreGeometry.left(), data.restoreGeometry.top(),
|
||||
data.restoreGeometry.right(), data.restoreGeometry.bottom()
|
||||
};
|
||||
if (SetWindowPlacement(hWnd, &wp) == FALSE) {
|
||||
WARNING << Utils::getSystemErrorMessage(kSetWindowPlacement);
|
||||
}
|
||||
} break;
|
||||
#endif // (QT_VERSION < QT_VERSION_CHECK(6, 5, 1))
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -2390,4 +2390,57 @@ void Utils::bringWindowToFront(const WId windowId)
|
|||
moveWindowToMonitor(hwnd, activeMonitor.value());
|
||||
}
|
||||
|
||||
QPoint Utils::getWindowPlacementOffset(const WId windowId)
|
||||
{
|
||||
Q_ASSERT(windowId);
|
||||
if (!windowId) {
|
||||
return {};
|
||||
}
|
||||
const auto hwnd = reinterpret_cast<HWND>(windowId);
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
const auto exStyle = static_cast<DWORD>(GetWindowLongPtrW(hwnd, GWL_EXSTYLE));
|
||||
if (exStyle == 0) {
|
||||
WARNING << getSystemErrorMessage(kGetWindowLongPtrW);
|
||||
return {};
|
||||
}
|
||||
// Tool windows are special and they don't need any offset.
|
||||
if (exStyle & WS_EX_TOOLWINDOW) {
|
||||
return {};
|
||||
}
|
||||
const HMONITOR mon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY);
|
||||
if (!mon) {
|
||||
WARNING << getSystemErrorMessage(kMonitorFromWindow);
|
||||
return {};
|
||||
}
|
||||
MONITORINFOEXW mi;
|
||||
SecureZeroMemory(&mi, sizeof(mi));
|
||||
mi.cbSize = sizeof(mi);
|
||||
if (GetMonitorInfoW(mon, &mi) == FALSE) {
|
||||
WARNING << getSystemErrorMessage(kGetMonitorInfoW);
|
||||
return {};
|
||||
}
|
||||
return {mi.rcWork.left - mi.rcMonitor.left, mi.rcWork.top - mi.rcMonitor.top};
|
||||
}
|
||||
|
||||
QRect Utils::getWindowRestoreFrameGeometry(const WId windowId)
|
||||
{
|
||||
Q_ASSERT(windowId);
|
||||
if (!windowId) {
|
||||
return {};
|
||||
}
|
||||
const auto hwnd = reinterpret_cast<HWND>(windowId);
|
||||
WINDOWPLACEMENT wp;
|
||||
SecureZeroMemory(&wp, sizeof(wp));
|
||||
wp.length = sizeof(wp);
|
||||
if (GetWindowPlacement(hwnd, &wp) == FALSE) {
|
||||
WARNING << getSystemErrorMessage(kGetWindowPlacement);
|
||||
return {};
|
||||
}
|
||||
const RECT rawRect = wp.rcNormalPosition;
|
||||
const QPoint topLeft = {rawRect.left, rawRect.top};
|
||||
const QSize size = {rawRect.right - rawRect.left, rawRect.bottom - rawRect.top};
|
||||
const QPoint offset = getWindowPlacementOffset(windowId);
|
||||
return QRect{topLeft, size}.translated(offset);
|
||||
}
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
|
Loading…
Reference in New Issue