From 49194275e02a9d6373767d6485bd8ebeeb0abba5 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 10 Sep 2014 11:42:55 +0200 Subject: [PATCH] Expose screen change event to widgets so that they can check the dpr Unlike ordinary widgets, the ones that have OpenGL framebuffers must know about screen changes because the device pixel ratio may be different on the new screen. Add an internal event, ScreenChangeInternal, as the counterpart to WindowChangeInternal. Change-Id: I5e55999838e4c0284e7d9832299f7cc6b541ee3f Reviewed-by: Paul Olav Tvete --- src/corelib/kernel/qcoreevent.cpp | 1 + src/corelib/kernel/qcoreevent.h | 1 + src/widgets/kernel/qopenglwidget.cpp | 4 ++++ src/widgets/kernel/qwidgetwindow.cpp | 25 ++++++++++++++++++++++--- src/widgets/kernel/qwidgetwindow_p.h | 3 ++- 5 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp index bc54a2ae74..044128998b 100644 --- a/src/corelib/kernel/qcoreevent.cpp +++ b/src/corelib/kernel/qcoreevent.cpp @@ -278,6 +278,7 @@ QT_BEGIN_NAMESPACE \omitvalue FutureCallOut \omitvalue NativeGesture \omitvalue WindowChangeInternal + \omitvalue ScreenChangeInternal */ /*! diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h index cd7689f842..bd5a5187e3 100644 --- a/src/corelib/kernel/qcoreevent.h +++ b/src/corelib/kernel/qcoreevent.h @@ -281,6 +281,7 @@ public: ApplicationStateChange = 214, WindowChangeInternal = 215, // internal for QQuickWidget + ScreenChangeInternal = 216, // 512 reserved for Qt Jambi's MetaCall event // 513 reserved for Qt Jambi's DeleteOnMainThread event diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index 8f7751618d..4eee4e526d 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -1061,6 +1061,10 @@ bool QOpenGLWidget::event(QEvent *e) d->recreateFbo(); } break; + case QEvent::ScreenChangeInternal: + if (d->initialized && d->paintDevice->devicePixelRatio() != devicePixelRatio()) + d->recreateFbo(); + break; default: break; } diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index b255bc16f9..dccd7ae2c8 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -99,7 +99,7 @@ QWidgetWindow::QWidgetWindow(QWidget *widget) setSurfaceType(QSurface::RasterGLSurface); } connect(m_widget, &QObject::objectNameChanged, this, &QWidgetWindow::updateObjectName); - connect(this, SIGNAL(screenChanged(QScreen*)), this, SLOT(repaintWindow())); + connect(this, SIGNAL(screenChanged(QScreen*)), this, SLOT(handleScreenChange())); } QWidgetWindow::~QWidgetWindow() @@ -558,8 +558,27 @@ void QWidgetWindow::updateGeometry() m_widget->data->fstrut_dirty = false; } -// Invalidates the backing store buffer and repaints immediately. -// ### Qt 5.4: replace with QUpdateWindowRequestEvent. +static void sendScreenChangeRecursively(QWidget *widget) +{ + QEvent e(QEvent::ScreenChangeInternal); + QApplication::sendEvent(widget, &e); + QWidgetPrivate *d = QWidgetPrivate::get(widget); + for (int i = 0; i < d->children.size(); ++i) { + QWidget *w = qobject_cast(d->children.at(i)); + if (w) + sendScreenChangeRecursively(w); + } +} + +void QWidgetWindow::handleScreenChange() +{ + // Send an event recursively to the widget and its children. + sendScreenChangeRecursively(m_widget); + + // Invalidate the backing store buffer and repaint immediately. + repaintWindow(); +} + void QWidgetWindow::repaintWindow() { if (!m_widget->isVisible() || !m_widget->updatesEnabled()) diff --git a/src/widgets/kernel/qwidgetwindow_p.h b/src/widgets/kernel/qwidgetwindow_p.h index be2adddff5..87ad7a4bd4 100644 --- a/src/widgets/kernel/qwidgetwindow_p.h +++ b/src/widgets/kernel/qwidgetwindow_p.h @@ -101,9 +101,10 @@ protected: private slots: void updateObjectName(); - void repaintWindow(); + void handleScreenChange(); private: + void repaintWindow(); void updateGeometry(); void updateNormalGeometry();