Fix some painting issues with native widgets

QWidgetPrivate::drawWidget was missing an important line about marking
native widgets dirty compared to 4.8, which caused all other widgets
besides the native one to not repaint unless window was resized in such
a way that the widgets would get hidden and then re-exposed.

The above didn't fix repainting issues when moving native widgets
(e.g. widgets in QMdiArea subwindows or just calling QWidget::move()).
Added setting widgets dirty to QWidgetWindow::handleExposeEvent to
address this issue.

If there is one native widget, Qt enforces that all widgets in same
parent hierarchy are native - presumably to get overlapping widgets
drawing correctly. However, qapplication_qpa.cpp set the attribute
Qt::AA_DontCreateNativeWidgetSiblings for all applications, which
caused only the parents of native windows be forced native, leading to
drawing artifacts related to siblings of native widgets (e.g.
overlapping QMdiArea subwindows). I don't see a reason for setting this
flag indiscriminately for all applications, so removed it.

Also added setting newly created QWindow visible if associated
widget is already visible, which can happen if regular widgets
are shown before the first native widget is shown and retroactively
forces other widgets native.

Task-number:QTBUG-25805
Change-Id: Ib133dae9b13cc6e7155e7cae00fc1339d3b5ae86
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com>
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
This commit is contained in:
Miikka Heikkinen 2012-05-28 16:13:24 +03:00 committed by Qt by Nokia
parent 4d0424b671
commit 618ea643ca
4 changed files with 17 additions and 5 deletions

View File

@ -426,7 +426,6 @@ void qt_init(QApplicationPrivate *priv, int type)
Q_UNUSED(priv);
Q_UNUSED(type);
qApp->setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
QColormap::initialize();
if (const QPalette *toolTipPalette = QGuiApplicationPrivate::platformTheme()->palette(QPlatformTheme::ToolTipPalette))

View File

@ -5116,6 +5116,10 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
QPaintEvent e(toBePainted);
QCoreApplication::sendSpontaneousEvent(q, &e);
// Native widgets need to be marked dirty on screen so painting will be done in correct context
if (backingStore && !onScreen && !asRoot && (q->internalWinId() || !q->nativeParentWidget()->isWindow()))
backingStore->markDirtyOnScreen(toBePainted, q, offset);
//restore
if (paintEngine) {
#ifdef Q_WS_MAC

View File

@ -146,10 +146,12 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
setWindowModified_helper();
setWinId(win->winId());
// first check children. and create them if necessary
// q_createNativeChildrenAndSetParent(q->windowHandle(),q);
// Check children and create windows for them if necessary
q_createNativeChildrenAndSetParent(q->windowHandle(), q);
// qDebug() << "create_sys" << q << q->internalWinId();
// If widget is already shown, set window visible, too
if (q->isVisible())
win->setVisible(true);
}
void QWidget::destroy(bool destroyWindow, bool destroySubWindows)

View File

@ -46,6 +46,7 @@
#ifndef QT_NO_ACCESSIBILITY
#include <QtGui/qaccessible.h>
#endif
#include <private/qwidgetbackingstore_p.h>
QT_BEGIN_NAMESPACE
@ -458,8 +459,14 @@ void QWidgetWindow::handleExposeEvent(QExposeEvent *event)
{
if (isExposed()) {
m_widget->setAttribute(Qt::WA_Mapped);
if (!event->region().isNull())
if (!event->region().isNull()) {
// Exposed native widgets need to be marked dirty to get them repainted correctly.
if (m_widget->internalWinId() && !m_widget->isWindow()) {
if (QWidgetBackingStore *bs = m_widget->d_func()->maybeBackingStore())
bs->markDirty(event->region(), m_widget);
}
m_widget->d_func()->syncBackingStore(event->region());
}
} else {
m_widget->setAttribute(Qt::WA_Mapped, false);
}