fix window maximization bugs on Windows
This commit is contained in:
parent
0e63a053de
commit
1f1de5deb6
|
@ -97,7 +97,7 @@ void FramelessHelper::install()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
updateQtFrameMargins(true);
|
Utilities::updateQtFrameMargins(m_window, true);
|
||||||
const WId winId = m_window->winId();
|
const WId winId = m_window->winId();
|
||||||
Utilities::updateFrameMargins(winId, !true);
|
Utilities::updateFrameMargins(winId, !true);
|
||||||
Utilities::triggerFrameChange(winId);
|
Utilities::triggerFrameChange(winId);
|
||||||
|
@ -123,7 +123,7 @@ void FramelessHelper::uninstall()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
updateQtFrameMargins(false);
|
Utilities::updateQtFrameMargins(m_window, false);
|
||||||
const WId winId = m_window->winId();
|
const WId winId = m_window->winId();
|
||||||
Utilities::updateFrameMargins(winId, !false);
|
Utilities::updateFrameMargins(winId, !false);
|
||||||
Utilities::triggerFrameChange(winId);
|
Utilities::triggerFrameChange(winId);
|
||||||
|
@ -631,34 +631,6 @@ static inline bool shouldHaveWindowFrame()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(QMargins)
|
|
||||||
void FramelessHelper::updateQtFrameMargins(const bool enable)
|
|
||||||
{
|
|
||||||
const bool useCustomFrameMargin = (enable && (m_window->windowState() != Qt::WindowMaximized)
|
|
||||||
&& (m_window->windowState() != Qt::WindowFullScreen));
|
|
||||||
const int resizeBorderThickness = useCustomFrameMargin ? this->resizeBorderThickness() : 0;
|
|
||||||
const int titleBarHeight = enable ? this->titleBarHeight() : 0;
|
|
||||||
const QMargins margins = {-resizeBorderThickness, -titleBarHeight, -resizeBorderThickness, -resizeBorderThickness}; // left, top, right, bottom
|
|
||||||
const QVariant marginsVar = QVariant::fromValue(margins);
|
|
||||||
m_window->setProperty("_q_windowsCustomMargins", marginsVar);
|
|
||||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
|
||||||
QPlatformWindow *platformWindow = m_window->handle();
|
|
||||||
if (platformWindow) {
|
|
||||||
QGuiApplication::platformNativeInterface()->setWindowProperty(platformWindow, QStringLiteral("WindowsCustomMargins"), marginsVar);
|
|
||||||
} else {
|
|
||||||
qWarning() << "Failed to retrieve the platform window.";
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
auto *platformWindow = dynamic_cast<QNativeInterface::Private::QWindowsWindow *>(
|
|
||||||
m_window->handle());
|
|
||||||
if (platformWindow) {
|
|
||||||
platformWindow->setCustomMargins(margins);
|
|
||||||
} else {
|
|
||||||
qWarning() << "Failed to retrieve the platform window.";
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
This function works like a eventFilter, return \c true means the event has been handled.
|
This function works like a eventFilter, return \c true means the event has been handled.
|
||||||
*/
|
*/
|
||||||
|
@ -688,8 +660,8 @@ bool FramelessHelper::handleNativeEvent(QWindow *window, const QByteArray &event
|
||||||
if (!window)
|
if (!window)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// 所有从 Qt 获得的值必须乘以放大倍速,所有传给 Qt 的值必须除以放大倍数。
|
// All values obtained from Qt must be multiplied by the scaleFactor,
|
||||||
// TODO: 全屏情况下 hitTestVisible 区域的计算有问题。很可能是全屏时,边框剪切造成的按钮位置偏移。
|
// and all values passed to Qt must be divided by the scaleFactor.
|
||||||
qreal scaleFactor = m_window->screen()->devicePixelRatio();
|
qreal scaleFactor = m_window->screen()->devicePixelRatio();
|
||||||
|
|
||||||
switch (msg->message) {
|
switch (msg->message) {
|
||||||
|
@ -775,10 +747,14 @@ bool FramelessHelper::handleNativeEvent(QWindow *window, const QByteArray &event
|
||||||
|
|
||||||
const auto clientRect = &(reinterpret_cast<LPNCCALCSIZE_PARAMS>(msg->lParam)->rgrc[0]);
|
const auto clientRect = &(reinterpret_cast<LPNCCALCSIZE_PARAMS>(msg->lParam)->rgrc[0]);
|
||||||
|
|
||||||
resizeWindow(QSize(
|
// In order to determine the area of the title bar, we need to record
|
||||||
|
// the geometric area of the new window size.
|
||||||
|
resizeWindow(
|
||||||
|
QSize(
|
||||||
qRound((clientRect->right - clientRect->left) / scaleFactor),
|
qRound((clientRect->right - clientRect->left) / scaleFactor),
|
||||||
qRound((clientRect->bottom - clientRect->top) / scaleFactor)
|
qRound((clientRect->bottom - clientRect->top) / scaleFactor)
|
||||||
));
|
)
|
||||||
|
);
|
||||||
|
|
||||||
if (shouldHaveWindowFrame()) {
|
if (shouldHaveWindowFrame()) {
|
||||||
// Store the original top before the default window proc
|
// Store the original top before the default window proc
|
||||||
|
@ -805,8 +781,10 @@ bool FramelessHelper::handleNativeEvent(QWindow *window, const QByteArray &event
|
||||||
// then the window is clipped to the monitor so that the resize handle
|
// then the window is clipped to the monitor so that the resize handle
|
||||||
// do not appear because you don't need them (because you can't resize
|
// do not appear because you don't need them (because you can't resize
|
||||||
// a window when it's maximized unless you restore it).
|
// a window when it's maximized unless you restore it).
|
||||||
const int resizeBorderThickness = qRound(
|
|
||||||
static_cast<qreal>(this->resizeBorderThickness()) * scaleFactor);
|
// Get system default resize border thickness.
|
||||||
|
const int resizeBorderThickness = Utilities::getSystemMetric(
|
||||||
|
window, SystemMetric::ResizeBorderThickness, true, true);
|
||||||
clientRect->top += resizeBorderThickness;
|
clientRect->top += resizeBorderThickness;
|
||||||
if (!shouldHaveWindowFrame()) {
|
if (!shouldHaveWindowFrame()) {
|
||||||
clientRect->bottom -= resizeBorderThickness;
|
clientRect->bottom -= resizeBorderThickness;
|
||||||
|
@ -1200,15 +1178,6 @@ bool FramelessHelper::handleNativeEvent(QWindow *window, const QByteArray &event
|
||||||
*result = ret;
|
*result = ret;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case WM_SIZE: {
|
|
||||||
const bool normal = (msg->wParam == SIZE_RESTORED);
|
|
||||||
const bool max = (msg->wParam == SIZE_MAXIMIZED);
|
|
||||||
const bool full = (window->windowState() == Qt::WindowFullScreen);
|
|
||||||
if (normal || max || full) {
|
|
||||||
Utilities::updateFrameMargins(reinterpret_cast<WId>(msg->hwnd), (max || full));
|
|
||||||
updateQtFrameMargins(true);
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,11 +97,6 @@ public:
|
||||||
#endif
|
#endif
|
||||||
#endif // Q_OS_WIN
|
#endif // Q_OS_WIN
|
||||||
|
|
||||||
private:
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
void updateQtFrameMargins(const bool enable);
|
|
||||||
#endif // Q_OS_WIN
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool eventFilter(QObject *object, QEvent *event) override;
|
bool eventFilter(QObject *object, QEvent *event) override;
|
||||||
void handleResizeHandlerDblClicked();
|
void handleResizeHandlerDblClicked();
|
||||||
|
|
|
@ -281,7 +281,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
||||||
// then the window is clipped to the monitor so that the resize handle
|
// then the window is clipped to the monitor so that the resize handle
|
||||||
// do not appear because you don't need them (because you can't resize
|
// do not appear because you don't need them (because you can't resize
|
||||||
// a window when it's maximized unless you restore it).
|
// a window when it's maximized unless you restore it).
|
||||||
const int resizeBorderThickness = Utilities::getSystemMetric(window, SystemMetric::ResizeBorderThickness, true);
|
const int resizeBorderThickness = Utilities::getSystemMetric(window, SystemMetric::ResizeBorderThickness, false, true);
|
||||||
clientRect->top += resizeBorderThickness;
|
clientRect->top += resizeBorderThickness;
|
||||||
if (!shouldHaveWindowFrame()) {
|
if (!shouldHaveWindowFrame()) {
|
||||||
clientRect->bottom -= resizeBorderThickness;
|
clientRect->bottom -= resizeBorderThickness;
|
||||||
|
|
Loading…
Reference in New Issue