From ba7f76dea029bc56288ecb46925f5104c6915a71 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 26 Jan 2016 10:49:31 +0100 Subject: winrt: Add support for offscreen surfaces Previously offscreen surfaces were only needed to properly shutdown Qt Quick applications and the scene graph to have something to potentially render into but not show on the screen. However, Canvas3D requires a fully functional surface, preferably offscreen. Hence we use the QEGLPbuffer provided by eglconvenience in platformsupport. Task-number: QTBUG-50576 Change-Id: I1a32820bb2f2c6823be4e96dd92cf7965566f2c3 Reviewed-by: Miikka Heikkinen Reviewed-by: Andrew Knight --- src/plugins/platforms/winrt/qwinrteglcontext.cpp | 21 ++++++++++++----- src/plugins/platforms/winrt/qwinrteglcontext.h | 2 ++ src/plugins/platforms/winrt/qwinrtintegration.cpp | 28 +++++++++++++++++------ 3 files changed, 38 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.cpp b/src/plugins/platforms/winrt/qwinrteglcontext.cpp index bc77df566e..882a7a6913 100644 --- a/src/plugins/platforms/winrt/qwinrteglcontext.cpp +++ b/src/plugins/platforms/winrt/qwinrteglcontext.cpp @@ -49,6 +49,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -148,14 +149,17 @@ bool QWinRTEGLContext::makeCurrent(QPlatformSurface *windowSurface) Q_D(QWinRTEGLContext); Q_ASSERT(windowSurface->surface()->supportsOpenGL()); - if (windowSurface->surface()->surfaceClass() == QSurface::Offscreen) - return false; + EGLSurface surface; + if (windowSurface->surface()->surfaceClass() == QSurface::Window) { + QWinRTWindow *window = static_cast(windowSurface); + if (window->eglSurface() == EGL_NO_SURFACE) + window->createEglSurface(g->eglDisplay, d->eglConfig); - QWinRTWindow *window = static_cast(windowSurface); - if (window->eglSurface() == EGL_NO_SURFACE) - window->createEglSurface(g->eglDisplay, d->eglConfig); + surface = window->eglSurface(); + } else { // Offscreen + surface = static_cast(windowSurface)->pbuffer(); + } - EGLSurface surface = window->eglSurface(); if (surface == EGL_NO_SURFACE) return false; @@ -346,4 +350,9 @@ QFunctionPointer QWinRTEGLContext::getProcAddress(const QByteArray &procName) return eglGetProcAddress(procName.constData()); } +EGLDisplay QWinRTEGLContext::display() +{ + return g->eglDisplay; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.h b/src/plugins/platforms/winrt/qwinrteglcontext.h index 31a2124b03..49b289cd79 100644 --- a/src/plugins/platforms/winrt/qwinrteglcontext.h +++ b/src/plugins/platforms/winrt/qwinrteglcontext.h @@ -38,6 +38,7 @@ #define QWINDOWSEGLCONTEXT_H #include +#include QT_BEGIN_NAMESPACE @@ -57,6 +58,7 @@ public: QSurfaceFormat format() const Q_DECL_OVERRIDE; QFunctionPointer getProcAddress(const QByteArray &procName) Q_DECL_OVERRIDE; + static EGLDisplay display(); private: QScopedPointer d_ptr; Q_DECLARE_PRIVATE(QWinRTEGLContext) diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp index 2281bf56cc..9dac667ce5 100644 --- a/src/plugins/platforms/winrt/qwinrtintegration.cpp +++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp @@ -45,12 +45,17 @@ #include "qwinrtfontdatabase.h" #include "qwinrttheme.h" -#include +#include #include -#include +#include +#include +#include +#include #include +#include + #include #include #include @@ -385,11 +390,20 @@ HRESULT QWinRTIntegration::onResume(IInspectable *, IInspectable *) QPlatformOffscreenSurface *QWinRTIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const { - // This is only used for shutdown of applications. - // In case we do not return an empty surface the scenegraph will try - // to create a new native window during application exit causing crashes - // or assertions. - return new QPlatformOffscreenSurface(surface); + QEGLPbuffer *pbuffer = nullptr; + HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([&pbuffer, surface]() { + pbuffer = new QEGLPbuffer(QWinRTEGLContext::display(), surface->requestedFormat(), surface); + return S_OK; + }); + if (hr == UI_E_WINDOW_CLOSED) { + // This is only used for shutdown of applications. + // In case we do not return an empty surface the scenegraph will try + // to create a new native window during application exit causing crashes + // or assertions. + return new QPlatformOffscreenSurface(surface); + } + + return pbuffer; } -- cgit v1.2.3 From a67a905190b85b53c30c9cb800b5e282d9364179 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 26 Jan 2016 14:45:46 +0100 Subject: Fix artihmetic exception when using non-scalable fonts For non-scalable fonts, the units_per_EM in FreeType is documented to be undefined and will default to 0, which means that any division by it will cause an exception. The emSquareSize() function already checks if the font is scalable and returns y_ppem if not, so lets use it instead in all locations where we're not already sure the font is scalable. [ChangeLog][Text][Freetype] Fixed a divide-by-zero exception when accessing bitmap fonts. Change-Id: I8839d4c83047fb3f6bb4d69af0258e94a258a4d9 Task-number: QTBUG-45963 Reviewed-by: Konstantin Ritt --- src/gui/text/qfontengine_ft.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 4dd2ee35b1..de5bec6f93 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -1255,7 +1255,7 @@ QFixed QFontEngineFT::xHeight() const TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2); if (os2 && os2->sxHeight) { lockFace(); - QFixed answer = QFixed(os2->sxHeight*freetype->face->size->metrics.y_ppem)/freetype->face->units_per_EM; + QFixed answer = QFixed(os2->sxHeight * freetype->face->size->metrics.y_ppem) / emSquareSize(); unlockFace(); return answer; } @@ -1267,7 +1267,7 @@ QFixed QFontEngineFT::averageCharWidth() const TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2); if (os2 && os2->xAvgCharWidth) { lockFace(); - QFixed answer = QFixed(os2->xAvgCharWidth*freetype->face->size->metrics.x_ppem)/freetype->face->units_per_EM; + QFixed answer = QFixed(os2->xAvgCharWidth * freetype->face->size->metrics.x_ppem) / emSquareSize(); unlockFace(); return answer; } @@ -1295,7 +1295,7 @@ void QFontEngineFT::doKerning(QGlyphLayout *g, QFontEngine::ShaperFlags flags) c kerning_pairs_loaded = true; lockFace(); if (freetype->face->size->metrics.x_ppem != 0) { - QFixed scalingFactor(freetype->face->units_per_EM/freetype->face->size->metrics.x_ppem); + QFixed scalingFactor = emSquareSize() / QFixed(freetype->face->size->metrics.x_ppem); unlockFace(); const_cast(this)->loadKerningPairs(scalingFactor); } else { -- cgit v1.2.3 From 14ef6abd0b8bb877edc0c479cd8a0067a4346c70 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Mon, 25 Jan 2016 11:26:09 +0100 Subject: Accessibility OS X: protect from accessing invalid objects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Usually when getting an object from an interface, the object can be assumed to be valid. We need to check isValid though since the screen reader access is inherently asynchronous and objects might be in the QWidget destructor where the QObject is still valid. Thus check QAccessibleInterface::isValid in all uses of it in the OS X implementation. Task-number: QTBUG-50545 Change-Id: I6e142f6ead1b3281cab2cbc61ce1406bbfe29f69 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoaaccessibility.mm | 2 +- .../platforms/cocoa/qcocoaaccessibilityelement.mm | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm index 723c341e59..624220ae5e 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm @@ -51,7 +51,7 @@ QCocoaAccessibility::~QCocoaAccessibility() void QCocoaAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event) { - if (!isActive() || !event->accessibleInterface()) + if (!isActive() || !event->accessibleInterface() || !event->accessibleInterface()->isValid()) return; QMacAccessibilityElement *element = [QMacAccessibilityElement elementWithId: event->uniqueId()]; if (!element) { diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index 608a7583c0..f554bbfe90 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -120,7 +120,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of if (!element) { QAccessibleInterface *iface = QAccessible::accessibleInterface(anId); Q_ASSERT(iface); - if (!iface) + if (!iface || !iface->isValid()) return nil; element = [[self alloc] initWithId:anId]; cache->insertElement(anId, element); @@ -172,7 +172,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of static NSArray *defaultAttributes = nil; QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface) + if (!iface || !iface->isValid()) return defaultAttributes; if (defaultAttributes == nil) { @@ -226,7 +226,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (id)parentElement { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface) + if (!iface || !iface->isValid()) return nil; if (QWindow *window = iface->window()) { @@ -259,7 +259,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (id)accessibilityAttributeValue:(NSString *)attribute { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface) { + if (!iface || !iface->isValid()) { qWarning() << "Called attribute on invalid object: " << axid; return nil; } @@ -354,7 +354,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (NSArray *)accessibilityParameterizedAttributeNames { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface) { + if (!iface || !iface->isValid()) { qWarning() << "Called attribute on invalid object: " << axid; return nil; } @@ -379,7 +379,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (id)accessibilityAttributeValue:(NSString *)attribute forParameter:(id)parameter { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface) { + if (!iface || !iface->isValid()) { qWarning() << "Called attribute on invalid object: " << axid; return nil; } @@ -446,7 +446,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface) + if (!iface || !iface->isValid()) return NO; if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) { @@ -465,7 +465,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface) + if (!iface || !iface->isValid()) return; if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) { if (QAccessibleActionInterface *action = iface->actionInterface()) @@ -494,7 +494,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (NSArray *)accessibilityActionNames { NSMutableArray * nsActions = [NSMutableArray new]; QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface) + if (!iface || !iface->isValid()) return nsActions; const QStringList &supportedActionNames = QAccessibleBridgeUtils::effectiveActionNames(iface); @@ -509,7 +509,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (NSString *)accessibilityActionDescription:(NSString *)action { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface) + if (!iface || !iface->isValid()) return nil; // FIXME is that the right return type?? QString qtAction = QCocoaAccessible::translateAction(action, iface); QString description; -- cgit v1.2.3 From 4c8cb329d458196105d73f08426c8f3b18d61ec7 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Mon, 25 Jan 2016 12:28:25 +0100 Subject: Accessibility OS X: Fix hang when editing password line edits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a regression when entering data in a password field. The important part is to simply not call convertLineOffset for single line text edits. The reason is that the function when dealing with password fields gets an empty string back when calling textAt etc. This is good since we don't want to leak passwords through a11y apis. The problem with the functions returning empty strings is that we end up in an infinite loop in convertLineOffset. Task-number: QTBUG-49437 Change-Id: I76faa7e33e3ad5c3aeb5c75d8c4b93f1b8227bfc Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index f554bbfe90..081bf927d9 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -336,9 +336,11 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of } else if ([attribute isEqualToString:NSAccessibilityInsertionPointLineNumberAttribute]) { if (QAccessibleTextInterface *text = iface->textInterface()) { - int line = -1; - int position = text->cursorPosition(); - convertLineOffset(text, &line, &position); + int line = 0; // true for all single line edits + if (iface->state().multiLine) { + int position = text->cursorPosition(); + convertLineOffset(text, &line, &position); + } return [NSNumber numberWithInt: line]; } return nil; -- cgit v1.2.3 From 3f482fad3c136b1b2f485dce823985bfa0922a3e Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 27 Jan 2016 08:44:44 +0100 Subject: Revert some changes to QTextCursor constructors This partially reverts the source and binary incompatible parts of change d921a9bd157b04242722ab4326c5f2ea8e88cbea that made public members in an exported class private and changed signature in one case. Task-number: QTBUG-50703 Change-Id: I2719f276256206347d3c27d80a16db34a4ea2888 Reviewed-by: Lars Knoll --- src/gui/text/qtextcursor.cpp | 4 ++-- src/gui/text/qtextcursor.h | 5 ++--- src/gui/text/qtextcursor_p.h | 2 +- src/gui/text/qtextdocument_p.cpp | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index dfb6c9c471..eb51447105 100644 --- a/src/gui/text/qtextcursor.cpp +++ b/src/gui/text/qtextcursor.cpp @@ -1072,8 +1072,8 @@ QTextCursor::QTextCursor(const QTextBlock &block) /*! \internal */ -QTextCursor::QTextCursor(QTextDocumentPrivate &p, int pos) - : d(new QTextCursorPrivate(&p)) +QTextCursor::QTextCursor(QTextDocumentPrivate *p, int pos) + : d(new QTextCursorPrivate(p)) { d->adjusted_anchor = d->anchor = d->position = pos; diff --git a/src/gui/text/qtextcursor.h b/src/gui/text/qtextcursor.h index c5462b2936..d42d7a1a70 100644 --- a/src/gui/text/qtextcursor.h +++ b/src/gui/text/qtextcursor.h @@ -61,6 +61,8 @@ class Q_GUI_EXPORT QTextCursor public: QTextCursor(); explicit QTextCursor(QTextDocument *document); + QTextCursor(QTextDocumentPrivate *p, int pos); + explicit QTextCursor(QTextCursorPrivate *d); explicit QTextCursor(QTextFrame *frame); explicit QTextCursor(const QTextBlock &block); QTextCursor(const QTextCursor &cursor); @@ -219,9 +221,6 @@ public: QTextDocument *document() const; private: - QTextCursor(QTextDocumentPrivate &p, int pos); - explicit QTextCursor(QTextCursorPrivate *d); - QSharedDataPointer d; friend class QTextCursorPrivate; friend class QTextDocumentPrivate; diff --git a/src/gui/text/qtextcursor_p.h b/src/gui/text/qtextcursor_p.h index 983ff13742..d3cb52d94f 100644 --- a/src/gui/text/qtextcursor_p.h +++ b/src/gui/text/qtextcursor_p.h @@ -101,7 +101,7 @@ public: void aboutToRemoveCell(int from, int to); static QTextCursor fromPosition(QTextDocumentPrivate *d, int pos) - { return QTextCursor(*d, pos); } + { return QTextCursor(d, pos); } QTextDocumentPrivate *priv; qreal x; diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp index e5dcfb2e55..587844c1dd 100644 --- a/src/gui/text/qtextdocument_p.cpp +++ b/src/gui/text/qtextdocument_p.cpp @@ -1704,7 +1704,7 @@ bool QTextDocumentPrivate::ensureMaximumBlockCount() beginEditBlock(); const int blocksToRemove = blocks.numNodes() - maximumBlockCount; - QTextCursor cursor(*this, 0); + QTextCursor cursor(this, 0); cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor, blocksToRemove); unreachableCharacterCount += cursor.selectionEnd() - cursor.selectionStart(); -- cgit v1.2.3 From 0192ab52e2f14d5914755af5ceb24172f11b6bc7 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 26 Jan 2016 12:28:45 +0100 Subject: Fix widget texture list locking to avoid animation issues on eglfs QWidgetBackingStore::sync() has two variants. The widget texture list logic was only present in one of them. This led to problems on eglfs in cases when the other variant got invoked. (for instance using the scroll area in the qopenglwidget example) eglfs relies on the texture lists's lock status to properly serialize its somewhat asynchronous built-in compositing mechanism and therefore is the only platform affected. The patch moves the code to be invoked from both sync() variants. Task-number: QTBUG-50668 Change-Id: I4c62987b7bb3cc40f98a4e94447368d2f740dbfd Reviewed-by: Paul Olav Tvete --- src/widgets/kernel/qwidgetbackingstore.cpp | 51 +++++++++++++++++------------- src/widgets/kernel/qwidgetbackingstore_p.h | 2 ++ 2 files changed, 31 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index d9d1c887c1..334b6cd463 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -1059,6 +1059,31 @@ static inline bool discardSyncRequest(QWidget *tlw, QTLWExtra *tlwExtra) return false; } +bool QWidgetBackingStore::syncAllowed() +{ +#ifndef QT_NO_OPENGL + QTLWExtra *tlwExtra = tlw->d_func()->maybeTopData(); + if (textureListWatcher && !textureListWatcher->isLocked()) { + textureListWatcher->deleteLater(); + textureListWatcher = 0; + } else if (!tlwExtra->widgetTextures.isEmpty()) { + bool skipSync = false; + foreach (QPlatformTextureList *tl, tlwExtra->widgetTextures) { + if (tl->isLocked()) { + if (!textureListWatcher) + textureListWatcher = new QPlatformTextureListWatcher(this); + if (!textureListWatcher->isLocked()) + textureListWatcher->watch(tl); + skipSync = true; + } + } + if (skipSync) // cannot compose due to widget textures being in use + return false; + } +#endif + return true; +} + /*! Synchronizes the \a exposedRegion of the \a exposedWidget with the backing store. @@ -1089,7 +1114,8 @@ void QWidgetBackingStore::sync(QWidget *exposedWidget, const QRegion &exposedReg else markDirtyOnScreen(exposedRegion, exposedWidget, QPoint()); - doSync(); + if (syncAllowed()) + doSync(); } /*! @@ -1115,27 +1141,8 @@ void QWidgetBackingStore::sync() return; } -#ifndef QT_NO_OPENGL - if (textureListWatcher && !textureListWatcher->isLocked()) { - textureListWatcher->deleteLater(); - textureListWatcher = 0; - } else if (!tlwExtra->widgetTextures.isEmpty()) { - bool skipSync = false; - foreach (QPlatformTextureList *tl, tlwExtra->widgetTextures) { - if (tl->isLocked()) { - if (!textureListWatcher) - textureListWatcher = new QPlatformTextureListWatcher(this); - if (!textureListWatcher->isLocked()) - textureListWatcher->watch(tl); - skipSync = true; - } - } - if (skipSync) // cannot compose due to widget textures being in use - return; - } -#endif - - doSync(); + if (syncAllowed()) + doSync(); } void QWidgetBackingStore::doSync() diff --git a/src/widgets/kernel/qwidgetbackingstore_p.h b/src/widgets/kernel/qwidgetbackingstore_p.h index c45e60ef6e..564dc7f245 100644 --- a/src/widgets/kernel/qwidgetbackingstore_p.h +++ b/src/widgets/kernel/qwidgetbackingstore_p.h @@ -164,6 +164,8 @@ private: void updateLists(QWidget *widget); + bool syncAllowed(); + inline void addDirtyWidget(QWidget *widget, const QRegion &rgn) { if (widget && !widget->d_func()->inDirtyList && !widget->data->in_destructor) { -- cgit v1.2.3 From 48ae2dac07fc15cfbcd79632305ba0f88a850459 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 26 Jan 2016 15:48:19 +0100 Subject: eglfs: fix cleanup when more than one tlw was used There is nothing guaranteeing there is a context current when the backingstore dtor is invoked for widget windows that do not contain render-to-texture widgets. In some cases the eglfs compositor's context is still current, while in other cases (esp. when having popups and other top-levels) there is none. To prevent not releasing the backingstore texture and the incorrect warning about incorrect context, make the correct context current via an offscreen surface, when necessary. Change-Id: Id8257650c1ec8cf96910a4f285b779419c3558a8 Reviewed-by: Paul Olav Tvete --- .../qopenglcompositorbackingstore.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp index fee3146f04..07a1e77c3a 100644 --- a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp +++ b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -82,13 +83,28 @@ QOpenGLCompositorBackingStore::~QOpenGLCompositorBackingStore() { if (m_bsTexture) { QOpenGLContext *ctx = QOpenGLContext::currentContext(); + // With render-to-texture-widgets QWidget makes sure the TLW's shareContext() is + // made current before destroying backingstores. That is however not the case for + // windows with regular widgets only. + QScopedPointer tempSurface; + if (!ctx) { + ctx = QOpenGLCompositor::instance()->context(); + tempSurface.reset(new QOffscreenSurface); + tempSurface->setFormat(ctx->format()); + tempSurface->create(); + ctx->makeCurrent(tempSurface.data()); + } + if (ctx && m_bsTextureContext && ctx->shareGroup() == m_bsTextureContext->shareGroup()) glDeleteTextures(1, &m_bsTexture); else qWarning("QOpenGLCompositorBackingStore: Texture is not valid in the current context"); + + if (tempSurface) + ctx->doneCurrent(); } - delete m_textures; + delete m_textures; // this does not actually own any GL resources } QPaintDevice *QOpenGLCompositorBackingStore::paintDevice() @@ -254,6 +270,7 @@ void QOpenGLCompositorBackingStore::resize(const QSize &size, const QRegion &sta if (m_bsTexture) { glDeleteTextures(1, &m_bsTexture); m_bsTexture = 0; + m_bsTextureContext = Q_NULLPTR; } } -- cgit v1.2.3 From 6774edcef0f9f34d41d1156f6c9748f6d9a18930 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Thu, 28 Jan 2016 16:07:13 +0100 Subject: winrt: set initial window size After creating the swapchain we set an initial size for the content matching the screen size. Only afterwards append it to the canvas. This fixes problems where dialogs were scaled wrongly, sometimes up to 4 times too big. Task-number: QTBUG-50335 Change-Id: Ie3ad9aa3509dfa105ae2ac2b95d2662ff25cdeba Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtwindow.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp index bec94c1e51..034879c478 100644 --- a/src/plugins/platforms/winrt/qwinrtwindow.cpp +++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp @@ -133,6 +133,15 @@ QWinRTWindow::QWinRTWindow(QWindow *window) hr = d->swapChainPanel.As(&d->uiElement); Q_ASSERT_SUCCEEDED(hr); + ComPtr frameworkElement; + hr = d->swapChainPanel.As(&frameworkElement); + Q_ASSERT_SUCCEEDED(hr); + const QSizeF size = QSizeF(d->screen->geometry().size()) / d->screen->scaleFactor(); + hr = frameworkElement->put_Width(size.width()); + Q_ASSERT_SUCCEEDED(hr); + hr = frameworkElement->put_Height(size.height()); + Q_ASSERT_SUCCEEDED(hr); + ComPtr canvas = d->screen->canvas(); ComPtr panel; hr = canvas.As(&panel); -- cgit v1.2.3 From 09e8d69b7a5c6f394b6a43f6c485d26f74189541 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 27 Jan 2016 11:53:25 +0100 Subject: eglfs: Sanitize the widget compositor's context handling createPlatformOpenGLContext() used to silently set the widget compositor's context as the context to share resources with. This works mostly, but is the wrong level to enforce the resource sharing. For example, QOpenGLContext::shareGroup() becomes inconsistent since from QOpenGLContext's view there was no shareContext specified. The inability to test via shareGroup() is the reason eglfs started to show warnings when exiting applications. The resource sharing was in place on EGL level but QOpenGLContext knew nothing about it. Therefore, let's switch over to the way other components, f.ex. Web Engine use: set the internal global share context pointer to the widget compositor's context. This way everything remains consistent: the widget compositor's context is stored upon creating the main QEGLFSWindow, QWidget::shareContext() picks this up then, and as a result we have sharing set up on QOpenGLContext's level instead of sneaking it in in the QPlatformOpenGLContext implementation. Task-number: QTBUG-50707 Change-Id: I5fc1dec58c69c46aa83c7b4cab1eadce6fa633ce Reviewed-by: Paul Olav Tvete --- src/platformsupport/platformcompositor/qopenglcompositor.cpp | 2 +- .../platformcompositor/qopenglcompositorbackingstore.cpp | 8 ++++++++ src/plugins/platforms/eglfs/qeglfsintegration.cpp | 5 +---- src/plugins/platforms/eglfs/qeglfswindow.cpp | 8 ++++++++ 4 files changed, 18 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/platformsupport/platformcompositor/qopenglcompositor.cpp b/src/platformsupport/platformcompositor/qopenglcompositor.cpp index 2e386532e2..7e0973040a 100644 --- a/src/platformsupport/platformcompositor/qopenglcompositor.cpp +++ b/src/platformsupport/platformcompositor/qopenglcompositor.cpp @@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE It is up to the platform plugin to manage the lifetime of the compositor (instance(), destroy()), set the correct destination - context and window as early as possible (setTargetWindow()), + context and window as early as possible (setTarget()), register the composited windows as they are shown, activated, raised and lowered (addWindow(), moveToTop(), etc.), and to schedule repaints (update()). diff --git a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp index 07a1e77c3a..83b551557f 100644 --- a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp +++ b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp @@ -184,6 +184,8 @@ void QOpenGLCompositorBackingStore::flush(QWindow *window, const QRegion ®ion QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); QOpenGLContext *dstCtx = compositor->context(); + Q_ASSERT(dstCtx); + QWindow *dstWin = compositor->targetWindow(); if (!dstWin) return; @@ -209,6 +211,12 @@ void QOpenGLCompositorBackingStore::composeAndFlush(QWindow *window, const QRegi QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); QOpenGLContext *dstCtx = compositor->context(); + Q_ASSERT(dstCtx); // setTarget() must have been called before, e.g. from QEGLFSWindow + + // 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()); + QWindow *dstWin = compositor->targetWindow(); if (!dstWin) return; diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index 2086ce56e2..35b27cba0b 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -188,11 +188,8 @@ QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { - // If there is a "root" window into which raster and QOpenGLWidget content is - // composited, all other contexts must share with its context. - QOpenGLContext *compositingContext = QOpenGLCompositor::instance()->context(); EGLDisplay dpy = context->screen() ? static_cast(context->screen()->handle())->display() : display(); - QPlatformOpenGLContext *share = compositingContext ? compositingContext->handle() : context->shareHandle(); + QPlatformOpenGLContext *share = context->shareHandle(); QVariant nativeHandle = context->nativeHandle(); QEglFSContext *ctx; diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp index 8301be8c17..84856831c3 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.cpp +++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp @@ -138,6 +138,14 @@ void QEglFSWindow::create() if (!context->create()) qFatal("EGLFS: Failed to create compositing context"); compositor->setTarget(context, window()); + // If there is a "root" window into which raster and QOpenGLWidget content is + // composited, all other contexts must share with its context. + if (!qt_gl_global_share_context()) { + qt_gl_set_global_share_context(context); + // What we set up here is in effect equivalent to the application setting + // AA_ShareOpenGLContexts. Set the attribute to be fully consistent. + QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); + } } } -- cgit v1.2.3 From dce530b64eab0666ad22ae5301c2f51b2ee4633f Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 27 Jan 2016 17:02:41 +0100 Subject: Fix bounding rect of glyph runs in multi-line QTextLayout When getting the glyph runs from a QTextLayout with multiple lines, the glyph runs would be merged if possible, but not their bounding rects. This was an oversight. [ChangeLog][Text][QTextLayout] QTextLayout::glyphRuns() now returns united bounding rects for glyph runs that are merged. Change-Id: Ibbeaa99ecfc4e82e7965342efdae7c3c2b637343 Task-number: QTBUG-50715 Reviewed-by: Konstantin Ritt Reviewed-by: Lars Knoll --- src/gui/text/qtextlayout.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 65650504ac..9e2a23a7f7 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1058,12 +1058,15 @@ QList QTextLayout::glyphRuns(int from, int length) const QVector indexes = oldGlyphRun.glyphIndexes(); QVector positions = oldGlyphRun.positions(); + QRectF boundingRect = oldGlyphRun.boundingRect(); indexes += glyphRun.glyphIndexes(); positions += glyphRun.positions(); + boundingRect = boundingRect.united(glyphRun.boundingRect()); oldGlyphRun.setGlyphIndexes(indexes); oldGlyphRun.setPositions(positions); + oldGlyphRun.setBoundingRect(boundingRect); } else { glyphRunHash[key] = glyphRun; } -- cgit v1.2.3 From 2f115fbe0f2ccc0ad25a77c9612588ace9340228 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Fri, 29 Jan 2016 15:24:04 +0100 Subject: Cocoa integration - fix outdated path in QCocoaFileDialogHelper When we set accessory view sometimes (sic!) a delegate's callback fires: -panel:directoryDidChange: with an outdated path (probably because panels are shared?) resetting our current directory; later we open file dialog with a wrong path as result. Change-Id: Iffb02e801c44c5d9a62c2cca3acdf9278eaadb26 Task-number: QTBUG-50140 Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index 9dc013ba4d..4c1b190b9c 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -126,7 +126,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate); if ([mSavePanel respondsToSelector:@selector(setLevel:)]) [mSavePanel setLevel:NSModalPanelWindowLevel]; - [mSavePanel setDelegate:self]; + mReturnCode = -1; mHelper = helper; mNameFilterDropDownList = new QStringList(mOptions->nameFilters()); @@ -147,7 +147,10 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate); [self createTextField]; [self createAccessory]; [mSavePanel setAccessoryView:mNameFilterDropDownList->size() > 1 ? mAccessoryView : nil]; - + // -setAccessoryView: can result in -panel:directoryDidChange: + // resetting our mCurrentDir, set the delegate + // here to make sure it gets the correct value. + [mSavePanel setDelegate:self]; if (mOptions->isLabelExplicitlySet(QFileDialogOptions::Accept)) [mSavePanel setPrompt:[self strip:options->labelText(QFileDialogOptions::Accept)]]; -- cgit v1.2.3 From 758b7b0d88742db7db223a69d689e235e6272f85 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 27 Jan 2016 11:20:45 +0100 Subject: eglfs: Fix up incorrect comments in the backingstore The note about RasterGLSurface leading to calling composeAndFlush() instead of flush() is simply not true. We have to have visible render-to-texture widgets in the window to enter the composeAndFlush() path. Change-Id: I8331b10c75a3fbefc21009c7e5bb2b4de991bf5a Reviewed-by: Paul Olav Tvete --- .../platformcompositor/qopenglcompositorbackingstore.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp index 83b551557f..8ec5d20e05 100644 --- a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp +++ b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp @@ -174,10 +174,7 @@ void QOpenGLCompositorBackingStore::updateTexture() void QOpenGLCompositorBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) { - // Called for ordinary raster windows. This is rare since RasterGLSurface - // support is claimed which leads to having all QWidget windows marked as - // RasterGLSurface instead of just Raster. These go through - // compositeAndFlush() instead of this function. + // Called for ordinary raster windows. Q_UNUSED(region); Q_UNUSED(offset); @@ -202,7 +199,7 @@ void QOpenGLCompositorBackingStore::composeAndFlush(QWindow *window, const QRegi QPlatformTextureList *textures, QOpenGLContext *context, bool translucentBackground) { - // QOpenGLWidget/QQuickWidget content provided as textures. The raster content should go on top. + // QOpenGLWidget/QQuickWidget content provided as textures. The raster content goes on top. Q_UNUSED(region); Q_UNUSED(offset); -- cgit v1.2.3 From 920472c85f6a5cd96344c28dbba0f199c34c6c10 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 27 Jan 2016 18:12:44 +0100 Subject: Fix clipRect interpretation in composited backingstores Empty clipRect means "clip away completely", not "no clipping". Task-number: QTBUG-50719 Change-Id: I6a9dd66130716a921fe9fc245582274e3c9718fe Reviewed-by: Paul Olav Tvete --- src/gui/painting/qplatformbackingstore.cpp | 8 +++++--- src/platformsupport/platformcompositor/qopenglcompositor.cpp | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp index 8e40eb6dff..5ac903c71d 100644 --- a/src/gui/painting/qplatformbackingstore.cpp +++ b/src/gui/painting/qplatformbackingstore.cpp @@ -263,12 +263,14 @@ static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight) static void blitTextureForWidget(const QPlatformTextureList *textures, int idx, QWindow *window, const QRect &deviceWindowRect, QOpenGLTextureBlitter *blitter, const QPoint &offset) { + const QRect clipRect = textures->clipRect(idx); + if (clipRect.isEmpty()) + return; + QRect rectInWindow = textures->geometry(idx); // relative to the TLW, not necessarily our window (if the flush is for a native child widget), have to adjust rectInWindow.translate(-offset); - QRect clipRect = textures->clipRect(idx); - if (clipRect.isEmpty()) - clipRect = QRect(QPoint(0, 0), rectInWindow.size()); + const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft()); const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height()); diff --git a/src/platformsupport/platformcompositor/qopenglcompositor.cpp b/src/platformsupport/platformcompositor/qopenglcompositor.cpp index 7e0973040a..c65d69e842 100644 --- a/src/platformsupport/platformcompositor/qopenglcompositor.cpp +++ b/src/platformsupport/platformcompositor/qopenglcompositor.cpp @@ -177,11 +177,11 @@ static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight) static void clippedBlit(const QPlatformTextureList *textures, int idx, const QRect &targetWindowRect, QOpenGLTextureBlitter *blitter) { - const QRect rectInWindow = textures->geometry(idx); - QRect clipRect = textures->clipRect(idx); + const QRect clipRect = textures->clipRect(idx); if (clipRect.isEmpty()) - clipRect = QRect(QPoint(0, 0), rectInWindow.size()); + return; + const QRect rectInWindow = textures->geometry(idx); const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft()); const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height()); -- cgit v1.2.3 From 09559b5b7991aa94529ad8ee8fe311427fe83834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 1 Feb 2016 17:31:33 +0100 Subject: BIC: Rename back symbol that was mistakenly thought to be private MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Being called from an inline function we were breaking BIC (however insignificant) by renaming the symbol in c7e5e1d9e0. Change-Id: I683bfd53a5ad0de7db0fae6d9aa7d175e00f96ed Reviewed-by: Jędrzej Nowacki --- src/gui/kernel/qwindowsysteminterface.cpp | 2 +- src/testlib/qtestkeyboard.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index a9dcb8bb7d..4bbc303ac0 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -868,7 +868,7 @@ Q_GUI_EXPORT void qt_handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::Keybo QWindowSystemInterface::setSynchronousWindowSystemEvents(wasSynchronous); } -Q_GUI_EXPORT bool qt_handleShortcutEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1) +Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1) { #ifndef QT_NO_SHORTCUT diff --git a/src/testlib/qtestkeyboard.h b/src/testlib/qtestkeyboard.h index aa117ed7de..f80a72e2df 100644 --- a/src/testlib/qtestkeyboard.h +++ b/src/testlib/qtestkeyboard.h @@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE Q_GUI_EXPORT void qt_handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1); -Q_GUI_EXPORT bool qt_handleShortcutEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1); +Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1); namespace QTest { @@ -93,7 +93,7 @@ namespace QTest if (action == Shortcut) { int timestamp = 0; - qt_handleShortcutEvent(window, timestamp, code, modifier, text, repeat); + qt_sendShortcutOverrideEvent(window, timestamp, code, modifier, text, repeat); return; } @@ -174,7 +174,7 @@ namespace QTest QKeyEvent a(press ? QEvent::KeyPress : QEvent::KeyRelease, code, modifier, text, repeat); QSpontaneKeyEvent::setSpontaneous(&a); - if (press && qt_handleShortcutEvent(widget, a.timestamp(), code, modifier, text, repeat)) + if (press && qt_sendShortcutOverrideEvent(widget, a.timestamp(), code, modifier, text, repeat)) return; if (!qApp->notify(widget, &a)) QTest::qWarn("Keyboard event not accepted by receiving widget"); -- cgit v1.2.3 From 46c73be4710a6aa1be84a19151f73d87413a52b4 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 30 Jan 2016 09:48:41 -0800 Subject: Fix livelock at application exit if threads were running This only happened in debug mode, though, because in release mode the warning wasn't printed and the socket notifier was removed. In debug mode, this loop in closingDown() never exited: while (!d->sn_read.isEmpty()) unregisterSocketNotifier((*(d->sn_read.begin()))->obj); [ChangeLog][QtCore][QThread] Fixed a bug that would cause debug-mode applications to live lock on exit if they had a global static containing a QThread that wasn't properly exited. Task-number: QTBUG-49870 Change-Id: I7a9e11d7b64a4cc78e24ffff142e457a4540d6b6 Reviewed-by: Mat Sutcliffe Reviewed-by: Roland Winklmeier Reviewed-by: Friedemann Kleint --- src/corelib/kernel/qeventdispatcher_win.cpp | 17 ++++++++++++----- src/corelib/kernel/qeventdispatcher_win_p.h | 1 + 2 files changed, 13 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 1a14500bd4..b3df139743 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -935,9 +935,8 @@ void QEventDispatcherWin32::registerSocketNotifier(QSocketNotifier *notifier) void QEventDispatcherWin32::unregisterSocketNotifier(QSocketNotifier *notifier) { Q_ASSERT(notifier); - int sockfd = notifier->socket(); - int type = notifier->type(); #ifndef QT_NO_DEBUG + int sockfd = notifier->socket(); if (sockfd < 0) { qWarning("QSocketNotifier: Internal error"); return; @@ -946,8 +945,16 @@ void QEventDispatcherWin32::unregisterSocketNotifier(QSocketNotifier *notifier) return; } #endif + doUnregisterSocketNotifier(notifier); +} +void QEventDispatcherWin32::doUnregisterSocketNotifier(QSocketNotifier *notifier) +{ Q_D(QEventDispatcherWin32); + int type = notifier->type(); + int sockfd = notifier->socket(); + Q_ASSERT(sockfd >= 0); + QSFDict::iterator it = d->active_fd.find(sockfd); if (it != d->active_fd.end()) { QSockFd &sd = it.value(); @@ -1203,11 +1210,11 @@ void QEventDispatcherWin32::closingDown() // clean up any socketnotifiers while (!d->sn_read.isEmpty()) - unregisterSocketNotifier((*(d->sn_read.begin()))->obj); + doUnregisterSocketNotifier((*(d->sn_read.begin()))->obj); while (!d->sn_write.isEmpty()) - unregisterSocketNotifier((*(d->sn_write.begin()))->obj); + doUnregisterSocketNotifier((*(d->sn_write.begin()))->obj); while (!d->sn_except.isEmpty()) - unregisterSocketNotifier((*(d->sn_except.begin()))->obj); + doUnregisterSocketNotifier((*(d->sn_except.begin()))->obj); Q_ASSERT(d->active_fd.isEmpty()); // clean up any timers diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h index 9a53e06730..222562dfce 100644 --- a/src/corelib/kernel/qeventdispatcher_win_p.h +++ b/src/corelib/kernel/qeventdispatcher_win_p.h @@ -103,6 +103,7 @@ public: protected: QEventDispatcherWin32(QEventDispatcherWin32Private &dd, QObject *parent = 0); virtual void sendPostedEvents(); + void doUnregisterSocketNotifier(QSocketNotifier *notifier); private: friend LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp); -- cgit v1.2.3 From 3726c46735edb23ad37af818ff7d52d661ec87e7 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 29 Jan 2016 13:41:38 -0800 Subject: Work around Clang < 3.7 integrated assembler bug PC-relative relocs The qversiontagging.h inline assembly expands to: .long qt_version_tag@GOTPCREL Which, with GCC, Clang >= 3.7 and with the option -no-integrated-as in previous versions, produces the proper relocation (a R_X86_64_GOTPCREL). With Clang < 3.7, it instead produces a R_X86_64_32, which is unsuitable for use in shared libraries: 32-bit displacement is insufficiently wide and would produce linker errors like obj/qftp.o: requires dynamic R_X86_64_32 reloc against 'qt_version_tag' which may overflow at runtime; recompile with -fPIC Instead, force a 64-bit relocation (an R_X86_64_GOT64), which like the 32-bit version is simply an offset into the GOT of where the address of the symbol is stored. Task-number: QTBUG-50749 Change-Id: I7a9e11d7b64a4cc78e24ffff142e039c172b802c Reviewed-by: Simon Hausmann --- src/corelib/global/qversiontagging.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src') diff --git a/src/corelib/global/qversiontagging.h b/src/corelib/global/qversiontagging.h index d6b4a65600..953f669501 100644 --- a/src/corelib/global/qversiontagging.h +++ b/src/corelib/global/qversiontagging.h @@ -59,11 +59,7 @@ QT_BEGIN_NAMESPACE #elif defined(Q_CC_GNU) && !defined(Q_OS_ANDROID) # if defined(Q_PROCESSOR_X86) && (defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD_KERNEL)) # if defined(Q_PROCESSOR_X86_64) // x86-64 or x32 -# if defined(__code_model_large__) -# define QT_VERSION_TAG_RELOC(sym) ".quad " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOT\n" -# else -# define QT_VERSION_TAG_RELOC(sym) ".long " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOTPCREL\n" -# endif +# define QT_VERSION_TAG_RELOC(sym) ".quad " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOT\n" # else // x86 # define QT_VERSION_TAG_RELOC(sym) ".long " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOT\n" # endif -- cgit v1.2.3 From ccf74b592809e0c5a613eff27d6431a4c659e368 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 29 Jan 2016 13:27:53 -0800 Subject: Fix build on FreeBSD: 'environ' is not defined in a library On FreeBSD, this variable is defined as a common symbol in the object file /usr/lib/crt1.o, which is injected into the final application by the compiler. This means when linking any library, 'environ' cannot be found and we can't use -Wl,-no-undefined on FreeBSD. I don't know why this wasn't caught before. Most likely, we failed to pass the linker flag until some recent change to the buildsystem. qprocess_unix.cpp:279: undefined reference to `environ' Change-Id: I7a9e11d7b64a4cc78e24ffff142e02dbf188bca5 Reviewed-by: Simon Hausmann Reviewed-by: Oswald Buddenhagen --- src/corelib/corelib.pro | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro index 5cd0bde87b..ab3f29e2c7 100644 --- a/src/corelib/corelib.pro +++ b/src/corelib/corelib.pro @@ -27,6 +27,10 @@ ANDROID_PERMISSIONS = \ android.permission.INTERNET \ android.permission.WRITE_EXTERNAL_STORAGE +# QtCore can't be compiled with -Wl,-no-undefined because it uses the "environ" +# variable and on FreeBSD, this variable is in the final executable itself +freebsd: QMAKE_LFLAGS_NOUNDEF = + load(qt_module) load(qfeatures) -- cgit v1.2.3 From 38e602d0f2e4c292296d603fda22b366d8879daf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Tue, 26 Jan 2016 13:46:28 +0100 Subject: Fix QT_DEPRECATED_SINCE usage The deprecation was introduced in 5.6 Change-Id: Ief6b749b40ec75c3c9f904caed8447bfb5ef5439 Reviewed-by: Marc Mutz Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/tools/qshareddata.h | 2 +- src/corelib/tools/qsharedpointer_impl.h | 2 +- src/dbus/qdbusextratypes.h | 2 +- src/gui/kernel/qopenglcontext.h | 2 +- src/gui/opengl/qopenglversionfunctions.h | 2 +- src/network/ssl/qsslellipticcurve.h | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/corelib/tools/qshareddata.h b/src/corelib/tools/qshareddata.h index 6a0900cf3f..bc81135d7a 100644 --- a/src/corelib/tools/qshareddata.h +++ b/src/corelib/tools/qshareddata.h @@ -36,7 +36,7 @@ #include #include -#if QT_DEPRECATED_SINCE(5, 5) +#if QT_DEPRECATED_SINCE(5, 6) #include #endif #include diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index bd98cb326c..70b100d018 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -55,7 +55,7 @@ QT_END_NAMESPACE #include #include #include // for qobject_cast -#if QT_DEPRECATED_SINCE(5, 5) +#if QT_DEPRECATED_SINCE(5, 6) #include #endif #include diff --git a/src/dbus/qdbusextratypes.h b/src/dbus/qdbusextratypes.h index 8495b3a320..adbc371fdf 100644 --- a/src/dbus/qdbusextratypes.h +++ b/src/dbus/qdbusextratypes.h @@ -39,7 +39,7 @@ #include #include #include -#if QT_DEPRECATED_SINCE(5, 5) +#if QT_DEPRECATED_SINCE(5, 6) #include #endif #include diff --git a/src/gui/kernel/qopenglcontext.h b/src/gui/kernel/qopenglcontext.h index 841967a545..a658f24ac5 100644 --- a/src/gui/kernel/qopenglcontext.h +++ b/src/gui/kernel/qopenglcontext.h @@ -54,7 +54,7 @@ #include #include -#if QT_DEPRECATED_SINCE(5, 5) +#if QT_DEPRECATED_SINCE(5, 6) #include #endif #include diff --git a/src/gui/opengl/qopenglversionfunctions.h b/src/gui/opengl/qopenglversionfunctions.h index a5d5677938..695fc76052 100644 --- a/src/gui/opengl/qopenglversionfunctions.h +++ b/src/gui/opengl/qopenglversionfunctions.h @@ -47,7 +47,7 @@ #ifndef QT_NO_OPENGL -#if QT_DEPRECATED_SINCE(5, 5) +#if QT_DEPRECATED_SINCE(5, 6) #include #endif #include diff --git a/src/network/ssl/qsslellipticcurve.h b/src/network/ssl/qsslellipticcurve.h index 5716e3447d..c57453d41f 100644 --- a/src/network/ssl/qsslellipticcurve.h +++ b/src/network/ssl/qsslellipticcurve.h @@ -37,7 +37,7 @@ #include #include #include -#if QT_DEPRECATED_SINCE(5, 5) +#if QT_DEPRECATED_SINCE(5, 6) #include #endif #include -- cgit v1.2.3 From cb6d4d1f16215694547514a6342e47854534223e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 4 Feb 2016 10:18:42 +0100 Subject: Revert "QWidgetWindow: call base class close event impl". The patch causes the window creation on reshowing nested QWidget with native windows to create child windows with 0-parent handles, which can have adverse effects on the various platforms. The patch might be re-applied on top of 73c86fcb400cb91868b56ac05a3b82a3f7ba1a1b. This reverts commit 470c8b68df539ca7356cd6b8596f8323ba3ed779. Task-number: QTBUG-43344 Task-number: QTBUG-50854 Change-Id: I2ad837c3800fc71cccf04d455d1b9c3600b233e7 Reviewed-by: Laszlo Agocs Reviewed-by: Andy Shaw --- src/widgets/kernel/qwidgetwindow.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 6f8d97e028..0de0fe21f2 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -708,7 +708,6 @@ void QWidgetWindow::handleCloseEvent(QCloseEvent *event) { bool is_closing = m_widget->d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent); event->setAccepted(is_closing); - QWindow::event(event); // Call QWindow QCloseEvent handler. } #ifndef QT_NO_WHEELEVENT -- cgit v1.2.3 From d482805856a83f39fdab32c76f10cf7d7d5e2112 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 4 Feb 2016 10:15:59 +0100 Subject: Do not change depth for the backingstore's underlying image The depth cannot change. This means that RGB16 cannot be upgraded to 8565 for example as that would be a 24 bit format whereas the backingstores and the underlying platform may expect a 16 bit format. Task-number: QTBUG-50869 Change-Id: I648b39287d43a80fae8097a33bbf3b8bbdcb8816 Reviewed-by: Friedemann Kleint Reviewed-by: Andreas Holzammer Reviewed-by: Allan Sandfeld Jensen --- src/gui/image/qimage_p.h | 6 ++++++ src/plugins/platforms/windows/qwindowsbackingstore.cpp | 2 +- src/plugins/platforms/xcb/qxcbbackingstore.cpp | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h index f9ad6c0ac0..0c0653e8ab 100644 --- a/src/gui/image/qimage_p.h +++ b/src/gui/image/qimage_p.h @@ -189,6 +189,12 @@ inline QImage::Format qt_alphaVersion(QImage::Format format) return QImage::Format_ARGB32_Premultiplied; } +inline QImage::Format qt_maybeAlphaVersionWithSameDepth(QImage::Format format) +{ + const QImage::Format toFormat = qt_alphaVersion(format); + return qt_depthForFormat(format) == qt_depthForFormat(toFormat) ? toFormat : format; +} + inline QImage::Format qt_alphaVersionForPainting(QImage::Format format) { QImage::Format toFormat = qt_alphaVersion(format); diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.cpp b/src/plugins/platforms/windows/qwindowsbackingstore.cpp index a6b1d0af26..af9d2a5969 100644 --- a/src/plugins/platforms/windows/qwindowsbackingstore.cpp +++ b/src/plugins/platforms/windows/qwindowsbackingstore.cpp @@ -155,7 +155,7 @@ void QWindowsBackingStore::resize(const QSize &size, const QRegion ®ion) if (QImage::toPixelFormat(format).alphaUsage() == QPixelFormat::UsesAlpha) m_alphaNeedsFill = true; else // upgrade but here we know app painting does not rely on alpha hence no need to fill - format = qt_alphaVersionForPainting(format); + format = qt_maybeAlphaVersionWithSameDepth(format); QWindowsNativeImage *oldwni = m_image.data(); QWindowsNativeImage *newwni = new QWindowsNativeImage(size.width(), size.height(), format); diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index c34bea0242..3b04c59e28 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -179,7 +179,7 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QI m_hasAlpha = QImage::toPixelFormat(format).alphaUsage() == QPixelFormat::UsesAlpha; if (!m_hasAlpha) - format = qt_alphaVersionForPainting(format); + format = qt_maybeAlphaVersionWithSameDepth(format); m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, format); m_graphics_buffer = new QXcbShmGraphicsBuffer(&m_qimage); -- cgit v1.2.3 From 786d23bb4966b6697ac04c43158e2312d898e133 Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Wed, 3 Feb 2016 11:53:57 +0100 Subject: Fix dbus wince build interface is a define under wince. This define is included even with standard header includes already. It needs to be undefined for using it. Task-number: QTBUG-50853 Change-Id: Ie44681f03709848e9747a8aec11835c8d62aa409 Reviewed-by: Lars Knoll Reviewed-by: Thiago Macieira --- src/dbus/qdbusabstractinterface.h | 4 ++++ src/dbus/qdbusconnection.cpp | 4 ++++ src/dbus/qdbusintegrator.cpp | 3 +++ 3 files changed, 11 insertions(+) (limited to 'src') diff --git a/src/dbus/qdbusabstractinterface.h b/src/dbus/qdbusabstractinterface.h index 5336dfba38..16071df956 100644 --- a/src/dbus/qdbusabstractinterface.h +++ b/src/dbus/qdbusabstractinterface.h @@ -43,6 +43,10 @@ #include #include +#ifdef interface +#undef interface +#endif + #ifndef QT_NO_DBUS QT_BEGIN_NAMESPACE diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp index 0f2d799b92..7f44272bc3 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -54,6 +54,10 @@ #include +#ifdef interface +#undef interface +#endif + #ifndef QT_NO_DBUS QT_BEGIN_NAMESPACE diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index ebf42b0b06..cd448613d6 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -63,6 +63,9 @@ #include "qdbusthreaddebug_p.h" #include +#ifdef interface +#undef interface +#endif #ifndef QT_NO_DBUS -- cgit v1.2.3 From e4f71b0cb5e52b4762c4c1d681eff08376e7bc0b Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Tue, 2 Feb 2016 14:06:28 +0100 Subject: Crash fix: reject certain malformed bmp images A malformed bmp file header could specify a negative color table size. The bmp handler would then return a QImage that claimed to be valid, but actually was invalid, having an empty color table. This would cause crash later, e.g. when attempting to paint it. Change-Id: I7df7c40867557a82dbcee44c7de061226ff232c0 Reviewed-by: Lars Knoll Reviewed-by: Richard J. Moore --- src/gui/image/qbmphandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp index ef12b23caa..27bab10196 100644 --- a/src/gui/image/qbmphandler.cpp +++ b/src/gui/image/qbmphandler.cpp @@ -294,7 +294,7 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int if (depth != 32) { ncols = bi.biClrUsed ? bi.biClrUsed : 1 << nbits; - if (ncols > 256) // sanity check - don't run out of mem if color table is broken + if (ncols < 1 || ncols > 256) // sanity check - don't run out of mem if color table is broken return false; image.setColorCount(ncols); } -- cgit v1.2.3 From b6630a5181cfc3935b13052e0a32d4008d89cdb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 26 Jan 2016 15:17:09 +0100 Subject: Scale offset as well on QBackingStore flush MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also use the target window ("win") as context instead of d->window. Change-Id: I5b0fa3bb857526e4a4bc9c5e44670593da1dfe7c Task-number: QTBUG-50487 Reviewed-by: Friedemann Kleint Reviewed-by: Morten Johan Sørvig Reviewed-by: Paul Olav Tvete --- src/gui/painting/qbackingstore.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index 8a5a6d4fcf..c39675b0b6 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -106,7 +106,8 @@ void QBackingStore::flush(const QRegion ®ion, QWindow *win, const QPoint &off } #endif - d_ptr->platformBackingStore->flush(win, QHighDpi::toNativeLocalRegion(region, d_ptr->window), offset); + d_ptr->platformBackingStore->flush(win, QHighDpi::toNativeLocalRegion(region, win), + QHighDpi::toNativeLocalPosition(offset, win)); } /*! -- cgit v1.2.3 From 4c1b6cdd292bc571a4104fff8b5b54d47970cca1 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Fri, 5 Feb 2016 09:56:49 +0100 Subject: Support arbitrary strides in the QPlatformBackingStore compositor Otherwise platform backingstores providing QImages with extra pixels would break horribly. The only such platform is wayland for now. Previously the need to support this case was masked by the RGBA8888 image conversion that happened always with wayland due to its ARGB32_Pre format. With the recent improvements this is not done anymore and so the problems became apparent. Task-number: QTBUG-50894 Change-Id: I27d7a1c8e25d152ca1227af1e2c38f7d4b6acbab Reviewed-by: Paul Olav Tvete --- src/gui/painting/qplatformbackingstore.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp index 5ac903c71d..33d5e76e52 100644 --- a/src/gui/painting/qplatformbackingstore.cpp +++ b/src/gui/painting/qplatformbackingstore.cpp @@ -516,7 +516,23 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu if (needsConversion) image = image.convertToFormat(QImage::Format_RGBA8888); + // The image provided by the backingstore may have a stride larger than width * 4, for + // instance on platforms that manually implement client-side decorations. + static const int bytesPerPixel = 4; + const int strideInPixels = image.bytesPerLine() / bytesPerPixel; + const bool hasUnpackRowLength = !ctx->isOpenGLES() || ctx->format().majorVersion() >= 3; + QOpenGLFunctions *funcs = ctx->functions(); + + if (hasUnpackRowLength) { + funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, strideInPixels); + } else if (strideInPixels != image.width()) { + // No UNPACK_ROW_LENGTH on ES 2.0 and yet we would need it. This case is typically + // hit with QtWayland which is rarely used in combination with a ES2.0-only GL + // implementation. Therefore, accept the performance hit and do a copy. + image = image.copy(); + } + if (resized) { if (d_ptr->textureId) funcs->glDeleteTextures(1, &d_ptr->textureId); @@ -538,11 +554,9 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu QRect imageRect = image.rect(); QRect rect = dirtyRegion.boundingRect() & imageRect; - if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) { - funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, image.width()); + if (hasUnpackRowLength) { funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType, - image.constScanLine(rect.y()) + rect.x() * 4); - funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + image.constScanLine(rect.y()) + rect.x() * bytesPerPixel); } else { // if the rect is wide enough it's cheaper to just // extend it instead of doing an image copy @@ -564,6 +578,9 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu } } + if (hasUnpackRowLength) + funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + return d_ptr->textureId; } #endif // QT_NO_OPENGL -- cgit v1.2.3 From f5b9cdbb0844dd149d9b945b28da42d56977f844 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 8 Feb 2016 14:32:18 +0100 Subject: HighDPI: Extend exposed region to avoid artifacts by rounding. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce a special scaling function fromNativeLocalExposedRegion() for exposed regions that uses the floor of the top left point and the ceiling of the bottom right point similarly to how it was done in the XCB plugin in 5.5. Task-number: QTBUG-46615 Task-number: QTBUG-50463 Change-Id: I95e4a571b814357c014605ed79e374a821fa155b Reviewed-by: Błażej Szczygieł Reviewed-by: Morten Johan Sørvig --- src/gui/kernel/qhighdpiscaling_p.h | 21 +++++++++++++++++++++ src/gui/kernel/qwindowsysteminterface.cpp | 3 ++- 2 files changed, 23 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h index 9e33787f53..fac3ae420d 100644 --- a/src/gui/kernel/qhighdpiscaling_p.h +++ b/src/gui/kernel/qhighdpiscaling_p.h @@ -47,6 +47,7 @@ #include #include +#include #include #include #include @@ -382,6 +383,24 @@ inline QRegion fromNativeLocalRegion(const QRegion &pixelRegion, const QWindow * return pointRegion; } +// When mapping expose events to Qt rects: round top/left towards the origin and +// bottom/right away from the origin, making sure that we cover the whole window. +inline QRegion fromNativeLocalExposedRegion(const QRegion &pixelRegion, const QWindow *window) +{ + if (!QHighDpiScaling::isActive()) + return pixelRegion; + + const qreal scaleFactor = QHighDpiScaling::factor(window); + QRegion pointRegion; + foreach (const QRect &rect, pixelRegion.rects()) { + const QPointF topLeftP = QPointF(rect.topLeft()) / scaleFactor; + const QPointF bottomRightP = QPointF(rect.bottomRight()) / scaleFactor; + pointRegion += QRect(QPoint(qFloor(topLeftP.x()), qFloor(topLeftP.y())), + QPoint(qCeil(bottomRightP.x()), qCeil(bottomRightP.y()))); + } + return pointRegion; +} + inline QRegion toNativeLocalRegion(const QRegion &pointRegion, const QWindow *window) { if (!QHighDpiScaling::isActive()) @@ -498,6 +517,8 @@ namespace QHighDpi { template inline T fromNativeLocalRegion(const T &value, ...) { return value; } template inline + T fromNativeLocalExposedRegion(const T &value, ...) { return value; } + template inline T toNativeLocalRegion(const T &value, ...) { return value; } template inline diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index 4bbc303ac0..e10ddf22a7 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -582,7 +582,8 @@ void QWindowSystemInterface::handleThemeChange(QWindow *tlw) void QWindowSystemInterface::handleExposeEvent(QWindow *tlw, const QRegion ®ion) { - QWindowSystemInterfacePrivate::ExposeEvent *e = new QWindowSystemInterfacePrivate::ExposeEvent(tlw, QHighDpi::fromNativeLocalRegion(region, tlw)); + QWindowSystemInterfacePrivate::ExposeEvent *e = + new QWindowSystemInterfacePrivate::ExposeEvent(tlw, QHighDpi::fromNativeLocalExposedRegion(region, tlw)); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } -- cgit v1.2.3 From 8c2b4266002736da499d169a0da187e5cdc5381a Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 9 Feb 2016 15:51:28 +0100 Subject: Account for hinting preference in alpha map bounding box We would ignore the vertical hinting when calculating the bounding box, giving an off-by-one error in the base line of some characters when rendering with PreferVerticalHinting, which is the default when doing High-DPI on Windows. Task-number: QTBUG-50940 Change-Id: I2846765ec044eaf317026ee8c7bb9588257bf05c Reviewed-by: Konstantin Ritt Reviewed-by: Friedemann Kleint Reviewed-by: Alessandro Portale --- src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp index bb4f4b1abd..d99a6caecd 100644 --- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp @@ -759,12 +759,17 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph transform.m21 = matrix.m21(); transform.m22 = matrix.m22(); + DWRITE_RENDERING_MODE renderMode = + fontDef.hintingPreference == QFont::PreferNoHinting + ? DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC + : DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL; + IDWriteGlyphRunAnalysis *glyphAnalysis = NULL; HRESULT hr = m_fontEngineData->directWriteFactory->CreateGlyphRunAnalysis( &glyphRun, 1.0f, &transform, - DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC, + renderMode, DWRITE_MEASURING_MODE_NATURAL, 0.0, 0.0, &glyphAnalysis -- cgit v1.2.3