diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/kernel/qwindow.cpp | 6 | ||||
-rw-r--r-- | src/gui/kernel/qwindow_p.h | 2 | ||||
-rw-r--r-- | src/gui/painting/qplatformbackingstore.cpp | 32 | ||||
-rw-r--r-- | src/gui/painting/qplatformbackingstore.h | 2 | ||||
-rw-r--r-- | src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp | 5 | ||||
-rw-r--r-- | src/platformsupport/platformcompositor/qopenglcompositorbackingstore_p.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoabackingstore.h | 4 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoabackingstore.mm | 34 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qiosbackingstore.h | 3 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qiosbackingstore.mm | 15 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbbackingstore.cpp | 4 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbbackingstore.h | 2 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget.cpp | 125 | ||||
-rw-r--r-- | src/widgets/kernel/qwidgetbackingstore.cpp | 6 | ||||
-rw-r--r-- | src/widgets/kernel/qwidgetwindow.cpp | 8 |
15 files changed, 117 insertions, 133 deletions
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index b4e2b47c03..42b54bf98a 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -45,6 +45,7 @@ #ifndef QT_NO_OPENGL #include <qpa/qplatformopenglcontext.h> #include "qopenglcontext.h" +#include "qopenglcontext_p.h" #endif #include "qscreen.h" @@ -2633,6 +2634,11 @@ QWindow *QWindowPrivate::topLevelWindow() const return window; } +QOpenGLContext *QWindowPrivate::shareContext() const +{ + return qt_gl_global_share_context(); +}; + /*! Creates a local representation of a window created by another process or by using native libraries below Qt. diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h index 9b8e2c47e4..bf6be1bb98 100644 --- a/src/gui/kernel/qwindow_p.h +++ b/src/gui/kernel/qwindow_p.h @@ -130,6 +130,8 @@ public: QWindow *topLevelWindow() const; + virtual QOpenGLContext *shareContext() const; + virtual QWindow *eventReceiver() { Q_Q(QWindow); return q; } virtual void setVisible(bool visible); diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp index 6cb115afba..8ab22beb31 100644 --- a/src/gui/painting/qplatformbackingstore.cpp +++ b/src/gui/painting/qplatformbackingstore.cpp @@ -50,6 +50,7 @@ #include <QtGui/QOpenGLFunctions> #ifndef QT_NO_OPENGL #include <QtGui/qopengltextureblitter.h> +#include <QtGui/qoffscreensurface.h> #endif #include <qpa/qplatformgraphicsbuffer.h> #include <qpa/qplatformgraphicsbufferhelper.h> @@ -95,14 +96,15 @@ public: ~QPlatformBackingStorePrivate() { #ifndef QT_NO_OPENGL - QOpenGLContext *ctx = QOpenGLContext::currentContext(); - if (ctx) { + if (context) { + QOffscreenSurface offscreenSurface; + offscreenSurface.setFormat(context->format()); + offscreenSurface.create(); + context->makeCurrent(&offscreenSurface); if (textureId) - ctx->functions()->glDeleteTextures(1, &textureId); + context->functions()->glDeleteTextures(1, &textureId); if (blitter) blitter->destroy(); - } else if (textureId || blitter) { - qWarning("No context current during QPlatformBackingStore destruction, OpenGL resources not released"); } delete blitter; #endif @@ -110,6 +112,7 @@ public: QWindow *window; QBackingStore *backingStore; #ifndef QT_NO_OPENGL + QScopedPointer<QOpenGLContext> context; mutable GLuint textureId; mutable QSize textureSize; mutable bool needsSwizzle; @@ -316,20 +319,31 @@ static void blitTextureForWidget(const QPlatformTextureList *textures, int idx, void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®ion, const QPoint &offset, - QPlatformTextureList *textures, QOpenGLContext *context, + QPlatformTextureList *textures, bool translucentBackground) { if (!qt_window_private(window)->receivedExpose) return; - if (!context->makeCurrent(window)) { + if (!d_ptr->context) { + d_ptr->context.reset(new QOpenGLContext); + d_ptr->context->setFormat(d_ptr->window->requestedFormat()); + d_ptr->context->setScreen(d_ptr->window->screen()); + d_ptr->context->setShareContext(qt_window_private(d_ptr->window)->shareContext()); + if (!d_ptr->context->create()) { + qWarning("composeAndFlush: QOpenGLContext creation failed"); + return; + } + } + + if (!d_ptr->context->makeCurrent(window)) { qWarning("composeAndFlush: makeCurrent() failed"); return; } QWindowPrivate::get(window)->lastComposeTime.start(); - QOpenGLFunctions *funcs = context->functions(); + QOpenGLFunctions *funcs = d_ptr->context->functions(); funcs->glViewport(0, 0, window->width() * window->devicePixelRatio(), window->height() * window->devicePixelRatio()); funcs->glClearColor(0, 0, 0, translucentBackground ? 0 : 1); funcs->glClear(GL_COLOR_BUFFER_BIT); @@ -435,7 +449,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i funcs->glDisable(GL_BLEND); d_ptr->blitter->release(); - context->swapBuffers(window); + d_ptr->context->swapBuffers(window); } #endif /*! diff --git a/src/gui/painting/qplatformbackingstore.h b/src/gui/painting/qplatformbackingstore.h index 9956c032a9..381c564079 100644 --- a/src/gui/painting/qplatformbackingstore.h +++ b/src/gui/painting/qplatformbackingstore.h @@ -120,7 +120,7 @@ public: virtual void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) = 0; #ifndef QT_NO_OPENGL virtual void composeAndFlush(QWindow *window, const QRegion ®ion, const QPoint &offset, - QPlatformTextureList *textures, QOpenGLContext *context, + QPlatformTextureList *textures, bool translucentBackground); #endif virtual QImage toImage() const; diff --git a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp index b24491b187..e938020437 100644 --- a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp +++ b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp @@ -202,14 +202,13 @@ void QOpenGLCompositorBackingStore::flush(QWindow *window, const QRegion ®ion } void QOpenGLCompositorBackingStore::composeAndFlush(QWindow *window, const QRegion ®ion, const QPoint &offset, - QPlatformTextureList *textures, QOpenGLContext *context, + QPlatformTextureList *textures, bool translucentBackground) { // QOpenGLWidget/QQuickWidget content provided as textures. The raster content goes on top. Q_UNUSED(region); Q_UNUSED(offset); - Q_UNUSED(context); Q_UNUSED(translucentBackground); QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); @@ -218,7 +217,7 @@ void QOpenGLCompositorBackingStore::composeAndFlush(QWindow *window, const QRegi // The compositor's context and the context to which QOpenGLWidget/QQuickWidget // textures belong are not the same. They share resources, though. - Q_ASSERT(context->shareGroup() == dstCtx->shareGroup()); + Q_ASSERT(qt_window_private(window)->shareContext()->shareGroup() == dstCtx->shareGroup()); QWindow *dstWin = compositor->targetWindow(); if (!dstWin) diff --git a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore_p.h b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore_p.h index 0b025e4304..da68b90e92 100644 --- a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore_p.h +++ b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore_p.h @@ -75,7 +75,7 @@ public: QImage toImage() const Q_DECL_OVERRIDE; void composeAndFlush(QWindow *window, const QRegion ®ion, const QPoint &offset, - QPlatformTextureList *textures, QOpenGLContext *context, + QPlatformTextureList *textures, bool translucentBackground) Q_DECL_OVERRIDE; const QPlatformTextureList *textures() const { return m_textures; } diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h index 002e5b40a8..a0bc204013 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.h +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h @@ -52,16 +52,12 @@ public: QCocoaBackingStore(QWindow *window); ~QCocoaBackingStore(); - void beginPaint(const QRegion &) override; - void endPaint() override; - void flush(QWindow *, const QRegion &, const QPoint &) Q_DECL_OVERRIDE; private: bool windowHasUnifiedToolbar() const; QImage::Format format() const Q_DECL_OVERRIDE; void redrawRoundedBottomCorners(CGRect) const; - QCFType<CGImageRef> m_cgImage; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm index 1f39d787be..57a03905ab 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm @@ -48,7 +48,6 @@ Q_LOGGING_CATEGORY(lcCocoaBackingStore, "qt.qpa.cocoa.backingstore"); QCocoaBackingStore::QCocoaBackingStore(QWindow *window) : QRasterBackingStore(window) - , m_cgImage(nullptr) { } @@ -70,26 +69,6 @@ QImage::Format QCocoaBackingStore::format() const return QRasterBackingStore::format(); } -void QCocoaBackingStore::beginPaint(const QRegion ®ion) -{ - m_cgImage = nullptr; - QRasterBackingStore::beginPaint(region); -} - -void QCocoaBackingStore::endPaint() -{ - QRasterBackingStore::endPaint(); - - // Prevent potentially costly color conversion by assiging the display - // color space to the backingstore image. - NSView *view = static_cast<QCocoaWindow *>(window()->handle())->view(); - CGColorSpaceRef displayColorSpace = view.window.screen.colorSpace.CGColorSpace; - QCFType<CGImageRef> displayColorSpaceImage = - CGImageCreateCopyWithColorSpace(m_image.toCGImage(), displayColorSpace); - - m_cgImage = displayColorSpaceImage; -} - #if !QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_12) static const NSCompositingOperation NSCompositingOperationCopy = NSCompositeCopy; static const NSCompositingOperation NSCompositingOperationSourceOver = NSCompositeSourceOver; @@ -111,6 +90,9 @@ void QCocoaBackingStore::flush(QWindow *window, const QRegion ®ion, const QPo if (m_image.isNull()) return; + // Use local pool so that any stale image references are cleaned up after flushing + QMacAutoReleasePool pool; + const QWindow *topLevelWindow = this->window(); Q_ASSERT(topLevelWindow->handle() && window->handle()); @@ -128,6 +110,12 @@ void QCocoaBackingStore::flush(QWindow *window, const QRegion ®ion, const QPo qCDebug(lcCocoaBackingStore) << "Flushing" << region << "of" << view << qPrintable(targetViewDescription); } + // Prevent potentially costly color conversion by assigning the display color space + // to the backingstore image. This does not copy the underlying image data. + CGColorSpaceRef displayColorSpace = view.window.screen.colorSpace.CGColorSpace; + QCFType<CGImageRef> cgImage = CGImageCreateCopyWithColorSpace( + QCFType<CGImageRef>(m_image.toCGImage()), displayColorSpace); + if (view.layer) { // In layer-backed mode, locking focus on a view does not give the right // view transformation, and doesn't give us a graphics context to render @@ -137,7 +125,7 @@ void QCocoaBackingStore::flush(QWindow *window, const QRegion ®ion, const QPo // we then directly set the layer's backingstore (content) to our backingstore, // masked to the part of the subview that is relevant. // FIXME: Figure out if there's a way to do partial updates - view.layer.contents = (__bridge id)static_cast<CGImageRef>(m_cgImage); + view.layer.contents = (__bridge id)static_cast<CGImageRef>(cgImage); if (view != topLevelView) { view.layer.contentsRect = CGRectApplyAffineTransform( [view convertRect:view.bounds toView:topLevelView], @@ -196,7 +184,7 @@ void QCocoaBackingStore::flush(QWindow *window, const QRegion ®ion, const QPo "Focusing the view should give us a current graphics context"); // Create temporary image to use for blitting, without copying image data - NSImage *backingStoreImage = [[[NSImage alloc] initWithCGImage:m_cgImage size:NSZeroSize] autorelease]; + NSImage *backingStoreImage = [[[NSImage alloc] initWithCGImage:cgImage size:NSZeroSize] autorelease]; QRegion clippedRegion = region; for (QWindow *w = window; w; w = w->parent()) { diff --git a/src/plugins/platforms/ios/qiosbackingstore.h b/src/plugins/platforms/ios/qiosbackingstore.h index 3954347471..e6b890251a 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.h +++ b/src/plugins/platforms/ios/qiosbackingstore.h @@ -55,9 +55,6 @@ public: ~QIOSBackingStore(); void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) Q_DECL_OVERRIDE; - -private: - QOpenGLContext *m_context; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index 74229684e3..db4dd81b2e 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -55,7 +55,6 @@ QT_BEGIN_NAMESPACE */ QIOSBackingStore::QIOSBackingStore(QWindow *window) : QRasterBackingStore(window) - , m_context(new QOpenGLContext) { // We use the surface both for raster operations and for GL drawing (when // we blit the raster image), so the type needs to cover both use cases. @@ -64,22 +63,10 @@ QIOSBackingStore::QIOSBackingStore(QWindow *window) Q_ASSERT_X(window->surfaceType() != QSurface::OpenGLSurface, "QIOSBackingStore", "QBackingStore on iOS can only be used with raster-enabled surfaces."); - - m_context->setFormat(window->requestedFormat()); - m_context->setScreen(window->screen()); - Q_ASSERT(QOpenGLContext::globalShareContext()); - m_context->setShareContext(QOpenGLContext::globalShareContext()); - m_context->create(); } QIOSBackingStore::~QIOSBackingStore() { - // We're using composeAndFlush from QPlatformBackingStore, which - // need to clean up any textures in its destructor, so make the - // context current and keep it alive until QPlatformBackingStore - // has cleaned up everything. - m_context->makeCurrent(window()); - m_context->deleteLater(); } void QIOSBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) @@ -98,7 +85,7 @@ void QIOSBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoin } static QPlatformTextureList emptyTextureList; - composeAndFlush(window, region, offset, &emptyTextureList, m_context, false); + composeAndFlush(window, region, offset, &emptyTextureList, false); } QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index 17927af3e3..420d1ac7c5 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -600,10 +600,10 @@ void QXcbBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoin #ifndef QT_NO_OPENGL void QXcbBackingStore::composeAndFlush(QWindow *window, const QRegion ®ion, const QPoint &offset, - QPlatformTextureList *textures, QOpenGLContext *context, + QPlatformTextureList *textures, bool translucentBackground) { - QPlatformBackingStore::composeAndFlush(window, region, offset, textures, context, translucentBackground); + QPlatformBackingStore::composeAndFlush(window, region, offset, textures, translucentBackground); QXcbWindow *platformWindow = static_cast<QXcbWindow *>(window->handle()); if (platformWindow->needsSync()) { diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.h b/src/plugins/platforms/xcb/qxcbbackingstore.h index 94b5994004..2e8fbfb7fa 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.h +++ b/src/plugins/platforms/xcb/qxcbbackingstore.h @@ -61,7 +61,7 @@ public: void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) override; #ifndef QT_NO_OPENGL void composeAndFlush(QWindow *window, const QRegion ®ion, const QPoint &offset, - QPlatformTextureList *textures, QOpenGLContext *context, + QPlatformTextureList *textures, bool translucentBackground) override; #endif QImage toImage() const override; diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index a5e09795a7..3369548f18 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1876,39 +1876,15 @@ static void deleteBackingStore(QWidgetPrivate *d) { QTLWExtra *topData = d->topData(); - // The context must be current when destroying the backing store as it may attempt to - // release resources like textures and shader programs. The window may not be suitable - // anymore as there will often not be a platform window underneath at this stage. Fall - // back to a QOffscreenSurface in this case. - QScopedPointer<QOffscreenSurface> tempSurface; -#ifndef QT_NO_OPENGL - if (d->textureChildSeen && topData->shareContext) { - if (topData->window->handle()) { - topData->shareContext->makeCurrent(topData->window); - } else { - tempSurface.reset(new QOffscreenSurface); - tempSurface->setFormat(topData->shareContext->format()); - tempSurface->create(); - topData->shareContext->makeCurrent(tempSurface.data()); - } - } -#endif - delete topData->backingStore; topData->backingStore = 0; - -#ifndef QT_NO_OPENGL - if (d->textureChildSeen && topData->shareContext) - topData->shareContext->doneCurrent(); -#endif } void QWidgetPrivate::deleteTLSysExtra() { if (extra && extra->topextra) { //the qplatformbackingstore may hold a reference to the window, so the backingstore - //needs to be deleted first. If the backingstore holds GL resources, we need to - // make the context current here. This is taken care of by deleteBackingStore(). + //needs to be deleted first. extra->topextra->backingStoreTracker.destroy(); deleteBackingStore(this); @@ -6945,6 +6921,9 @@ bool QWidget::isActiveWindow() const /*! Puts the \a second widget after the \a first widget in the focus order. + It effectively removes the \a second widget from its focus chain and + inserts it after the \a first widget. + Note that since the tab order of the \a second widget is changed, you should order a chain like this: @@ -6957,11 +6936,19 @@ bool QWidget::isActiveWindow() const If \a first or \a second has a focus proxy, setTabOrder() correctly substitutes the proxy. + \note Since Qt 5.10: A widget that has a child as focus proxy is understood as + a compound widget. When setting a tab order between one or two compound widgets, the + local tab order inside each will be preserved. This means that if both widgets are + compound widgets, the resulting tab order will be from the last child inside + \a first, to the first child inside \a second. + \sa setFocusPolicy(), setFocusProxy(), {Keyboard Focus in Widgets} */ void QWidget::setTabOrder(QWidget* first, QWidget *second) { - if (!first || !second || first->focusPolicy() == Qt::NoFocus || second->focusPolicy() == Qt::NoFocus) + if (!first || !second || first == second + || first->focusPolicy() == Qt::NoFocus + || second->focusPolicy() == Qt::NoFocus) return; if (Q_UNLIKELY(first->window() != second->window())) { @@ -6969,54 +6956,56 @@ void QWidget::setTabOrder(QWidget* first, QWidget *second) return; } - QWidget *fp = first->focusProxy(); - if (fp) { - // If first is redirected, set first to the last child of first - // that can take keyboard focus so that second is inserted after - // that last child, and the focus order within first is (more - // likely to be) preserved. - QList<QWidget *> l = first->findChildren<QWidget *>(); - for (int i = l.size()-1; i >= 0; --i) { - QWidget * next = l.at(i); - if (next->window() == fp->window()) { - fp = next; - if (fp->focusPolicy() != Qt::NoFocus) - break; - } - } - first = fp; - } + auto determineLastFocusChild = [](QWidget *target, QWidget *&lastFocusChild) + { + // Since we need to repeat the same logic for both 'first' and 'second', we add a function that + // determines the last focus child for a widget, taking proxies and compound widgets into account. + // If the target is not a compound widget (it doesn't have a focus proxy that points to a child), + // 'lastFocusChild' will be set to the target itself. + lastFocusChild = target; + + QWidget *focusProxy = target->d_func()->deepestFocusProxy(); + if (!focusProxy || !target->isAncestorOf(focusProxy)) + return; - if (fp == second) - return; + lastFocusChild = focusProxy; - if (QWidget *sp = second->focusProxy()) - second = sp; + for (QWidget *focusNext = lastFocusChild->d_func()->focus_next; + focusNext != focusProxy && target->isAncestorOf(focusNext) && focusNext->window() == focusProxy->window(); + focusNext = focusNext->d_func()->focus_next) { + if (focusNext->focusPolicy() != Qt::NoFocus) + lastFocusChild = focusNext; + } + }; -// QWidget *fp = first->d_func()->focus_prev; - QWidget *fn = first->d_func()->focus_next; + QWidget *lastFocusChildOfFirst, *lastFocusChildOfSecond; + determineLastFocusChild(first, lastFocusChildOfFirst); + determineLastFocusChild(second, lastFocusChildOfSecond); - if (fn == second || first == second) + // If the tab order is already correct, exit early + if (lastFocusChildOfFirst->d_func()->focus_next == second) return; - QWidget *sp = second->d_func()->focus_prev; - QWidget *sn = second->d_func()->focus_next; - - fn->d_func()->focus_prev = second; - first->d_func()->focus_next = second; - - second->d_func()->focus_next = fn; - second->d_func()->focus_prev = first; - - sp->d_func()->focus_next = sn; - sn->d_func()->focus_prev = sp; - - - Q_ASSERT(first->d_func()->focus_next->d_func()->focus_prev == first); - Q_ASSERT(first->d_func()->focus_prev->d_func()->focus_next == first); - - Q_ASSERT(second->d_func()->focus_next->d_func()->focus_prev == second); - Q_ASSERT(second->d_func()->focus_prev->d_func()->focus_next == second); + // Note that we need to handle two different sections in the tab chain; The section + // that 'first' belongs to (firstSection), where we are about to insert 'second', and + // the section that 'second' used be a part of (secondSection). When we pull 'second' + // out of the second section and insert it into the first, we also need to ensure + // that we leave the second section in a connected state. + QWidget *firstChainOldSecond = lastFocusChildOfFirst->d_func()->focus_next; + QWidget *secondChainNewFirst = second->d_func()->focus_prev; + QWidget *secondChainNewSecond = lastFocusChildOfSecond->d_func()->focus_next; + + // Insert 'second' after 'first' + lastFocusChildOfFirst->d_func()->focus_next = second; + second->d_func()->focus_prev = lastFocusChildOfFirst; + + // The widget that used to be 'second' in the first section, should now become 'third' + lastFocusChildOfSecond->d_func()->focus_next = firstChainOldSecond; + firstChainOldSecond->d_func()->focus_prev = lastFocusChildOfSecond; + + // Repair the second section after we pulled 'second' out of it + secondChainNewFirst->d_func()->focus_next = secondChainNewSecond; + secondChainNewSecond->d_func()->focus_prev = secondChainNewFirst; } /*!\internal diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index bb421927db..52080fe05f 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -143,10 +143,8 @@ void QWidgetBackingStore::qt_flush(QWidget *widget, const QRegion ®ion, QBack // WA_TranslucentBackground. Therefore the compositor needs to know whether the app intends // to rely on translucency, in order to decide if it should clear to transparent or opaque. const bool translucentBackground = widget->testAttribute(Qt::WA_TranslucentBackground); - // Use the tlw's context, not widget's. The difference is important with native child - // widgets where tlw != widget. - backingStore->handle()->composeAndFlush(widget->windowHandle(), effectiveRegion, offset, widgetTextures, - tlw->d_func()->shareContext(), translucentBackground); + backingStore->handle()->composeAndFlush(widget->windowHandle(), effectiveRegion, offset, + widgetTextures, translucentBackground); widget->window()->d_func()->sendComposeStatus(widget->window(), true); } else #endif diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index d30154410c..319eccf223 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -96,6 +96,7 @@ public: } QRectF closestAcceptableGeometry(const QRectF &rect) const Q_DECL_OVERRIDE; + QOpenGLContext *shareContext() const override; }; QRectF QWidgetWindowPrivate::closestAcceptableGeometry(const QRectF &rect) const @@ -127,6 +128,13 @@ QRectF QWidgetWindowPrivate::closestAcceptableGeometry(const QRectF &rect) const return result; } +QOpenGLContext *QWidgetWindowPrivate::shareContext() const +{ + Q_Q(const QWidgetWindow); + const QWidgetPrivate *widgetPrivate = QWidgetPrivate::get(q->widget()); + return widgetPrivate->shareContext(); +} + QWidgetWindow::QWidgetWindow(QWidget *widget) : QWindow(*new QWidgetWindowPrivate(), 0) , m_widget(widget) |