win: add a little delay to some operations

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
Yuhang Zhao 2022-11-20 12:56:36 +08:00
parent 04f254556d
commit 648876b6b0
2 changed files with 27 additions and 17 deletions

View File

@ -27,6 +27,7 @@
#include <QtCore/qmutex.h>
#include <QtCore/qvariant.h>
#include <QtCore/qcoreapplication.h>
#include <QtCore/qtimer.h>
#include <QtGui/qwindow.h>
#include "framelessmanager.h"
#include "framelessmanager_p.h"
@ -639,7 +640,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
const WPARAM wParam = msg->wParam;
const LPARAM lParam = msg->lParam;
switch (uMsg) {
#if (QT_VERSION < QT_VERSION_CHECK(5, 9, 0))
#if (QT_VERSION < QT_VERSION_CHECK(5, 9, 0)) // Qt has done this for us since 5.9.0
case WM_NCCREATE: {
// Enable automatic DPI scaling for the non-client area of the window,
// such as the caption bar, the scrollbars, and the menu bar. We need
@ -1112,7 +1113,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
return true;
}
}
#if (QT_VERSION < QT_VERSION_CHECK(6, 2, 2))
#if (QT_VERSION < QT_VERSION_CHECK(6, 2, 2)) // I contributed this to Qt since 6.2.2
case WM_WINDOWPOSCHANGING: {
// Tell Windows to discard the entire contents of the client area, as re-using
// parts of the client area would lead to jitter during resize.
@ -1127,6 +1128,9 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
<< hwnd2str(hWnd) << ": QDpi(" << dpiX << ", " << dpiY << ").";
// Sync the internal window frame margins with the latest DPI.
Utils::updateInternalWindowFrameMargins(data.params.getWindowHandle(), true);
// Here we need a little delay because event filters are processed before
// Qt's own window message handlers.
QTimer::singleShot(50, [data](){ // Copy "data" intentionally, otherwise it'll go out of scope when Qt finally use it.
// For some unknown reason, Qt sometimes won't re-paint the window contents after
// the DPI changes, and in my experiments the controls should be moved to our
// desired geometry already, the only issue is we don't get the updated appearance
@ -1134,6 +1138,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
// event manually. There's no need to increase/decrease the window size and then
// change it back, just give Qt our current window size is sufficient enough.
data.params.setWindowSize(data.params.getWindowSize());
});
} break;
case WM_DWMCOMPOSITIONCHANGED: {
// Re-apply the custom window frame if recovered from the basic theme.

View File

@ -25,6 +25,7 @@
#include "framelessmanager_p.h"
#include <QtCore/qmutex.h>
#include <QtCore/qcoreapplication.h>
#include <QtCore/qtimer.h>
#include <QtGui/qscreen.h>
#include <QtGui/qwindow.h>
#include <QtGui/qfontdatabase.h>
@ -217,6 +218,9 @@ void FramelessManagerPrivate::addWindow(const SystemParameters &params)
g_helper()->data[windowId].screenChangeConnection =
connect(window, &QWindow::screenChanged, window, [windowId, window](QScreen *screen){
Q_UNUSED(screen);
// Add a little delay here, make sure it happens after Qt has processed the window
// messages.
QTimer::singleShot(50, window, [windowId, window](){
// Force a WM_NCCALCSIZE event to inform Windows about our custom window frame,
// this is only necessary when the window is being moved cross monitors.
Utils::triggerFrameChange(windowId);
@ -226,6 +230,7 @@ void FramelessManagerPrivate::addWindow(const SystemParameters &params)
// observed disappeared indeed, amazingly.
window->resize(window->size());
});
});
g_helper()->mutex.unlock();
}
}