Fix crash when handling WM_PAINT during COM operations
Synchronous expose corrupts painter state if it is done during existing paint operation, which can happen e.g. when requesting some value from dumpcpp generated wrapper inside a slot. Fixed by implementing support for setting asynchronous expose and doing expose according to the setting in handleWmPaint(). Task-number: QTBUG-27209 Change-Id: I89b5aa823fda947d26b1a4757f129e7c31ea408b Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>bb10
parent
52ccbd8911
commit
c4109fe103
|
|
@ -259,6 +259,7 @@ struct QWindowsContextPrivate {
|
|||
const HRESULT m_oleInitializeResult;
|
||||
const QByteArray m_eventType;
|
||||
QWindow *m_lastActiveWindow;
|
||||
bool m_asyncExpose;
|
||||
};
|
||||
|
||||
QWindowsContextPrivate::QWindowsContextPrivate() :
|
||||
|
|
@ -267,7 +268,7 @@ QWindowsContextPrivate::QWindowsContextPrivate() :
|
|||
m_defaultDPI(GetDeviceCaps(m_displayContext,LOGPIXELSY)),
|
||||
m_oleInitializeResult(OleInitialize(NULL)),
|
||||
m_eventType(QByteArrayLiteral("windows_generic_MSG")),
|
||||
m_lastActiveWindow(0)
|
||||
m_lastActiveWindow(0), m_asyncExpose(0)
|
||||
{
|
||||
#ifndef Q_OS_WINCE
|
||||
QWindowsContext::user32dll.init();
|
||||
|
|
@ -923,6 +924,16 @@ void QWindowsContext::handleContextMenuEvent(QWindow *window, const MSG &msg)
|
|||
}
|
||||
#endif
|
||||
|
||||
bool QWindowsContext::asyncExpose() const
|
||||
{
|
||||
return d->m_asyncExpose;
|
||||
}
|
||||
|
||||
void QWindowsContext::setAsyncExpose(bool value)
|
||||
{
|
||||
d->m_asyncExpose = value;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Windows functions for actual windows.
|
||||
|
||||
|
|
|
|||
|
|
@ -184,6 +184,8 @@ public:
|
|||
#endif
|
||||
|
||||
static QByteArray comErrorString(HRESULT hr);
|
||||
bool asyncExpose() const;
|
||||
void setAsyncExpose(bool value);
|
||||
|
||||
private:
|
||||
void handleFocusEvent(QtWindows::WindowsEventType et, QWindowsWindow *w);
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ QT_BEGIN_NAMESPACE
|
|||
class QWindowsNativeInterface : public QPlatformNativeInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool asyncExpose READ asyncExpose WRITE setAsyncExpose)
|
||||
public:
|
||||
#ifndef QT_NO_OPENGL
|
||||
virtual void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context);
|
||||
|
|
@ -106,6 +107,8 @@ public:
|
|||
Q_INVOKABLE void *createMessageWindow(const QString &classNameTemplate,
|
||||
const QString &windowName,
|
||||
void *eventProc) const;
|
||||
bool asyncExpose() const;
|
||||
void setAsyncExpose(bool value);
|
||||
};
|
||||
|
||||
void *QWindowsNativeInterface::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
|
||||
|
|
@ -183,6 +186,16 @@ void *QWindowsNativeInterface::createMessageWindow(const QString &classNameTempl
|
|||
return hwnd;
|
||||
}
|
||||
|
||||
bool QWindowsNativeInterface::asyncExpose() const
|
||||
{
|
||||
return QWindowsContext::instance()->asyncExpose();
|
||||
}
|
||||
|
||||
void QWindowsNativeInterface::setAsyncExpose(bool value)
|
||||
{
|
||||
QWindowsContext::instance()->setAsyncExpose(value);
|
||||
}
|
||||
|
||||
/*!
|
||||
\class QWindowsIntegration
|
||||
\brief QPlatformIntegration implementation for Windows.
|
||||
|
|
|
|||
|
|
@ -1158,7 +1158,8 @@ bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message,
|
|||
InvalidateRect(hwnd, 0, false);
|
||||
BeginPaint(hwnd, &ps);
|
||||
QWindowSystemInterface::handleExposeEvent(window(), QRegion(qrectFromRECT(ps.rcPaint)));
|
||||
QWindowSystemInterface::flushWindowSystemEvents();
|
||||
if (!QWindowsContext::instance()->asyncExpose())
|
||||
QWindowSystemInterface::flushWindowSystemEvents();
|
||||
|
||||
EndPaint(hwnd, &ps);
|
||||
} else {
|
||||
|
|
@ -1169,7 +1170,8 @@ bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message,
|
|||
qDebug() << __FUNCTION__ << this << window() << updateRect;
|
||||
|
||||
QWindowSystemInterface::handleExposeEvent(window(), QRegion(updateRect));
|
||||
QWindowSystemInterface::flushWindowSystemEvents();
|
||||
if (!QWindowsContext::instance()->asyncExpose())
|
||||
QWindowSystemInterface::flushWindowSystemEvents();
|
||||
EndPaint(hwnd, &ps);
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
Loading…
Reference in New Issue