From 5afc431323454225363dae30e67a1cb909086bf9 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Fri, 16 Oct 2015 13:09:46 +0200 Subject: [PATCH 001/133] Use Node::name if Node::logicalModuleName is empty for qml modules Change-Id: I55693a4f34f0a89ceb326b5eb4b229dd3f91c172 Reviewed-by: Martin Smith --- src/tools/qdoc/qdocindexfiles.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tools/qdoc/qdocindexfiles.cpp b/src/tools/qdoc/qdocindexfiles.cpp index 8961ff71ad..226280132f 100644 --- a/src/tools/qdoc/qdocindexfiles.cpp +++ b/src/tools/qdoc/qdocindexfiles.cpp @@ -900,6 +900,9 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer, if (node->isQmlModule()) { logicalModuleName = node->logicalModuleName(); logicalModuleVersion = node->logicalModuleVersion(); + if (logicalModuleName.isEmpty()) { + logicalModuleName = node->name(); + } if (!logicalModuleName.isEmpty()) { writer.writeAttribute("qml-module-name", logicalModuleName); if (node->isQmlModule()) From 1811e31cdbce08ce59eb673fa64a43192006afd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Fri, 29 May 2015 17:23:37 +0200 Subject: [PATCH 002/133] Android: Improve the way we update layout params for native views. Removing and adding a view each time the layout parameters changes is triggering unnecessary layout updates. The affect of this is not very visible since there are few views in the layout, but the procedure is never the less wasteful. Change-Id: I2540ab519b12c6d3e10457e2e518b439118b966d Reviewed-by: BogDan Vatra --- .../qt5/android/QtActivityDelegate.java | 9 ++---- .../org/qtproject/qt5/android/QtLayout.java | 30 +++++++++++++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index ba3ecfecd6..b7190fd4de 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -312,8 +312,7 @@ public class QtActivityDelegate m_editText.setImeOptions(imeOptions); m_editText.setInputType(inputType); - m_layout.removeView(m_editText); - m_layout.addView(m_editText, new QtLayout.LayoutParams(width, height, x, y)); + m_layout.setLayoutParams(m_editText, new QtLayout.LayoutParams(width, height, x, y), false); m_editText.requestFocus(); m_editText.postDelayed(new Runnable() { @Override @@ -1091,12 +1090,10 @@ public class QtActivityDelegate if (Build.VERSION.SDK_INT < 11 || w <= 0 || h <= 0) { m_activity.openContextMenu(m_layout); } else if (Build.VERSION.SDK_INT < 14) { - m_layout.removeView(m_editText); - m_layout.addView(m_editText, new QtLayout.LayoutParams(w, h, x, y)); + m_layout.setLayoutParams(m_editText, new QtLayout.LayoutParams(w, h, x, y), false); QtPopupMenu.getInstance().showMenu(m_editText); } else { - m_layout.removeView(m_editText); - m_layout.addView(m_editText, new QtLayout.LayoutParams(w, h, x, y)); + m_layout.setLayoutParams(m_editText, new QtLayout.LayoutParams(w, h, x, y), false); QtPopupMenu14.getInstance().showMenu(m_editText); } } diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtLayout.java b/src/android/jar/src/org/qtproject/qt5/android/QtLayout.java index 4d7ca47dde..408636dcf3 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtLayout.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtLayout.java @@ -216,4 +216,34 @@ public class QtLayout extends ViewGroup invalidate(); attachViewToParent(view, index, view.getLayoutParams()); } + + /** + * set the layout params on a child view. + * + * Note: This function adds the child view if it's not in the + * layout already. + */ + public void setLayoutParams(final View childView, + final ViewGroup.LayoutParams params, + final boolean forceRedraw) + { + // Invalid view + if (childView == null) + return; + + // Invalid params + if (!checkLayoutParams(params)) + return; + + // View is already in the layout and can therefore be updated + final boolean canUpdate = (this == childView.getParent()); + + if (canUpdate) { + childView.setLayoutParams(params); + if (forceRedraw) + invalidate(); + } else { + addView(childView, params); + } + } } From 28b57f0e95dfb162064f3b0bd9534725b1070380 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Fri, 12 Jun 2015 15:09:37 +0200 Subject: [PATCH 003/133] Android: Don't show the VK when the state is set to HIDDEN by the user. Don't call showSoftInput() if the state is set to _HIDDEN or _ALWAYS_HIDDEN by the user. Task-number: QTBUG-46528 Change-Id: I5dbaf612cf4f339c5288d6d3292c27cc6217f3af Reviewed-by: BogDan Vatra --- .../qt5/android/QtActivityDelegate.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index b7190fd4de..3e55164419 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -244,12 +244,18 @@ public class QtActivityDelegate if (m_imm == null) return; - if (m_softInputMode == 0 && height > m_layout.getHeight() * 2 / 3) - m_activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); - else if (m_softInputMode == 0) - m_activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); - else + if (m_softInputMode != 0) { m_activity.getWindow().setSoftInputMode(m_softInputMode); + // softInputIsHidden is true if SOFT_INPUT_STATE_HIDDEN or SOFT_INPUT_STATE_ALWAYS_HIDDEN is set. + final boolean softInputIsHidden = (m_softInputMode & WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN) != 0; + if (softInputIsHidden) + return; + } else { + if (height > m_layout.getHeight() * 2 / 3) + m_activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); + else + m_activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); + } int initialCapsMode = 0; int imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_DONE; From 75efe9a0f35e74119b5c86992aa0220ebe3fe71e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Wed, 17 Jun 2015 17:32:55 +0200 Subject: [PATCH 004/133] Android: Remove unused forward declaration. Change-Id: I7c81a542df2a47754c2972a1811c020cd12e2dc2 Reviewed-by: BogDan Vatra --- src/plugins/platforms/android/qandroidplatformscreen.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/platforms/android/qandroidplatformscreen.h b/src/plugins/platforms/android/qandroidplatformscreen.h index 403d6036f0..f4f9cedb70 100644 --- a/src/plugins/platforms/android/qandroidplatformscreen.h +++ b/src/plugins/platforms/android/qandroidplatformscreen.h @@ -49,7 +49,6 @@ QT_BEGIN_NAMESPACE class QAndroidPlatformWindow; -class QAndroidPlatformBackingStore; class QAndroidPlatformScreen: public QObject, public QPlatformScreen, public AndroidSurfaceClient { From 14709d097fbc0b87be4a1ba5c7a09a40b5ae23e2 Mon Sep 17 00:00:00 2001 From: Tim Blechmann Date: Fri, 16 Oct 2015 10:35:07 +0200 Subject: [PATCH 005/133] Fix QCFSocketNotifier in namespaced Qt builds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without QT_BEGIN/END_NAMESPACE, the qt_mac_socket_callback is not resolved as a friend function of QCFSocketNotifier, which is required due to access to private members of QCFSocketNotifier. Change-Id: Ief89e18f8b4f7fc4cb013a33959db1dd90eb9efe Reviewed-by: Tor Arne Vestbø --- src/platformsupport/cfsocketnotifier/qcfsocketnotifier.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/platformsupport/cfsocketnotifier/qcfsocketnotifier.cpp b/src/platformsupport/cfsocketnotifier/qcfsocketnotifier.cpp index c58e0ea78d..b3a85292d0 100644 --- a/src/platformsupport/cfsocketnotifier/qcfsocketnotifier.cpp +++ b/src/platformsupport/cfsocketnotifier/qcfsocketnotifier.cpp @@ -36,6 +36,7 @@ #include #include +QT_BEGIN_NAMESPACE /************************************************************************** Socket Notifiers @@ -301,3 +302,6 @@ void QCFSocketNotifier::enableSocketNotifiers(CFRunLoopObserverRef ref, CFRunLoo } } } + +QT_END_NAMESPACE + From 344b19f8e906183b6f5ed6370966edc711ed6c71 Mon Sep 17 00:00:00 2001 From: Caroline Chao Date: Fri, 17 Apr 2015 15:26:24 +0200 Subject: [PATCH 006/133] Tests: Use blacklist for tst_NetworkSelfTest::ftpProxyServer() Remove the insignificant_tests CONFIG option in favor of a BLACKLIST file. The test blacklisted have been found using CI builds logs. Change-Id: Iac07316862cff9b5085dacdf9f35e691cff09384 Task-number: QTBUG-27571 Reviewed-by: Janne Anttila Reviewed-by: Frederik Gladhorn --- tests/auto/other/networkselftest/BLACKLIST | 4 ++++ tests/auto/other/networkselftest/networkselftest.pro | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 tests/auto/other/networkselftest/BLACKLIST diff --git a/tests/auto/other/networkselftest/BLACKLIST b/tests/auto/other/networkselftest/BLACKLIST new file mode 100644 index 0000000000..4a958b43a5 --- /dev/null +++ b/tests/auto/other/networkselftest/BLACKLIST @@ -0,0 +1,4 @@ +# QTBUG-27571 +[ftpProxyServer] +windows 32bit +windows 64bit diff --git a/tests/auto/other/networkselftest/networkselftest.pro b/tests/auto/other/networkselftest/networkselftest.pro index 22208e02fb..60b45e6b5e 100644 --- a/tests/auto/other/networkselftest/networkselftest.pro +++ b/tests/auto/other/networkselftest/networkselftest.pro @@ -4,5 +4,4 @@ TARGET = tst_networkselftest SOURCES += tst_networkselftest.cpp QT = core core-private network testlib -win32:CONFIG += insignificant_test # QTBUG-27571 DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 From 13b1c23f8b2cdf283703a75f475ddcf06653bf7e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 19 Oct 2015 16:24:50 +0200 Subject: [PATCH 007/133] QLineEdit: Fix visibility handling of side widgets. Compare against isVisibleTo() in QLineEditIconButton::actionEvent() so that action events received before show() are handled correctly. Fix a regression introduced by change 4dccb2ca674e9eafca65da0775254932102c7f4b for handling action events causing side widgets to overlap when added before the widget was shown. Use QAction::isVisible() to determine visibility. Task-number: QTBUG-48806 Task-number: QTBUG-48899 Task-number: QTBUG-39660 Change-Id: I7a39a3b9a094f2c74cde09544f1158deb2b81cf2 Reviewed-by: David Faure --- src/widgets/widgets/qlineedit_p.cpp | 6 +- .../widgets/qlineedit/tst_qlineedit.cpp | 58 +++++++++++++------ 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp index 6645a375a7..e24cc8a03a 100644 --- a/src/widgets/widgets/qlineedit_p.cpp +++ b/src/widgets/widgets/qlineedit_p.cpp @@ -329,7 +329,7 @@ void QLineEditIconButton::actionEvent(QActionEvent *e) switch (e->type()) { case QEvent::ActionChanged: { const QAction *action = e->action(); - if (isVisible() != action->isVisible()) { + if (isVisibleTo(parentWidget()) != action->isVisible()) { setVisible(action->isVisible()); if (QLineEdit *le = qobject_cast(parentWidget())) static_cast(qt_widget_private(le))->positionSideWidgets(); @@ -433,13 +433,13 @@ void QLineEditPrivate::positionSideWidgets() QRect widgetGeometry(QPoint(QLineEditIconButton::IconMargin, (contentRect.height() - iconSize.height()) / 2), iconSize); foreach (const SideWidgetEntry &e, leftSideWidgetList()) { e.widget->setGeometry(widgetGeometry); - if (e.widget->isVisible()) + if (e.action->isVisible()) widgetGeometry.moveLeft(widgetGeometry.left() + delta); } widgetGeometry.moveLeft(contentRect.width() - iconSize.width() - QLineEditIconButton::IconMargin); foreach (const SideWidgetEntry &e, rightSideWidgetList()) { e.widget->setGeometry(widgetGeometry); - if (e.widget->isVisible()) + if (e.action->isVisible()) widgetGeometry.moveLeft(widgetGeometry.left() - delta); } } diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp index e6d63ee4d9..1d70e8a8ab 100644 --- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp @@ -4319,10 +4319,10 @@ void tst_QLineEdit::clearButtonVisibleAfterSettingText_QTBUG_45518() #endif // QT_BUILD_INTERNAL } -static inline QIcon sideWidgetTestIcon() +static inline QIcon sideWidgetTestIcon(Qt::GlobalColor color = Qt::yellow) { QImage image(QSize(20, 20), QImage::Format_ARGB32); - image.fill(Qt::yellow); + image.fill(color); return QIcon(QPixmap::fromImage(image)); } @@ -4360,6 +4360,15 @@ void tst_QLineEdit::sideWidgets() lineEdit->addAction(iconAction); } +template T *findAssociatedWidget(const QAction *a) +{ + foreach (QWidget *w, a->associatedWidgets()) { + if (T *result = qobject_cast(w)) + return result; + } + return Q_NULLPTR; +} + void tst_QLineEdit::sideWidgetsActionEvents() { // QTBUG-39660, verify whether action events are handled by the widget. @@ -4368,28 +4377,43 @@ void tst_QLineEdit::sideWidgetsActionEvents() QLineEdit *lineEdit = new QLineEdit(&testWidget); l->addWidget(lineEdit); l->addSpacerItem(new QSpacerItem(0, 50, QSizePolicy::Ignored, QSizePolicy::Fixed)); - QAction *iconAction = lineEdit->addAction(sideWidgetTestIcon(), QLineEdit::LeadingPosition); + QAction *iconAction1 = lineEdit->addAction(sideWidgetTestIcon(Qt::red), QLineEdit::LeadingPosition); + QAction *iconAction2 = lineEdit->addAction(sideWidgetTestIcon(Qt::blue), QLineEdit::LeadingPosition); + QAction *iconAction3 = lineEdit->addAction(sideWidgetTestIcon(Qt::yellow), QLineEdit::LeadingPosition); + iconAction3->setVisible(false); + testWidget.move(300, 300); testWidget.show(); QVERIFY(QTest::qWaitForWindowExposed(&testWidget)); - QWidget *toolButton = Q_NULLPTR; - foreach (QWidget *w, iconAction->associatedWidgets()) { - if (qobject_cast(w)) { - toolButton = w; - break; - } - } - QVERIFY(toolButton); + QWidget *toolButton1 = findAssociatedWidget(iconAction1); + QWidget *toolButton2 = findAssociatedWidget(iconAction2); + QWidget *toolButton3 = findAssociatedWidget(iconAction3); - QVERIFY(toolButton->isVisible()); - QVERIFY(toolButton->isEnabled()); + QVERIFY(toolButton1); + QVERIFY(toolButton2); + QVERIFY(toolButton3); - iconAction->setEnabled(false); - QVERIFY(!toolButton->isEnabled()); + QVERIFY(!toolButton3->isVisible()); // QTBUG-48899 , action hidden before show(). - iconAction->setVisible(false); - QVERIFY(!toolButton->isVisible()); + QVERIFY(toolButton1->isVisible()); + QVERIFY(toolButton1->isEnabled()); + + QVERIFY(toolButton2->isVisible()); + QVERIFY(toolButton2->isEnabled()); + + const int toolButton1X = toolButton1->x(); + const int toolButton2X = toolButton2->x(); + QVERIFY(toolButton1X < toolButton2X); // QTBUG-48806, positioned beside each other. + + iconAction1->setEnabled(false); + QVERIFY(!toolButton1->isEnabled()); + + iconAction1->setVisible(false); + QVERIFY(!toolButton1->isVisible()); + + // QTBUG-39660, button 2 takes position of invisible button 1. + QCOMPARE(toolButton2->x(), toolButton1X); } Q_DECLARE_METATYPE(Qt::AlignmentFlag) From b50ee28eb52fa23c05a9599e02e9671f7ab42d10 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Thu, 22 Oct 2015 18:36:24 +0200 Subject: [PATCH 008/133] QWidgetAction: Don't deactivate the current window on Mac We check the name of the window class the widget's QNSView changes window and set a flag when the that window is a native Cocoa menu window. Later, only those views not inside a native menu can become first responder, ensuring Qt won't deactivate the main window. We're allowed to reject becoming the first responder mainly because Cocoa itself doesn't support sending key event to menu views and, therefore, it doesn't change what's already possible. This patch also sets the widget action visible, which needs to be done right after reparenting it to the container widget. Besides that, it also contains a few small code cleaning changes related to Cocoa's support of QWidgetAction. Change-Id: Ia2170bdc5e1f40bfa2f1091c05e9e99397c47187 Task-number: QTBUG-44015 Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qcocoamenuitem.mm | 6 ++++-- src/plugins/platforms/cocoa/qnsview.h | 1 + src/plugins/platforms/cocoa/qnsview.mm | 14 +++++++++----- src/widgets/widgets/qmenu.cpp | 2 +- src/widgets/widgets/qmenu_mac.mm | 1 + 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index 942fc8db21..0fc1bff325 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -197,6 +197,8 @@ void QCocoaMenuItem::setEnabled(bool enabled) void QCocoaMenuItem::setNativeContents(WId item) { NSView *itemView = (NSView *)item; + if (m_itemView == itemView) + return; [m_itemView release]; m_itemView = [itemView retain]; [m_itemView setAutoresizesSubviews:YES]; @@ -301,8 +303,8 @@ NSMenuItem *QCocoaMenuItem::sync() if (!m_native) { m_native = [[NSMenuItem alloc] initWithTitle:QCFString::toNSString(m_text) - action:nil - keyEquivalent:@""]; + action:nil + keyEquivalent:@""]; [m_native setTag:reinterpret_cast(this)]; } diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index 028a34af1c..a2890d9b4a 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -77,6 +77,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper)); bool m_scrolling; bool m_exposedOnMoveToWindow; NSEvent *m_currentlyInterpretedKeyEvent; + bool m_isMenuView; } - (id)init; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 8c22e51fe2..6e6e128aed 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -160,6 +160,8 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::NormalizedPosition | QTouchDevice::MouseEmulation); QWindowSystemInterface::registerTouchDevice(touchDevice); } + + m_isMenuView = false; } return self; } @@ -269,11 +271,11 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; - (void)viewDidMoveToWindow { + m_isMenuView = [self.window.className isEqualToString:@"NSCarbonMenuWindow"]; if (self.window) { // This is the case of QWidgetAction's generated QWidget inserted in an NSMenu. // 10.9 and newer get the NSWindowDidChangeOcclusionStateNotification - if ((!_q_NSWindowDidChangeOcclusionStateNotification - && [self.window.className isEqualToString:@"NSCarbonMenuWindow"])) { + if (!_q_NSWindowDidChangeOcclusionStateNotification && m_isMenuView) { m_exposedOnMoveToWindow = true; m_platformWindow->exposeWindow(); } @@ -402,7 +404,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; NSString *notificationName = [windowNotification name]; if (notificationName == NSWindowDidBecomeKeyNotification) { - if (!m_platformWindow->windowIsPopupType()) + if (!m_platformWindow->windowIsPopupType() && !m_isMenuView) QWindowSystemInterface::handleWindowActivated(m_window); } else if (notificationName == NSWindowDidResignKeyNotification) { // key window will be non-nil if another window became key... do not @@ -411,7 +413,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; NSWindow *keyWindow = [NSApp keyWindow]; if (!keyWindow) { // no new key window, go ahead and set the active window to zero - if (!m_platformWindow->windowIsPopupType()) + if (!m_platformWindow->windowIsPopupType() && !m_isMenuView) QWindowSystemInterface::handleWindowActivated(0); } } else if (notificationName == NSWindowDidMiniaturizeNotification @@ -621,13 +623,15 @@ QT_WARNING_POP { if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) return NO; - if (!m_platformWindow->windowIsPopupType()) + if (!m_platformWindow->windowIsPopupType() && !m_isMenuView) QWindowSystemInterface::handleWindowActivated([self topLevelWindow]); return YES; } - (BOOL)acceptsFirstResponder { + if (m_isMenuView) + return NO; if (m_platformWindow->shouldRefuseKeyWindowAndFirstResponder()) return NO; if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 6e37f91197..5453d9d64f 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -1265,7 +1265,7 @@ void QMenuPrivate::_q_platformMenuAboutToShow() #ifdef Q_OS_OSX if (platformMenu) Q_FOREACH (QAction *action, q->actions()) - if (QWidget *widget = widgetItems.value(const_cast(action))) + if (QWidget *widget = widgetItems.value(action)) if (widget->parent() == q) { QPlatformMenuItem *menuItem = platformMenu->menuItemForTag(reinterpret_cast(action)); moveWidgetToPlatformItem(widget, menuItem); diff --git a/src/widgets/widgets/qmenu_mac.mm b/src/widgets/widgets/qmenu_mac.mm index a42879fc73..8b29011178 100644 --- a/src/widgets/widgets/qmenu_mac.mm +++ b/src/widgets/widgets/qmenu_mac.mm @@ -115,6 +115,7 @@ void QMenuPrivate::moveWidgetToPlatformItem(QWidget *widget, QPlatformMenuItem* QObject::connect(platformMenu, SIGNAL(destroyed()), container, SLOT(deleteLater())); container->resize(widget->sizeHint()); widget->setParent(container); + widget->setVisible(true); NSView *containerView = container->nativeView(); QWindow *containerWindow = container->windowHandle(); From b29d18f7366d09c7efe85bbad638159879b29406 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Wed, 22 Jul 2015 13:09:58 +0200 Subject: [PATCH 009/133] Doc: Edit description of QSslSocket::AddCaCertificates() The QSslSocket::addCaCertificates() variant that takes a path argument uses QSslCertificate::fromPath() in its implementation. Edit the description of the former to match that of the latter. Fix minor issues in QSslCertificate::fromPath() documentation; add a missing word, limit code snippet line width. Task-number: QTBUG-47359 Change-Id: Ibead74c998503e60a67d0b8eb551536bd20feff8 Reviewed-by: Venugopal Shivashankar Reviewed-by: Timur Pocheptsov Reviewed-by: Richard J. Moore --- .../doc/snippets/code/src_network_ssl_qsslcertificate.cpp | 3 ++- src/network/ssl/qsslcertificate.cpp | 4 ++-- src/network/ssl/qsslsocket.cpp | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/network/doc/snippets/code/src_network_ssl_qsslcertificate.cpp b/src/network/doc/snippets/code/src_network_ssl_qsslcertificate.cpp index 8abae00b4e..d157af737c 100644 --- a/src/network/doc/snippets/code/src_network_ssl_qsslcertificate.cpp +++ b/src/network/doc/snippets/code/src_network_ssl_qsslcertificate.cpp @@ -39,7 +39,8 @@ ****************************************************************************/ //! [0] -foreach (const QSslCertificate &cert, QSslCertificate::fromPath("C:/ssl/certificate.*.pem", QSsl::Pem, +foreach (const QSslCertificate &cert, QSslCertificate::fromPath("C:/ssl/certificate.*.pem", + QSsl::Pem, QRegExp::Wildcard)) { qDebug() << cert.issuerInfo(QSslCertificate::Organization); } diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index 6f91ccdb4d..22d66770e5 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -446,8 +446,8 @@ QByteArray QSslCertificate::digest(QCryptographicHash::Algorithm algorithm) cons /*! Searches all files in the \a path for certificates encoded in the - specified \a format and returns them in a list. \e must be a file or a - pattern matching one or more files, as specified by \a syntax. + specified \a format and returns them in a list. \a path must be a file + or a pattern matching one or more files, as specified by \a syntax. Example: diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 092a414f99..9b5d90225f 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -1312,8 +1312,8 @@ QList QSslSocket::supportedCiphers() /*! Searches all files in the \a path for certificates encoded in the specified \a format and adds them to this socket's CA certificate - database. \a path can be explicit, or it can contain wildcards in - the format specified by \a syntax. Returns \c true if one or more + database. \a path must be a file or a pattern matching one or more + files, as specified by \a syntax. Returns \c true if one or more certificates are added to the socket's CA certificate database; otherwise returns \c false. From 3890988bb69c2a50d4ebdbcd8c4c7058ac364125 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 22 Oct 2015 10:39:59 +0200 Subject: [PATCH 010/133] Add support for -Zc:throwingNew option to vcxproj generation for 2015 Task-number: QTBUG-48898 Change-Id: I56abae0cbc56e07fd9bb554b84927c327c1b3232 Reviewed-by: Oswald Buddenhagen Reviewed-by: Maurice Kalinowski --- qmake/generators/win32/msvc_objectmodel.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp index 09937c8ac2..1e522cc8ee 100644 --- a/qmake/generators/win32/msvc_objectmodel.cpp +++ b/qmake/generators/win32/msvc_objectmodel.cpp @@ -922,6 +922,8 @@ bool VCCLCompilerTool::parseOption(const char* option) TreatWChar_tAsBuiltInType = ((*c) == '-' ? _False : _True); else if (config->CompilerVersion >= NET2013 && strncmp(option + 4, "strictStrings", 13) == 0) AdditionalOptions += option; + else if (config->CompilerVersion >= NET2015 && strncmp(option + 4, "throwingNew", 11) == 0) + AdditionalOptions += option; else found = false; } else { From 0f543438089dece42a4fda6254c80c19816e1cea Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Fri, 23 Oct 2015 13:45:23 +0200 Subject: [PATCH 011/133] Configure: don't enable the WMF multimedia backend by default. This means we now use DirectShow as default multimedia backend on Windows. Task-number: QTBUG-45597 Change-Id: If95bbb8e7b33d73d80f7ba42de63ac54539e15b8 Reviewed-by: Oswald Buddenhagen --- tools/configure/configureapp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 1fdc4bb657..886a383122 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -165,7 +165,7 @@ Configure::Configure(int& argc, char** argv) : verbose(0) dictionary[ "CETEST" ] = "auto"; dictionary[ "CE_SIGNATURE" ] = "no"; dictionary[ "AUDIO_BACKEND" ] = "auto"; - dictionary[ "WMF_BACKEND" ] = "auto"; + dictionary[ "WMF_BACKEND" ] = "no"; dictionary[ "WMSDK" ] = "auto"; dictionary[ "QML_DEBUG" ] = "yes"; dictionary[ "PLUGIN_MANIFESTS" ] = "no"; From 8a8a5813a9fcbaef4dd96e8c33f605043d51b590 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Fri, 23 Oct 2015 15:12:33 +0300 Subject: [PATCH 012/133] QMenu: Fix a typo EventShouldBePropogated -> EventShouldBePropagated Change-Id: Id9439bd749576d1f7dfcb1653905f5de47b825b4 Reviewed-by: Friedemann Kleint --- src/widgets/widgets/qmenu.cpp | 2 +- src/widgets/widgets/qmenu_p.h | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 5453d9d64f..b29d7de5f5 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -3143,7 +3143,7 @@ void QMenu::mouseMoveEvent(QMouseEvent *e) d->activeMenu->d_func()->setCurrentAction(0); QMenuSloppyState::MouseEventResult sloppyEventResult = d->sloppyState.processMouseEvent(e->localPos(), action, d->currentAction); - if (sloppyEventResult == QMenuSloppyState::EventShouldBePropogated) { + if (sloppyEventResult == QMenuSloppyState::EventShouldBePropagated) { d->setCurrentAction(action, d->mousePopupDelay); } else if (sloppyEventResult == QMenuSloppyState::EventDiscardsSloppyState) { d->sloppyState.reset(); diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h index 3acf73af90..e717d923ae 100644 --- a/src/widgets/widgets/qmenu_p.h +++ b/src/widgets/widgets/qmenu_p.h @@ -126,7 +126,7 @@ public: enum MouseEventResult { EventIsProcessed, - EventShouldBePropogated, + EventShouldBePropagated, EventDiscardsSloppyState }; @@ -187,14 +187,14 @@ public: m_parent->stopTimer(); if (!m_enabled) - return EventShouldBePropogated; + return EventShouldBePropagated; if (!m_time.isActive()) startTimer(); if (!m_sub_menu) { reset(); - return EventShouldBePropogated; + return EventShouldBePropagated; } QSetValueOnDestroy setFirstMouse(m_first_mouse, false); @@ -208,7 +208,7 @@ public: if (m_action_rect.contains(mousePos)) { startTimer(); - return currentAction == m_menu->menuAction() ? EventIsProcessed : EventShouldBePropogated; + return currentAction == m_menu->menuAction() ? EventIsProcessed : EventShouldBePropagated; } if (m_uni_directional && !m_first_mouse && resetAction != m_origin_action) { @@ -247,7 +247,7 @@ public: } - return m_select_other_actions ? EventShouldBePropogated : EventIsProcessed; + return m_select_other_actions ? EventShouldBePropagated : EventIsProcessed; } void setSubMenuPopup(const QRect &actionRect, QAction *resetAction, QMenu *subMenu); From 2cdafb099945bd534f0c752edf8d4f1ab80ed45f Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 23 Oct 2015 16:32:59 +0200 Subject: [PATCH 013/133] Convert some QDateTime::currentDateTime() to currentDateTimeUtc() (I) The latter is much faster as it doesn't have to deal with time zones. This change handles the trivial ones: Either the call to currentDateTime() is immediately followed by a call to toUTC() or toTime_t(). The latter is much faster on UTC QDateTimes, too. Credits to Milian Wolff, from whose QtWS15 talk this advice is taken. Change-Id: I872f5bbb26cbecedc1e5c0dbee4d5ac2c6eb67ee Reviewed-by: Milian Wolff --- src/corelib/plugin/quuid.cpp | 4 ++-- src/gui/painting/qpdf.cpp | 2 +- src/network/access/qnetworkcookie.cpp | 2 +- src/plugins/bearer/qnetworksession_impl.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp index 6698b140af..0e1557941d 100644 --- a/src/corelib/plugin/quuid.cpp +++ b/src/corelib/plugin/quuid.cpp @@ -963,7 +963,7 @@ QUuid QUuid::createUuid() { int *pseed = new int; static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(2); - qsrand(*pseed = QDateTime::currentDateTime().toTime_t() + qsrand(*pseed = QDateTime::currentDateTimeUtc().toTime_t() + quintptr(&pseed) + serial.fetchAndAddRelaxed(1)); uuidseed.setLocalData(pseed); @@ -971,7 +971,7 @@ QUuid QUuid::createUuid() #else static bool seeded = false; if (!seeded) - qsrand(QDateTime::currentDateTime().toTime_t() + qsrand(QDateTime::currentDateTimeUtc().toTime_t() + quintptr(&seeded)); #endif diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index 47483b2869..d746ab9379 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -1498,7 +1498,7 @@ void QPdfEnginePrivate::writeInfo() printString(creator); xprintf("\n/Producer "); printString(QString::fromLatin1("Qt " QT_VERSION_STR)); - QDateTime now = QDateTime::currentDateTime().toUTC(); + QDateTime now = QDateTime::currentDateTimeUtc(); QTime t = now.time(); QDate d = now.date(); xprintf("\n/CreationDate (D:%d%02d%02d%02d%02d%02d)\n", diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index 8a24fc55fd..2d8f192d03 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -901,7 +901,7 @@ QList QNetworkCookiePrivate::parseSetCookieHeaderLine(const QByt // We do not support RFC 2965 Set-Cookie2-style cookies QList result; - QDateTime now = QDateTime::currentDateTime().toUTC(); + const QDateTime now = QDateTime::currentDateTimeUtc(); int position = 0; const int length = cookieString.length(); diff --git a/src/plugins/bearer/qnetworksession_impl.cpp b/src/plugins/bearer/qnetworksession_impl.cpp index 5e9e5e7015..8139040f84 100644 --- a/src/plugins/bearer/qnetworksession_impl.cpp +++ b/src/plugins/bearer/qnetworksession_impl.cpp @@ -279,7 +279,7 @@ quint64 QNetworkSessionPrivateImpl::bytesReceived() const quint64 QNetworkSessionPrivateImpl::activeTime() const { if (state == QNetworkSession::Connected && startTime != Q_UINT64_C(0)) - return QDateTime::currentDateTime().toTime_t() - startTime; + return QDateTime::currentDateTimeUtc().toTime_t() - startTime; return Q_UINT64_C(0); } From f0c915de70575225d0e968a2fbba07b631970a0d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 22 Oct 2015 13:56:48 -0700 Subject: [PATCH 014/133] Autotest: remove AIX-related QT_POINTER_SIZE code This test hasn't been run for years, so clean up. And besides, it's extremely fragile and would depend on how IBM packages their OpenGL libraries. Change-Id: I1d0f78915b5942aab07cffff140f9db5a09ee7e2 Reviewed-by: Oswald Buddenhagen --- tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp b/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp index e87585163b..f31a7af6dd 100644 --- a/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp +++ b/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp @@ -413,15 +413,6 @@ void tst_QLibrary::loadHints_data() QTest::addColumn("result"); QLibrary::LoadHints lh; -#if defined(Q_OS_AIX) - if (QFile::exists("/usr/lib/libGL.a") || QFile::exists("/usr/X11R6/lib/libGL.a")) { -# if QT_POINTER_SIZE == 4 - QTest::newRow( "ok03 (Archive member)" ) << "libGL.a(shr.o)" << int(QLibrary::LoadArchiveMemberHint) << true; -# else - QTest::newRow( "ok03 (Archive member)" ) << "libGL.a(shr_64.o)" << int(QLibrary::LoadArchiveMemberHint) << true; -#endif - } -#endif QString appDir = QCoreApplication::applicationDirPath(); From f3e4769d057a3aa1b8977352caa71b39ab0c24e5 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 22 Oct 2015 13:49:15 -0700 Subject: [PATCH 015/133] Compile the 64-bit version of some code on all 64-bit processors This is true for ILP32 on x86-64, IA-64 and AArch64. Change-Id: I1d0f78915b5942aab07cffff140f9d4c277bb5d4 Reviewed-by: Oswald Buddenhagen --- src/corelib/tools/qcryptographichash.cpp | 2 +- src/gui/painting/qdrawhelper_p.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/tools/qcryptographichash.cpp b/src/corelib/tools/qcryptographichash.cpp index 42877ec664..1c74a602c6 100644 --- a/src/corelib/tools/qcryptographichash.cpp +++ b/src/corelib/tools/qcryptographichash.cpp @@ -65,7 +65,7 @@ typedef HashReturn (SHA3Init)(hashState *state, int hashbitlen); typedef HashReturn (SHA3Update)(hashState *state, const BitSequence *data, DataLength databitlen); typedef HashReturn (SHA3Final)(hashState *state, BitSequence *hashval); -#if QT_POINTER_SIZE == 8 // 64 bit version +#if Q_PROCESSOR_WORDSIZE == 8 // 64 bit version #include "../../3rdparty/sha3/KeccakF-1600-opt64.c" diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 2fb9e7760c..1d70477051 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -588,7 +588,7 @@ static Q_ALWAYS_INLINE uint INTERPOLATE_PIXEL_255(uint x, uint a, uint y, uint b return x; } -#if QT_POINTER_SIZE == 8 // 64-bit versions +#if Q_PROCESSOR_WORDSIZE == 8 // 64-bit versions static Q_ALWAYS_INLINE uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b) { quint64 t = (((quint64(x)) | ((quint64(x)) << 24)) & 0x00ff00ff00ff00ff) * a; @@ -1093,7 +1093,7 @@ const uint qt_bayer_matrix[16][16] = { ((((argb >> 24) * alpha) >> 8) << 24) | (argb & 0x00ffffff) -#if QT_POINTER_SIZE == 8 // 64-bit versions +#if Q_PROCESSOR_WORDSIZE == 8 // 64-bit versions #define AMIX(mask) (qMin(((qint64(s)&mask) + (qint64(d)&mask)), qint64(mask))) #define MIX(mask) (qMin(((qint64(s)&mask) + (qint64(d)&mask)), qint64(mask))) #else // 32 bits From 192606a9fd2c900fa4917a1830439e8bbf8f1d12 Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Fri, 23 Oct 2015 10:40:15 +0300 Subject: [PATCH 016/133] QIpPacketHeader: correct the type of hopLimit member In other places, it's referenced as int. Change-Id: Ic66f33a34d45208686ad0e229644d3ef33c55a62 Reviewed-by: Thiago Macieira --- src/network/socket/qabstractsocketengine_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/socket/qabstractsocketengine_p.h b/src/network/socket/qabstractsocketengine_p.h index d2b5882d18..01b191971f 100644 --- a/src/network/socket/qabstractsocketengine_p.h +++ b/src/network/socket/qabstractsocketengine_p.h @@ -78,7 +78,7 @@ public: QHostAddress destinationAddress; uint ifindex; - qint16 hopLimit; + int hopLimit; quint16 senderPort; quint16 destinationPort; }; From ccca3ffdc26f585f28ce0a8539f96f02adce30dc Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Fri, 23 Oct 2015 11:37:40 +0300 Subject: [PATCH 017/133] QNativeSocketEngine: declare PacketHeaderOption enum as a bit field It should be possible to use these constants simultaneously and to handle them separately from each other. Change-Id: I0c48a3c25456b487c9d6139b05105ada20f34be6 Reviewed-by: Oswald Buddenhagen Reviewed-by: Thiago Macieira --- src/network/socket/qabstractsocketengine_p.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/network/socket/qabstractsocketengine_p.h b/src/network/socket/qabstractsocketengine_p.h index 01b191971f..3771cdb135 100644 --- a/src/network/socket/qabstractsocketengine_p.h +++ b/src/network/socket/qabstractsocketengine_p.h @@ -125,9 +125,9 @@ public: enum PacketHeaderOption { WantNone = 0, - WantDatagramSender, - WantDatagramDestination, - WantDatagramHopLimit, + WantDatagramSender = 0x01, + WantDatagramDestination = 0x02, + WantDatagramHopLimit = 0x04, WantAll = 0xff }; From 129d268246bf4871cdac84fd4a40d20cece71b3c Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Fri, 23 Oct 2015 16:28:03 +0200 Subject: [PATCH 018/133] Fix alignment in qConvertARGB64PMToA2RGB30PM_sse2 _mm_load_si128 requires 16 byte alignment. This crashes on 32 bit Windows builds. Change-Id: Ib6c30eba726747bbab56467eada820521981a80c Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/gui/painting/qdrawhelper.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 6cfc4b9307..5c1cd8adef 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -1257,9 +1257,8 @@ static inline void qConvertARGB64PMToA2RGB30PM_sse2(uint *dest, const QRgba64 *b const __m128i cmask = _mm_set1_epi32(0x000003ff); int i = 0; __m128i vr, vg, vb, va; - if (i < count && (const uintptr_t)buffer & 0x8) { + for (; i < count && (const uintptr_t)buffer & 0xF; ++i) { *dest++ = qConvertRgb64ToRgb30(*buffer++); - ++i; } for (; i < count-15; i += 16) { From 7df107f0266892276c85d259afba335c2a77ba07 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Thu, 22 Oct 2015 12:54:18 +0200 Subject: [PATCH 019/133] Cocoa: Implement QPlatformInputContext::locale(). Listen to NSTextInputContextKeyboardSelectionDidChangeNotification. Task-number: QTBUG-48772 Change-Id: Icea4ef61fd184edbe65a7f195318832a22c312ab Reviewed-by: Richard Moe Gustavsen --- .../platforms/cocoa/qcocoainputcontext.h | 5 +++++ .../platforms/cocoa/qcocoainputcontext.mm | 19 +++++++++++++++++++ src/plugins/platforms/cocoa/qnsview.h | 1 + src/plugins/platforms/cocoa/qnsview.mm | 15 +++++++++++++++ 4 files changed, 40 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoainputcontext.h b/src/plugins/platforms/cocoa/qcocoainputcontext.h index c7df823dc4..054c4795cb 100644 --- a/src/plugins/platforms/cocoa/qcocoainputcontext.h +++ b/src/plugins/platforms/cocoa/qcocoainputcontext.h @@ -35,6 +35,7 @@ #define QCOCOAINPUTCONTEXT_H #include +#include #include QT_BEGIN_NAMESPACE @@ -50,12 +51,16 @@ public: void reset() Q_DECL_OVERRIDE; + QLocale locale() const Q_DECL_OVERRIDE { return m_locale; } + void updateLocale(); + private Q_SLOTS: void connectSignals(); void focusObjectChanged(QObject *focusObject); private: QPointer mWindow; + QLocale m_locale; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoainputcontext.mm b/src/plugins/platforms/cocoa/qcocoainputcontext.mm index f072991bdd..7d01826ffe 100644 --- a/src/plugins/platforms/cocoa/qcocoainputcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoainputcontext.mm @@ -36,6 +36,8 @@ #include "qcocoanativeinterface.h" #include "qcocoawindow.h" +#include + #include #include #include @@ -76,6 +78,7 @@ QCocoaInputContext::QCocoaInputContext() , mWindow(QGuiApplication::focusWindow()) { QMetaObject::invokeMethod(this, "connectSignals", Qt::QueuedConnection); + updateLocale(); } QCocoaInputContext::~QCocoaInputContext() @@ -116,4 +119,20 @@ void QCocoaInputContext::focusObjectChanged(QObject *focusObject) mWindow = QGuiApplication::focusWindow(); } +void QCocoaInputContext::updateLocale() +{ + TISInputSourceRef source = TISCopyCurrentKeyboardInputSource(); + CFArrayRef languages = (CFArrayRef) TISGetInputSourceProperty(source, kTISPropertyInputSourceLanguages); + if (CFArrayGetCount(languages) > 0) { + CFStringRef langRef = (CFStringRef)CFArrayGetValueAtIndex(languages, 0); + QString name = QCFString::toQString(langRef); + QLocale locale(name); + if (m_locale != locale) { + m_locale = locale; + emitLocaleChanged(); + } + CFRelease(langRef); + } +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index a2890d9b4a..de28b8d74a 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -95,6 +95,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper)); - (void)notifyWindowStateChanged:(Qt::WindowState)newState; - (void)windowNotification : (NSNotification *) windowNotification; - (void)notifyWindowWillZoom:(BOOL)willZoom; +- (void)textInputContextKeyboardSelectionDidChangeNotification : (NSNotification *) textInputContextKeyboardSelectionDidChangeNotification; - (void)viewDidHide; - (void)viewDidUnhide; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 6e6e128aed..faa048874f 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -41,6 +41,7 @@ #include "qcocoahelpers.h" #include "qmultitouch_mac_p.h" #include "qcocoadrag.h" +#include "qcocoainputcontext.h" #include #include @@ -215,6 +216,11 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; name:NSViewFrameDidChangeNotification object:self]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(textInputContextKeyboardSelectionDidChangeNotification:) + name:NSTextInputContextKeyboardSelectionDidChangeNotification + object:nil]; + return self; } @@ -464,6 +470,15 @@ QT_WARNING_POP } } +- (void)textInputContextKeyboardSelectionDidChangeNotification : (NSNotification *) textInputContextKeyboardSelectionDidChangeNotification +{ + Q_UNUSED(textInputContextKeyboardSelectionDidChangeNotification) + if (([NSApp keyWindow] == [self window]) && [[self window] firstResponder] == self) { + QCocoaInputContext *ic = qobject_cast(QCocoaIntegration::instance()->inputContext()); + ic->updateLocale(); + } +} + - (void)notifyWindowWillZoom:(BOOL)willZoom { Qt::WindowState newState = willZoom ? Qt::WindowMaximized : Qt::WindowNoState; From a8455ac5fa250cf651cf9f6c66b82b51a5557f19 Mon Sep 17 00:00:00 2001 From: Samuel Nevala Date: Thu, 22 Oct 2015 14:02:28 +0300 Subject: [PATCH 020/133] ANGLE: Fix winrt backing store to support feature level 9_3 devices. Partially revert c7abf81786f4a0c. Instead of using the ES3 entry point, use ES2 for framebuffer blitting. This means that a small change is required to ANGLE for the blit behave the same as ES3 (applied only for Windows Store apps). Task-Id: QTBUG-48266 Change-Id: Idc51f00a659c91f740876be071eb71bff69e0e38 Reviewed-by: Andrew Knight --- .../libGLESv2/entry_points_gles_2_0_ext.cpp | 4 ++ ...backing-store-to-support-feature-lev.patch | 38 +++++++++++++++++++ .../platforms/winrt/qwinrtbackingstore.cpp | 11 +++--- 3 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 src/angle/patches/0009-ANGLE-Fix-winrt-backing-store-to-support-feature-lev.patch diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_ext.cpp b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_ext.cpp index 8be6ae7d2f..d41c5a4da5 100644 --- a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_ext.cpp +++ b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_ext.cpp @@ -659,7 +659,11 @@ void GL_APIENTRY BlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLi { if (!ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter, +#ifndef ANGLE_ENABLE_WINDOWS_STORE true)) +#else + false)) +#endif { return; } diff --git a/src/angle/patches/0009-ANGLE-Fix-winrt-backing-store-to-support-feature-lev.patch b/src/angle/patches/0009-ANGLE-Fix-winrt-backing-store-to-support-feature-lev.patch new file mode 100644 index 0000000000..8f66b0c1d8 --- /dev/null +++ b/src/angle/patches/0009-ANGLE-Fix-winrt-backing-store-to-support-feature-lev.patch @@ -0,0 +1,38 @@ +From 54461670e035ffcb41268a02e9b0c441cc008ddb Mon Sep 17 00:00:00 2001 +From: Samuel Nevala +Date: Thu, 22 Oct 2015 14:02:28 +0300 +Subject: [PATCH] ANGLE: Fix winrt backing store to support feature level 9_3 + devices. + +Partially revert c7abf81786f4a0c. Instead of using ES3 entry point +use ES2 for blitting. Small change is also required to ANGLE that +makes ES2 entry to behave same as ES3. + +Task-Id: QTBUG-48266 +Change-Id: Idc51f00a659c91f740876be071eb71bff69e0e38 +--- + .../src/libGLESv2/entry_points_gles_2_0_ext.cpp | 4 +++ + ...inrt-backing-store-to-support-feature-lev.patch | 33 ++++++++++++++++++++++ + src/plugins/platforms/winrt/qwinrtbackingstore.cpp | 11 ++++---- + 3 files changed, 42 insertions(+), 6 deletions(-) + create mode 100644 src/angle/patches/0009-ANGLE-Fix-winrt-backing-store-to-support-feature-lev.patch + +diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_ext.cpp b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_ext.cpp +index 8be6ae7..d41c5a4 100644 +--- a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_ext.cpp ++++ b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_ext.cpp +@@ -659,7 +659,11 @@ void GL_APIENTRY BlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLi + { + if (!ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1, mask, filter, ++#ifndef ANGLE_ENABLE_WINDOWS_STORE + true)) ++#else ++ false)) ++#endif + { + return; + } +-- +1.9.5.msysgit.1 + diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp index dcf8239538..ee54bf795c 100644 --- a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp +++ b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp @@ -42,8 +42,8 @@ #include #include -#include -#include +#include +#include QT_BEGIN_NAMESPACE @@ -78,7 +78,6 @@ bool QWinRTBackingStore::initialize() d->context.reset(new QOpenGLContext); QSurfaceFormat format = window()->requestedFormat(); - format.setVersion(3, 0); // Required for ES3 framebuffer blit d->context->setFormat(format); d->context->setScreen(window()->screen()); if (!d->context->create()) @@ -121,13 +120,13 @@ void QWinRTBackingStore::flush(QWindow *window, const QRegion ®ion, const QPo GL_RGBA, GL_UNSIGNED_BYTE, d->paintDevice.constScanLine(bounds.y())); glBindTexture(GL_TEXTURE_2D, 0); - glBindFramebuffer(GL_READ_FRAMEBUFFER, d->fbo->handle()); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, d->fbo->handle()); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, 0); const int y1 = bounds.y(); const int y2 = y1 + bounds.height(); const int x1 = bounds.x(); const int x2 = x1 + bounds.width(); - glBlitFramebuffer(x1, y1, x2, y2, + glBlitFramebufferANGLE(x1, y1, x2, y2, x1, d->size.height() - y1, x2, d->size.height() - y2, GL_COLOR_BUFFER_BIT, GL_NEAREST); From 51dac9890d9df2e2101e3519a8deaa9cbcc42d14 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Wed, 14 Oct 2015 12:25:19 +0200 Subject: [PATCH 021/133] xcb: better error reporting when shmget() fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I160ebc07f25fd08b86ca5494cb149c5fc7c70086 Reviewed-by: Tor Arne Vestbø Reviewed-by: Laszlo Agocs --- src/plugins/platforms/xcb/qxcbbackingstore.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index e62d515b62..25f1ea5236 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -146,8 +146,8 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QI int id = shmget(IPC_PRIVATE, segmentSize, IPC_CREAT | 0600); if (id == -1) - qWarning("QXcbShmImage: shmget() failed (%d) for size %d (%dx%d)", - errno, segmentSize, size.width(), size.height()); + qWarning("QXcbShmImage: shmget() failed (%d: %s) for size %d (%dx%d)", + errno, strerror(errno), segmentSize, size.width(), size.height()); else m_shm_info.shmid = id; m_shm_info.shmaddr = m_xcb_image->data = (quint8 *)shmat (m_shm_info.shmid, 0, 0); From 1721c83c275a0d6aaf01622eb140c02094365142 Mon Sep 17 00:00:00 2001 From: Maks Naumov Date: Sun, 25 Oct 2015 22:01:42 +0200 Subject: [PATCH 022/133] QPathSegments::Intersection: reduce struct size 24 -> 16 bytes Only for systems where qreal is double(8 bytes). Change-Id: I3fd6b5d4279c41102ead24eef287bb37847398c1 Reviewed-by: Gunnar Sletta --- src/gui/painting/qpathclipper.cpp | 4 ++-- src/gui/painting/qpathclipper_p.h | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/gui/painting/qpathclipper.cpp b/src/gui/painting/qpathclipper.cpp index 513fdfa2b6..3a686bd209 100644 --- a/src/gui/painting/qpathclipper.cpp +++ b/src/gui/painting/qpathclipper.cpp @@ -548,11 +548,11 @@ void SegmentTree::produceIntersectionsLeaf(const TreeNode &node, int segment) for (int k = 0; k < m_intersections.size(); ++k) { QPathSegments::Intersection i_isect, j_isect; - i_isect.vertex = j_isect.vertex = m_segments.addPoint(m_intersections.at(k).pos); - i_isect.t = m_intersections.at(k).alphaA; j_isect.t = m_intersections.at(k).alphaB; + i_isect.vertex = j_isect.vertex = m_segments.addPoint(m_intersections.at(k).pos); + i_isect.next = 0; j_isect.next = 0; diff --git a/src/gui/painting/qpathclipper_p.h b/src/gui/painting/qpathclipper_p.h index 36330052dd..d1caea4a1a 100644 --- a/src/gui/painting/qpathclipper_p.h +++ b/src/gui/painting/qpathclipper_p.h @@ -156,9 +156,8 @@ class QPathSegments { public: struct Intersection { - int vertex; qreal t; - + int vertex; int next; bool operator<(const Intersection &o) const { From 4f4da7462bd1ea81c15136d90a0ba71aefbf793e Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 23 Oct 2015 17:17:11 +0200 Subject: [PATCH 023/133] Support overlapping contours in glyph rasterizer fallback Truetype fonts should be rasterized with a winding fill as documented in e.g. Microsoft's specs. Failing to do this caused a bug when doing native rendering in Qt Quick for fonts that were large enough that the fallback path was taken when drawing the glyphs into the cache. If the glyph had overlapping contours, they would be subtracted from the shape. [ChangeLog][Text] Fixed an uncommon rendering error with fonts containing overlapping contours. Task-number: QTBUG-41197 Change-Id: I0e4a4432ba3f902bc3ea59d8f4dbd12a295630b2 Reviewed-by: Konstantin Ritt --- src/gui/text/qfontengine.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index bef4dc5547..6567859a5b 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -960,6 +960,7 @@ QImage QFontEngine::alphaMapForGlyph(glyph_t glyph) pt.x = -glyph_x; pt.y = -glyph_y; // the baseline QPainterPath path; + path.setFillRule(Qt::WindingFill); QImage im(glyph_width + 4, glyph_height, QImage::Format_ARGB32_Premultiplied); im.fill(Qt::transparent); QPainter p(&im); From a681b90418aae8b6ffffc0c6ba79d4e1c257901b Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 23 Oct 2015 16:32:59 +0200 Subject: [PATCH 024/133] QNetworkAccessCache: convert QDateTime::currentDateTime() to currentDateTimeUtc() The latter is much faster as it doesn't have to deal with time zones. This change is safe, because the timestamp member is only ever handled inside, and the calculation of the time difference does not depend on any particular time zone. Credits to Milian Wolff, from whose QtWS15 talk this advice is taken. Change-Id: I6c9190a4253ce5972871ab1f12870f8ae9891966 Reviewed-by: Milian Wolff Reviewed-by: Lars Knoll --- src/network/access/qnetworkaccesscache.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/network/access/qnetworkaccesscache.cpp b/src/network/access/qnetworkaccesscache.cpp index 19316bda75..3d029f118b 100644 --- a/src/network/access/qnetworkaccesscache.cpp +++ b/src/network/access/qnetworkaccesscache.cpp @@ -151,7 +151,7 @@ void QNetworkAccessCache::linkEntry(const QByteArray &key) oldest = node; } - node->timestamp = QDateTime::currentDateTime().addSecs(ExpiryTime); + node->timestamp = QDateTime::currentDateTimeUtc().addSecs(ExpiryTime); newest = node; } @@ -190,7 +190,7 @@ void QNetworkAccessCache::updateTimer() if (!oldest) return; - int interval = QDateTime::currentDateTime().secsTo(oldest->timestamp); + int interval = QDateTime::currentDateTimeUtc().secsTo(oldest->timestamp); if (interval <= 0) { interval = 0; } else { @@ -216,7 +216,7 @@ bool QNetworkAccessCache::emitEntryReady(Node *node, QObject *target, const char void QNetworkAccessCache::timerEvent(QTimerEvent *) { // expire old items - QDateTime now = QDateTime::currentDateTime(); + const QDateTime now = QDateTime::currentDateTimeUtc(); while (oldest && oldest->timestamp < now) { Node *next = oldest->newer; From 45bb9c29e8b70cd15b01d8ab18d1df7f9707c215 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 2 Oct 2015 15:56:04 +0200 Subject: [PATCH 025/133] Fix QHighDPiScaling initialization issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call QHighDpiScaling::updateHighDpiScaling() in init_plaform(), after the platform integration has been created and most platforms have populated the screen list. Keep the existing udpate call for the platforms that don't, but guard against calling it twice. Task-number: QTBUG-47947 Change-Id: Ib73bea7c4ab42e7acf6532f3a3100e1fc29acc2c Reviewed-by: Friedemann Kleint Reviewed-by: Laszlo Agocs Reviewed-by: Morten Johan Sørvig --- src/gui/kernel/qguiapplication.cpp | 16 +++++++++++++--- src/gui/kernel/qguiapplication_p.h | 1 + 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 2e0595152b..216537e51a 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -129,6 +129,8 @@ QWindow *QGuiApplicationPrivate::currentMouseWindow = 0; Qt::ApplicationState QGuiApplicationPrivate::applicationState = Qt::ApplicationInactive; +bool QGuiApplicationPrivate::highDpiScalingUpdated = false; + QPlatformIntegration *QGuiApplicationPrivate::platform_integration = 0; QPlatformTheme *QGuiApplicationPrivate::platform_theme = 0; @@ -1051,6 +1053,13 @@ static void init_platform(const QString &pluginArgument, const QString &platform return; } + // Many platforms have created QScreens at this point. Finish initializing + // QHighDpiScaling to be prepared for early calls to qt_defaultDpi(). + if (QGuiApplication::primaryScreen()) { + QGuiApplicationPrivate::highDpiScalingUpdated = true; + QHighDpiScaling::updateHighDpiScaling(); + } + // Create the platform theme: // 1) Fetch the platform name from the environment if present. @@ -1220,9 +1229,10 @@ void QGuiApplicationPrivate::eventDispatcherReady() platform_integration->initialize(); - // Do this here in order to play nice with platforms that add screens only - // in initialize(). - QHighDpiScaling::updateHighDpiScaling(); + // All platforms should have added screens at this point. Finish + // QHighDpiScaling initialization if it has not been done so already. + if (!QGuiApplicationPrivate::highDpiScalingUpdated) + QHighDpiScaling::updateHighDpiScaling(); } void QGuiApplicationPrivate::init() diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index 0559442049..c3c5acf17c 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -202,6 +202,7 @@ public: static QWindow *currentMouseWindow; static QWindow *currentMousePressWindow; static Qt::ApplicationState applicationState; + static bool highDpiScalingUpdated; #ifndef QT_NO_CLIPBOARD static QClipboard *qt_clipboard; From b2d24dc3475906d4f46c917f129fd98e883569a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 9 Jul 2015 16:32:44 +0200 Subject: [PATCH 026/133] Android: Add opt-in high-dpi support Opt-in by setting android.app.auto_screen_scale_factor to true in AndroidManifest.xml. This will enable devicePixelRatio scaling in QtGui using a scale factor provided by Android DisplayMetrics. Note that the Android style is not currently supported: it already accounts for different display densities which results in incorrect visual sizes when enabling devicePixelRatio scaling. Implementation: Bring DisplayMetrics::density through to setDisplayMetrics in androidjnimain.cpp, similar to what is done for "scaledDensity". Override QPlatformScreen::pixelDensity(), which forwards the scale factor to QtGui. [The difference between "density" and "scaledDensity" is that the former is a physical display density factor which corresponds closely to devicePixelRatio in Qt, while the latter also includes the Android global font scale factor.] Scale the global font pixel size in qandroidplatformtheme.cpp to keep the visual font size constant. Based on an initial patch from Daiwei Li Task-number: QTBUG-46615 Change-Id: Ia51f99bf6dda485a57413949246c7b32cb47e8dd Reviewed-by: BogDan Vatra --- .../src/org/qtproject/qt5/android/QtLayout.java | 4 ++-- .../src/org/qtproject/qt5/android/QtNative.java | 14 ++++++++++---- .../qtproject/qt5/android/bindings/QtActivity.java | 6 ++++++ src/android/templates/AndroidManifest.xml | 4 ++++ src/plugins/platforms/android/androidjnimain.cpp | 13 +++++++++++-- src/plugins/platforms/android/androidjnimain.h | 1 + .../platforms/android/qandroidplatformscreen.cpp | 5 +++++ .../platforms/android/qandroidplatformscreen.h | 1 + .../platforms/android/qandroidplatformtheme.cpp | 4 +++- 9 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtLayout.java b/src/android/jar/src/org/qtproject/qt5/android/QtLayout.java index 4d7ca47dde..b11396aeaf 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtLayout.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtLayout.java @@ -65,8 +65,8 @@ public class QtLayout extends ViewGroup { DisplayMetrics metrics = new DisplayMetrics(); ((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(metrics); - QtNative.setApplicationDisplayMetrics(metrics.widthPixels, - metrics.heightPixels, w, h, metrics.xdpi, metrics.ydpi, metrics.scaledDensity); + QtNative.setApplicationDisplayMetrics(metrics.widthPixels, metrics.heightPixels, w, h, + metrics.xdpi, metrics.ydpi, metrics.scaledDensity, metrics.density); if (m_startApplicationRunnable != null) { m_startApplicationRunnable.run(); m_startApplicationRunnable = null; diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java index 07ef6d657d..371e4e4a61 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java @@ -77,6 +77,7 @@ public class QtNative private static double m_displayMetricsXDpi = .0; private static double m_displayMetricsYDpi = .0; private static double m_displayMetricsScaledDensity = 1.0; + private static double m_displayMetricsDensity = 1.0; private static int m_oldx, m_oldy; private static final int m_moveThreshold = 0; private static ClipboardManager m_clipboardManager = null; @@ -229,7 +230,8 @@ public class QtNative m_displayMetricsDesktopHeightPixels, m_displayMetricsXDpi, m_displayMetricsYDpi, - m_displayMetricsScaledDensity); + m_displayMetricsScaledDensity, + m_displayMetricsDensity); if (params.length() > 0 && !params.startsWith("\t")) params = "\t" + params; startQtApplication(f.getAbsolutePath() + params, environment); @@ -244,7 +246,8 @@ public class QtNative int desktopHeightPixels, double XDpi, double YDpi, - double scaledDensity) + double scaledDensity, + double density) { /* Fix buggy dpi report */ if (XDpi < android.util.DisplayMetrics.DENSITY_LOW) @@ -260,7 +263,8 @@ public class QtNative desktopHeightPixels, XDpi, YDpi, - scaledDensity); + scaledDensity, + density); } else { m_displayMetricsScreenWidthPixels = screenWidthPixels; m_displayMetricsScreenHeightPixels = screenHeightPixels; @@ -269,6 +273,7 @@ public class QtNative m_displayMetricsXDpi = XDpi; m_displayMetricsYDpi = YDpi; m_displayMetricsScaledDensity = scaledDensity; + m_displayMetricsDensity = density; } } } @@ -621,7 +626,8 @@ public class QtNative int desktopHeightPixels, double XDpi, double YDpi, - double scaledDensity); + double scaledDensity, + double density); public static native void handleOrientationChanged(int newRotation, int nativeOrientation); // screen methods diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java index e5ed690f07..146d6b34f2 100644 --- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java +++ b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java @@ -897,6 +897,12 @@ public class QtActivity extends Activity } else { ENVIRONMENT_VARIABLES += "QT_BLOCK_EVENT_LOOPS_WHEN_SUSPENDED=1\t"; } + + if (m_activityInfo.metaData.containsKey("android.app.auto_screen_scale_factor") + && m_activityInfo.metaData.getBoolean("android.app.auto_screen_scale_factor")) { + ENVIRONMENT_VARIABLES += "QT_AUTO_SCREEN_SCALE_FACTOR=1\t"; + } + startApp(true); } } diff --git a/src/android/templates/AndroidManifest.xml b/src/android/templates/AndroidManifest.xml index ad240956ef..262a5f6dba 100644 --- a/src/android/templates/AndroidManifest.xml +++ b/src/android/templates/AndroidManifest.xml @@ -44,6 +44,10 @@ signal is sent! --> + + + + diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index 99cb58830c..d419e42cd5 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -55,6 +55,7 @@ #include #include #include +#include #include @@ -109,6 +110,7 @@ static QAndroidPlatformIntegration *m_androidPlatformIntegration = nullptr; static int m_desktopWidthPixels = 0; static int m_desktopHeightPixels = 0; static double m_scaledDensity = 0; +static double m_density = 1.0; static volatile bool m_pauseApplication; @@ -157,6 +159,11 @@ namespace QtAndroid return m_scaledDensity; } + double pixelDensity() + { + return m_density; + } + JavaVM *javaVM() { return m_javaVM; @@ -547,7 +554,8 @@ static void setSurface(JNIEnv *env, jobject /*thiz*/, jint id, jobject jSurface, static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/, jint widthPixels, jint heightPixels, jint desktopWidthPixels, jint desktopHeightPixels, - jdouble xdpi, jdouble ydpi, jdouble scaledDensity) + jdouble xdpi, jdouble ydpi, + jdouble scaledDensity, jdouble density) { // Android does not give us the correct screen size for immersive mode, but // the surface does have the right size @@ -558,6 +566,7 @@ static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/, m_desktopWidthPixels = desktopWidthPixels; m_desktopHeightPixels = desktopHeightPixels; m_scaledDensity = scaledDensity; + m_density = density; if (!m_androidPlatformIntegration) { QAndroidPlatformIntegration::setDefaultDisplayMetrics(desktopWidthPixels, @@ -683,7 +692,7 @@ static JNINativeMethod methods[] = { {"startQtApplication", "(Ljava/lang/String;Ljava/lang/String;)V", (void *)startQtApplication}, {"quitQtAndroidPlugin", "()V", (void *)quitQtAndroidPlugin}, {"terminateQt", "()V", (void *)terminateQt}, - {"setDisplayMetrics", "(IIIIDDD)V", (void *)setDisplayMetrics}, + {"setDisplayMetrics", "(IIIIDDDD)V", (void *)setDisplayMetrics}, {"setSurface", "(ILjava/lang/Object;II)V", (void *)setSurface}, {"updateWindow", "()V", (void *)updateWindow}, {"updateApplicationState", "(I)V", (void *)updateApplicationState}, diff --git a/src/plugins/platforms/android/androidjnimain.h b/src/plugins/platforms/android/androidjnimain.h index 4d037f4b74..cdedeb38f8 100644 --- a/src/plugins/platforms/android/androidjnimain.h +++ b/src/plugins/platforms/android/androidjnimain.h @@ -71,6 +71,7 @@ namespace QtAndroid int desktopWidthPixels(); int desktopHeightPixels(); double scaledDensity(); + double pixelDensity(); JavaVM *javaVM(); AAssetManager *assetManager(); jclass applicationClass(); diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp index 7a509e4d61..209ce2f7db 100644 --- a/src/plugins/platforms/android/qandroidplatformscreen.cpp +++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp @@ -382,6 +382,11 @@ QDpi QAndroidPlatformScreen::logicalDpi() const return QDpi(lDpi, lDpi); } +qreal QAndroidPlatformScreen::pixelDensity() const +{ + return QtAndroid::pixelDensity(); +} + Qt::ScreenOrientation QAndroidPlatformScreen::orientation() const { return QAndroidPlatformIntegration::m_orientation; diff --git a/src/plugins/platforms/android/qandroidplatformscreen.h b/src/plugins/platforms/android/qandroidplatformscreen.h index 403d6036f0..c01dbbc712 100644 --- a/src/plugins/platforms/android/qandroidplatformscreen.h +++ b/src/plugins/platforms/android/qandroidplatformscreen.h @@ -96,6 +96,7 @@ protected: private: QDpi logicalDpi() const; + qreal pixelDensity() const; Qt::ScreenOrientation orientation() const; Qt::ScreenOrientation nativeOrientation() const; void surfaceChanged(JNIEnv *env, jobject surface, int w, int h); diff --git a/src/plugins/platforms/android/qandroidplatformtheme.cpp b/src/plugins/platforms/android/qandroidplatformtheme.cpp index 3e2ae7c939..71a3f910d2 100644 --- a/src/plugins/platforms/android/qandroidplatformtheme.cpp +++ b/src/plugins/platforms/android/qandroidplatformtheme.cpp @@ -31,6 +31,7 @@ ** ****************************************************************************/ +#include "androidjnimain.h" #include "androidjnimenu.h" #include "qandroidplatformtheme.h" #include "qandroidplatformmenubar.h" @@ -216,6 +217,7 @@ QJsonObject AndroidStyle::loadStyleData() static std::shared_ptr loadAndroidStyle(QPalette *defaultPalette) { + double pixelDensity = qEnvironmentVariableIsSet("QT_AUTO_SCREEN_SCALE_FACTOR") ? QtAndroid::pixelDensity() : 1.0; std::shared_ptr style(new AndroidStyle); style->m_styleData = AndroidStyle::loadStyleData(); if (style->m_styleData.isEmpty()) @@ -245,7 +247,7 @@ static std::shared_ptr loadAndroidStyle(QPalette *defaultPalette) // Font size (in pixels) attributeIterator = item.find(QLatin1String("TextAppearance_textSize")); if (attributeIterator != item.constEnd()) - font.setPixelSize(int(attributeIterator.value().toDouble())); + font.setPixelSize(int(attributeIterator.value().toDouble() / pixelDensity)); // Font style attributeIterator = item.find(QLatin1String("TextAppearance_textStyle")); From a38df3f3bade12007b546f6c4d3bede7922743f0 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 24 Oct 2015 12:47:53 +0200 Subject: [PATCH 027/133] Android: use Q_UNIMPLEMENTED() ... instead of explicit qWarnings() Change-Id: I986a11bf519eaefd400813776d173b0ab2c2bc62 Reviewed-by: BogDan Vatra --- src/corelib/kernel/qsharedmemory_android.cpp | 14 +++++++------- src/corelib/kernel/qsystemsemaphore_android.cpp | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/corelib/kernel/qsharedmemory_android.cpp b/src/corelib/kernel/qsharedmemory_android.cpp index cdcd5685e0..12afff5dce 100644 --- a/src/corelib/kernel/qsharedmemory_android.cpp +++ b/src/corelib/kernel/qsharedmemory_android.cpp @@ -50,12 +50,12 @@ QSharedMemoryPrivate::QSharedMemoryPrivate() void QSharedMemoryPrivate::setErrorString(QLatin1String function) { Q_UNUSED(function); - qWarning() << Q_FUNC_INFO << "Not yet implemented on Android"; + Q_UNIMPLEMENTED(); } key_t QSharedMemoryPrivate::handle() { - qWarning() << Q_FUNC_INFO << "Not yet implemented on Android"; + Q_UNIMPLEMENTED(); return 0; } @@ -65,7 +65,7 @@ key_t QSharedMemoryPrivate::handle() int QSharedMemoryPrivate::createUnixKeyFile(const QString &fileName) { Q_UNUSED(fileName); - qWarning() << Q_FUNC_INFO << "Not yet implemented on Android"; + Q_UNIMPLEMENTED(); return 0; } #endif // QT_NO_SHAREDMEMORY && QT_NO_SYSTEMSEMAPHORE @@ -74,27 +74,27 @@ int QSharedMemoryPrivate::createUnixKeyFile(const QString &fileName) bool QSharedMemoryPrivate::cleanHandle() { - qWarning() << Q_FUNC_INFO << "Not yet implemented on Android"; + Q_UNIMPLEMENTED(); return true; } bool QSharedMemoryPrivate::create(int size) { Q_UNUSED(size); - qWarning() << Q_FUNC_INFO << "Not yet implemented on Android"; + Q_UNIMPLEMENTED(); return false; } bool QSharedMemoryPrivate::attach(QSharedMemory::AccessMode mode) { Q_UNUSED(mode); - qWarning() << Q_FUNC_INFO << "Not yet implemented on Android"; + Q_UNIMPLEMENTED(); return false; } bool QSharedMemoryPrivate::detach() { - qWarning() << Q_FUNC_INFO << "Not yet implemented on Android"; + Q_UNIMPLEMENTED(); return false; } diff --git a/src/corelib/kernel/qsystemsemaphore_android.cpp b/src/corelib/kernel/qsystemsemaphore_android.cpp index f501779db9..536b09bb41 100644 --- a/src/corelib/kernel/qsystemsemaphore_android.cpp +++ b/src/corelib/kernel/qsystemsemaphore_android.cpp @@ -49,25 +49,25 @@ QSystemSemaphorePrivate::QSystemSemaphorePrivate() : void QSystemSemaphorePrivate::setErrorString(const QString &function) { Q_UNUSED(function); - qWarning() << Q_FUNC_INFO << "Not yet implemented on Android"; + Q_UNIMPLEMENTED(); } key_t QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode) { Q_UNUSED(mode); - qWarning() << Q_FUNC_INFO << "Not yet implemented on Android"; + Q_UNIMPLEMENTED(); return -1; } void QSystemSemaphorePrivate::cleanHandle() { - qWarning() << Q_FUNC_INFO << "Not yet implemented on Android"; + Q_UNIMPLEMENTED(); } bool QSystemSemaphorePrivate::modifySemaphore(int count) { Q_UNUSED(count); - qWarning() << Q_FUNC_INFO << "Not yet implemented on Android"; + Q_UNIMPLEMENTED(); return false; } From 7532fb4e61fc4102fd11022f57f7d8195414167b Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Fri, 23 Oct 2015 10:37:49 +0200 Subject: [PATCH 028/133] Xcb: fix crash on screen power save Handle various cases where we have null QScreen or QPlatformScreen pointers. With this change, I can run Qt Creator for several days. Before, it would crash multiple times per day with a two-monitor setup. Change-Id: I0923d886ae2a4199ac37edd711ddd4f6f99df93d Reviewed-by: Friedemann Kleint Reviewed-by: Lars Knoll Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbbackingstore.cpp | 13 +++++++++++-- src/plugins/platforms/xcb/qxcbbackingstore.h | 1 + src/plugins/platforms/xcb/qxcbwindow.cpp | 4 ++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index 25f1ea5236..1825a463d0 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -311,9 +311,12 @@ QPaintDevice *QXcbBackingStore::paintDevice() void QXcbBackingStore::beginPaint(const QRegion ®ion) { + if (!m_image && !m_size.isEmpty()) + resize(m_size, QRegion()); + if (!m_image) return; - + m_size = QSize(); m_paintRegion = region; m_image->preparePaint(m_paintRegion); @@ -420,7 +423,8 @@ void QXcbBackingStore::resize(const QSize &size, const QRegion &) return; Q_XCB_NOOP(connection()); - QXcbScreen *screen = static_cast(window()->screen()->handle()); + + QXcbScreen *screen = window()->screen() ? static_cast(window()->screen()->handle()) : 0; QPlatformWindow *pw = window()->handle(); if (!pw) { window()->create(); @@ -429,6 +433,11 @@ void QXcbBackingStore::resize(const QSize &size, const QRegion &) QXcbWindow* win = static_cast(pw); delete m_image; + if (!screen) { + m_image = 0; + m_size = size; + return; + } m_image = new QXcbShmImage(screen, size, win->depth(), win->imageFormat()); // Slow path for bgr888 VNC: Create an additional image, paint into that and // swap R and B while copying to m_image after each paint. diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.h b/src/plugins/platforms/xcb/qxcbbackingstore.h index b58a32d313..1bea36d423 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.h +++ b/src/plugins/platforms/xcb/qxcbbackingstore.h @@ -71,6 +71,7 @@ private: QXcbShmImage *m_image; QRegion m_paintRegion; QImage m_rgbImage; + QSize m_size; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index bde8826792..b691c7550f 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -652,7 +652,7 @@ void QXcbWindow::setGeometry(const QRect &rect) m_xcbScreen = newScreen; const QRect wmGeometry = windowToWmGeometry(rect); - if (newScreen != currentScreen) + if (newScreen && newScreen != currentScreen) QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen()); if (qt_window_private(window())->positionAutomatic) { @@ -1606,7 +1606,7 @@ void QXcbWindow::requestActivateWindow() return; } - if (!m_mapped) { + if (!m_mapped || !xcbScreen()) { m_deferredActivation = true; return; } From b7c4f15d6702941b110f7c2ffea490cf1b68c953 Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Fri, 23 Oct 2015 21:13:18 +0300 Subject: [PATCH 029/133] Undef HAVE_WAITID if needed constants are not defined MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit That is the case on Hurd, where the code currently breaks because Hurd does not have WEXITED or WNOWAIT defined. Change-Id: I4b13633612b1168d36c949d9e8b35bc05bca7d5c Reviewed-by: Lisandro Damián Nicanor Pérez Meyer Reviewed-by: Thiago Macieira --- src/3rdparty/forkfd/forkfd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/3rdparty/forkfd/forkfd.c b/src/3rdparty/forkfd/forkfd.c index ec24ba7b16..e35b66ae2c 100644 --- a/src/3rdparty/forkfd/forkfd.c +++ b/src/3rdparty/forkfd/forkfd.c @@ -58,6 +58,9 @@ #if _POSIX_VERSION-0 >= 200809L || _XOPEN_VERSION-0 >= 500 # define HAVE_WAITID 1 #endif +#if !defined(WEXITED) || !defined(WNOWAIT) +# undef HAVE_WAITID +#endif #if defined(__FreeBSD__) # define HAVE_PIPE2 1 From c20f92a0fa11c2cc7bad8f69a1e0a8f8b5893df3 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 8 Oct 2015 18:07:00 +0200 Subject: [PATCH 030/133] fix growth of event queue in QWinOverlappedIoNotifier::waitFor* Do not emit _q_notified when we're in a wait function. Otherwise, the queued signals could pile up in the event queue. Task-number: QTBUG-48653 Change-Id: I071863e2356e17c7004e3b7ca359967cb115e343 Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qwinoverlappedionotifier.cpp | 70 +++++++++++++++------ 1 file changed, 51 insertions(+), 19 deletions(-) diff --git a/src/corelib/io/qwinoverlappedionotifier.cpp b/src/corelib/io/qwinoverlappedionotifier.cpp index 083feb4a20..c6ce15c2c9 100644 --- a/src/corelib/io/qwinoverlappedionotifier.cpp +++ b/src/corelib/io/qwinoverlappedionotifier.cpp @@ -33,6 +33,7 @@ #include "qwinoverlappedionotifier_p.h" #include +#include #include #include #include @@ -99,6 +100,7 @@ public: { } + OVERLAPPED *waitForAnyNotified(int msecs); void notify(DWORD numberOfBytes, DWORD errorCode, OVERLAPPED *overlapped); OVERLAPPED *_q_notified(); @@ -108,6 +110,7 @@ public: HANDLE hHandle; HANDLE hSemaphore; HANDLE hResultsMutex; + QAtomicInt waiting; QQueue results; }; @@ -286,6 +289,47 @@ void QWinOverlappedIoNotifier::setEnabled(bool enabled) d->iocp->unregisterNotifier(d); } +OVERLAPPED *QWinOverlappedIoNotifierPrivate::waitForAnyNotified(int msecs) +{ + if (!iocp->isRunning()) { + qWarning("Called QWinOverlappedIoNotifier::waitForAnyNotified on inactive notifier."); + return 0; + } + + if (msecs == 0) + iocp->drainQueue(); + + const DWORD wfso = WaitForSingleObject(hSemaphore, msecs == -1 ? INFINITE : DWORD(msecs)); + switch (wfso) { + case WAIT_OBJECT_0: + ReleaseSemaphore(hSemaphore, 1, NULL); + return _q_notified(); + case WAIT_TIMEOUT: + return 0; + default: + qErrnoWarning("QWinOverlappedIoNotifier::waitForAnyNotified: WaitForSingleObject failed."); + return 0; + } +} + +class QScopedAtomicIntIncrementor +{ +public: + QScopedAtomicIntIncrementor(QAtomicInt &i) + : m_int(i) + { + ++m_int; + } + + ~QScopedAtomicIntIncrementor() + { + --m_int; + } + +private: + QAtomicInt &m_int; +}; + /*! * Wait synchronously for any notified signal. * @@ -296,24 +340,9 @@ void QWinOverlappedIoNotifier::setEnabled(bool enabled) OVERLAPPED *QWinOverlappedIoNotifier::waitForAnyNotified(int msecs) { Q_D(QWinOverlappedIoNotifier); - if (!d->iocp->isRunning()) { - qWarning("Called QWinOverlappedIoNotifier::waitForAnyNotified on inactive notifier."); - return 0; - } - - if (msecs == 0) - d->iocp->drainQueue(); - - switch (WaitForSingleObject(d->hSemaphore, msecs == -1 ? INFINITE : DWORD(msecs))) { - case WAIT_OBJECT_0: - ReleaseSemaphore(d->hSemaphore, 1, NULL); - return d->_q_notified(); - case WAIT_TIMEOUT: - return 0; - default: - qErrnoWarning("QWinOverlappedIoNotifier::waitForAnyNotified: WaitForSingleObject failed."); - return 0; - } + QScopedAtomicIntIncrementor saii(d->waiting); + OVERLAPPED *result = d->waitForAnyNotified(msecs); + return result; } /*! @@ -324,6 +353,8 @@ OVERLAPPED *QWinOverlappedIoNotifier::waitForAnyNotified(int msecs) */ bool QWinOverlappedIoNotifier::waitForNotified(int msecs, OVERLAPPED *overlapped) { + Q_D(QWinOverlappedIoNotifier); + QScopedAtomicIntIncrementor saii(d->waiting); int t = msecs; QElapsedTimer stopWatch; stopWatch.start(); @@ -350,7 +381,8 @@ void QWinOverlappedIoNotifierPrivate::notify(DWORD numberOfBytes, DWORD errorCod results.enqueue(IOResult(numberOfBytes, errorCode, overlapped)); ReleaseMutex(hResultsMutex); ReleaseSemaphore(hSemaphore, 1, NULL); - emit q->_q_notify(); + if (!waiting) + emit q->_q_notify(); } OVERLAPPED *QWinOverlappedIoNotifierPrivate::_q_notified() From 2f7d3cf559e0bdf8643e213de3a36796f6a88bd3 Mon Sep 17 00:00:00 2001 From: Martin Koller Date: Tue, 4 Aug 2015 21:29:18 +0200 Subject: [PATCH 031/133] Android: auto-detect MIME type for local files to make openUrl work [ChangeLog][QtCore][Android] Fixed the opening of a local file using QDesktopServices::openUrl(). For a local file to be viewed with QDesktopServices::openUrl(), Android needs to be given the MIME type otherwise it does not start an Intent to view the file. Task-number: QTBUG-45585 Change-Id: Ifcfce4bff35011f205cfadbdb2b37a1780dac87d Reviewed-by: BogDan Vatra --- .../org/qtproject/qt5/android/QtNative.java | 4 +++- .../android/qandroidplatformservices.cpp | 23 +++++++++++++++---- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java index 040eba5e42..11b6ad8cdc 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java @@ -100,13 +100,15 @@ public class QtNative } } - public static boolean openURL(String url) + public static boolean openURL(String url, String mime) { boolean ok = true; try { Uri uri = Uri.parse(url); Intent intent = new Intent(Intent.ACTION_VIEW, uri); + if (!mime.isEmpty()) + intent.setDataAndType(uri, mime); activity().startActivity(intent); } catch (Exception e) { e.printStackTrace(); diff --git a/src/plugins/platforms/android/qandroidplatformservices.cpp b/src/plugins/platforms/android/qandroidplatformservices.cpp index 2dba6c78e1..412e3e0466 100644 --- a/src/plugins/platforms/android/qandroidplatformservices.cpp +++ b/src/plugins/platforms/android/qandroidplatformservices.cpp @@ -33,8 +33,9 @@ #include "qandroidplatformservices.h" #include -#include +#include #include +#include #include QT_BEGIN_NAMESPACE @@ -43,13 +44,27 @@ QAndroidPlatformServices::QAndroidPlatformServices() { } -bool QAndroidPlatformServices::openUrl(const QUrl &url) +bool QAndroidPlatformServices::openUrl(const QUrl &theUrl) { + QString mime; + QUrl url(theUrl); + + // if the file is local, we need to pass the MIME type, otherwise Android + // does not start an Intent to view this file + if ((url.scheme().isEmpty() && QFile::exists(url.path())) || url.isLocalFile()) { + // a real URL including the scheme is needed, else the Intent can not be started + url.setScheme(QLatin1String("file")); + + QMimeDatabase mimeDb; + mime = mimeDb.mimeTypeForUrl(url).name(); + } + QJNIObjectPrivate urlString = QJNIObjectPrivate::fromString(url.toString()); + QJNIObjectPrivate mimeString = QJNIObjectPrivate::fromString(mime); return QJNIObjectPrivate::callStaticMethod(QtAndroid::applicationClass(), "openURL", - "(Ljava/lang/String;)Z", - urlString.object()); + "(Ljava/lang/String;Ljava/lang/String;)Z", + urlString.object(), mimeString.object()); } bool QAndroidPlatformServices::openDocument(const QUrl &url) From 30d02f468fd3d85189c4afc6f84c1015927f43de Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Thu, 24 Sep 2015 21:35:18 +0200 Subject: [PATCH 032/133] WinRT: Retrieve color settings on Windows 10 Windows 10 uses one enum for all target platforms. Use ApiInformationStatics to identify whether enum values are accessible at runtime. Change-Id: Ib77c9d2a2b5cf1655fbe7d937d0c83cc4cdd9ee9 Reviewed-by: Andrew Knight Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrttheme.cpp | 185 ++++++++++++++++---- 1 file changed, 152 insertions(+), 33 deletions(-) diff --git a/src/plugins/platforms/winrt/qwinrttheme.cpp b/src/plugins/platforms/winrt/qwinrttheme.cpp index c32ec8a151..7d09551f5b 100644 --- a/src/plugins/platforms/winrt/qwinrttheme.cpp +++ b/src/plugins/platforms/winrt/qwinrttheme.cpp @@ -44,7 +44,13 @@ #include #include #include +#if _MSC_VER >= 1900 +#include +using namespace ABI::Windows::Foundation::Metadata; +#endif + using namespace Microsoft::WRL; +using namespace Microsoft::WRL::Wrappers; using namespace ABI::Windows::UI; using namespace ABI::Windows::UI::ViewManagement; @@ -73,102 +79,215 @@ static inline QColor fromColor(const Color &color) return QColor(color.R, color.G, color.B, color.A); } -QWinRTTheme::QWinRTTheme() - : d_ptr(new QWinRTThemePrivate) +#if _MSC_VER >= 1900 +static bool uiColorSettings(const wchar_t *value, UIElementType type, Color *color) { - Q_D(QWinRTTheme); + static ComPtr apiInformationStatics; + HRESULT hr; + if (!apiInformationStatics) { + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Foundation_Metadata_ApiInformation).Get(), + IID_PPV_ARGS(&apiInformationStatics)); + RETURN_FALSE_IF_FAILED("Could not get ApiInformationStatics"); + } + static const HStringReference enumRef(L"Windows.UI.ViewManagement.UIElementType"); + HStringReference valueRef(value); + + boolean exists; + hr = apiInformationStatics->IsEnumNamedValuePresent(enumRef.Get(), valueRef.Get(), &exists); + + if (hr != S_OK || !exists) + return false; + + return SUCCEEDED(uiSettings()->UIElementColor(type, color)); +} + +static void nativeColorSettings(QPalette &p) +{ + Color color; + + if (uiColorSettings(L"ActiveCaption", UIElementType_ActiveCaption, &color)) + p.setColor(QPalette::ToolTipBase, fromColor(color)); + + if (uiColorSettings(L"Background", UIElementType_Background, &color)) + p.setColor(QPalette::AlternateBase, fromColor(color)); + + if (uiColorSettings(L"ButtonFace", UIElementType_ButtonFace, &color)) { + p.setColor(QPalette::Button, fromColor(color)); + p.setColor(QPalette::Midlight, fromColor(color).lighter(110)); + p.setColor(QPalette::Light, fromColor(color).lighter(150)); + p.setColor(QPalette::Mid, fromColor(color).dark(130)); + p.setColor(QPalette::Dark, fromColor(color).dark(150)); + } + + if (uiColorSettings(L"ButtonText", UIElementType_ButtonText, &color)) { + p.setColor(QPalette::ButtonText, fromColor(color)); + p.setColor(QPalette::Text, fromColor(color)); + } + + if (uiColorSettings(L"CaptionText", UIElementType_CaptionText, &color)) + p.setColor(QPalette::ToolTipText, fromColor(color)); + + if (uiColorSettings(L"Highlight", UIElementType_Highlight, &color)) + p.setColor(QPalette::Highlight, fromColor(color)); + + if (uiColorSettings(L"HighlightText", UIElementType_HighlightText, &color)) + p.setColor(QPalette::HighlightedText, fromColor(color)); + + if (uiColorSettings(L"Window", UIElementType_Window, &color)) { + p.setColor(QPalette::Window, fromColor(color)); + p.setColor(QPalette::Base, fromColor(color)); + } + + if (uiColorSettings(L"Hotlight", UIElementType_Hotlight, &color)) + p.setColor(QPalette::BrightText, fromColor(color)); + + //Phone related + if (uiColorSettings(L"PopupBackground", UIElementType_PopupBackground, &color)) { + p.setColor(QPalette::ToolTipBase, fromColor(color)); + p.setColor(QPalette::AlternateBase, fromColor(color)); + } + + if (uiColorSettings(L"NonTextMedium", UIElementType_NonTextMedium, &color)) + p.setColor(QPalette::Button, fromColor(color)); + + if (uiColorSettings(L"NonTextMediumHigh", UIElementType_NonTextMediumHigh, &color)) + p.setColor(QPalette::Midlight, fromColor(color)); + + if (uiColorSettings(L"NonTextHigh", UIElementType_NonTextHigh, &color)) + p.setColor(QPalette::Light, fromColor(color)); + + if (uiColorSettings(L"NonTextMediumLow", UIElementType_NonTextMediumLow, &color)) + p.setColor(QPalette::Mid, fromColor(color)); + + if (uiColorSettings(L"NonTextLow", UIElementType_NonTextLow, &color)) + p.setColor(QPalette::Dark, fromColor(color)); + + if (uiColorSettings(L"TextHigh", UIElementType_TextHigh, &color)) { + p.setColor(QPalette::ButtonText, fromColor(color)); + p.setColor(QPalette::Text, fromColor(color)); + p.setColor(QPalette::WindowText, fromColor(color)); + } + + if (uiColorSettings(L"TextMedium", UIElementType_TextMedium, &color)) + p.setColor(QPalette::ToolTipText, fromColor(color)); + + if (uiColorSettings(L"AccentColor", UIElementType_AccentColor, &color)) + p.setColor(QPalette::Highlight, fromColor(color)); + + if (uiColorSettings(L"PageBackground", UIElementType_PageBackground, &color)) { + p.setColor(QPalette::Window, fromColor(color)); + p.setColor(QPalette::Base, fromColor(color)); + } + + if (uiColorSettings(L"TextContrastWithHigh", UIElementType_TextContrastWithHigh, &color)) + p.setColor(QPalette::BrightText, fromColor(color)); +} + +#else // _MSC_VER >= 1900 + +static void nativeColorSettings(QPalette &p) +{ HRESULT hr; Color color; #ifdef Q_OS_WINPHONE hr = uiSettings()->UIElementColor(UIElementType_PopupBackground, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::ToolTipBase, fromColor(color)); - d->palette.setColor(QPalette::AlternateBase, fromColor(color)); + p.setColor(QPalette::ToolTipBase, fromColor(color)); + p.setColor(QPalette::AlternateBase, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_NonTextMedium, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::Button, fromColor(color)); + p.setColor(QPalette::Button, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_NonTextMediumHigh, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::Midlight, fromColor(color)); + p.setColor(QPalette::Midlight, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_NonTextHigh, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::Light, fromColor(color)); + p.setColor(QPalette::Light, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_NonTextMediumLow, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::Mid, fromColor(color)); + p.setColor(QPalette::Mid, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_NonTextLow, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::Dark, fromColor(color)); + p.setColor(QPalette::Dark, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_TextHigh, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::ButtonText, fromColor(color)); - d->palette.setColor(QPalette::Text, fromColor(color)); - d->palette.setColor(QPalette::WindowText, fromColor(color)); + p.setColor(QPalette::ButtonText, fromColor(color)); + p.setColor(QPalette::Text, fromColor(color)); + p.setColor(QPalette::WindowText, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_TextMedium, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::ToolTipText, fromColor(color)); + p.setColor(QPalette::ToolTipText, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_AccentColor, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::Highlight, fromColor(color)); + p.setColor(QPalette::Highlight, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_PageBackground, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::Window, fromColor(color)); - d->palette.setColor(QPalette::Base, fromColor(color)); + p.setColor(QPalette::Window, fromColor(color)); + p.setColor(QPalette::Base, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_TextContrastWithHigh, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::BrightText, fromColor(color)); + p.setColor(QPalette::BrightText, fromColor(color)); #else hr = uiSettings()->UIElementColor(UIElementType_ActiveCaption, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::ToolTipBase, fromColor(color)); + p.setColor(QPalette::ToolTipBase, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_Background, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::AlternateBase, fromColor(color)); + p.setColor(QPalette::AlternateBase, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_ButtonFace, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::Button, fromColor(color)); - d->palette.setColor(QPalette::Midlight, fromColor(color).lighter(110)); - d->palette.setColor(QPalette::Light, fromColor(color).lighter(150)); - d->palette.setColor(QPalette::Mid, fromColor(color).dark(130)); - d->palette.setColor(QPalette::Dark, fromColor(color).dark(150)); + p.setColor(QPalette::Button, fromColor(color)); + p.setColor(QPalette::Midlight, fromColor(color).lighter(110)); + p.setColor(QPalette::Light, fromColor(color).lighter(150)); + p.setColor(QPalette::Mid, fromColor(color).dark(130)); + p.setColor(QPalette::Dark, fromColor(color).dark(150)); hr = uiSettings()->UIElementColor(UIElementType_ButtonText, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::ButtonText, fromColor(color)); - d->palette.setColor(QPalette::Text, fromColor(color)); + p.setColor(QPalette::ButtonText, fromColor(color)); + p.setColor(QPalette::Text, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_CaptionText, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::ToolTipText, fromColor(color)); + p.setColor(QPalette::ToolTipText, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_Highlight, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::Highlight, fromColor(color)); + p.setColor(QPalette::Highlight, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_HighlightText, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::HighlightedText, fromColor(color)); + p.setColor(QPalette::HighlightedText, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_Window, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::Window, fromColor(color)); - d->palette.setColor(QPalette::Base, fromColor(color)); + p.setColor(QPalette::Window, fromColor(color)); + p.setColor(QPalette::Base, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_Hotlight, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::BrightText, fromColor(color)); + p.setColor(QPalette::BrightText, fromColor(color)); #endif } +#endif // _MSC_VER < 1900 + +QWinRTTheme::QWinRTTheme() + : d_ptr(new QWinRTThemePrivate) +{ + Q_D(QWinRTTheme); + + nativeColorSettings(d->palette); +} bool QWinRTTheme::usePlatformNativeDialog(DialogType type) const { From 3b447ae1f3b60794bdceaa4c590751a97b43bd1b Mon Sep 17 00:00:00 2001 From: Andy Nichols Date: Wed, 14 Oct 2015 17:03:33 +0200 Subject: [PATCH 033/133] Add qgltf support to qmake qgltf is a tool provided by the Qt3D module that enables 3D assets to be defined in qmake project files, and have them converted to an efficient binary format at build time. The qmake feature will convert all 3D assets specified by the QT3D_MODELS variable to the qgltf format and add the new model asset to the project as a Qt resource file. Change-Id: If7250d6f23a06254b1ed0e408057723763aad8c8 Reviewed-by: Oswald Buddenhagen --- mkspecs/features/exclusive_builds.prf | 3 ++- mkspecs/features/qgltf.prf | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 mkspecs/features/qgltf.prf diff --git a/mkspecs/features/exclusive_builds.prf b/mkspecs/features/exclusive_builds.prf index 4d88dcd15e..5d06198ae4 100644 --- a/mkspecs/features/exclusive_builds.prf +++ b/mkspecs/features/exclusive_builds.prf @@ -34,4 +34,5 @@ defineTest(addExclusiveBuilds) { } # Default directories to process -QMAKE_DIR_REPLACE = OBJECTS_DIR MOC_DIR RCC_DIR PRECOMPILED_DIR DESTDIR +QMAKE_DIR_REPLACE = OBJECTS_DIR MOC_DIR RCC_DIR PRECOMPILED_DIR QGLTF_DIR DESTDIR +QMAKE_DIR_REPLACE_SANE += QGLTF_DIR diff --git a/mkspecs/features/qgltf.prf b/mkspecs/features/qgltf.prf new file mode 100644 index 0000000000..c62e8c2ee8 --- /dev/null +++ b/mkspecs/features/qgltf.prf @@ -0,0 +1,11 @@ +qtPrepareTool(QMAKE_QGLTF, qgltf) + +isEmpty(QGLTF_DIR): QGLTF_DIR = . + +qgltf.input = QT3D_MODELS +qgltf.output = $$QGLTF_DIR/${QMAKE_FILE_BASE}.qrc +qgltf.variable_out += RESOURCES +qgltf.commands = $$QMAKE_QGLTF -d $$QGLTF_DIR $$QGLTF_PARAMS ${QMAKE_FILE_NAME} +silent: qgltf.commands = @echo qgltf ${QMAKE_FILE_IN} && $$qgltf.commands -s +qgltf.CONFIG += no_link +QMAKE_EXTRA_COMPILERS += qgltf From 00f35b4ae7f94e0fe1c8c77efec401ab5f3c4855 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 22 Oct 2015 12:54:45 -0700 Subject: [PATCH 034/133] Move pointer size detection entirely to qprocessordetection.h This commit removes the legacy ptrsize check, which was deficient because it did not work for multiarch systems (when we supported fat OS X binaries) and did not work for bootstrap builds because the size might be different when cross-compiling. Instead, let's rely on the predefined preprocessor macros to detect correctly. As a nice side-effect, this fixes 64-bit Android builds cross-compiled from Windows. Task-number: QTBUG-48932 Change-Id: I1d0f78915b5942aab07cffff140f9a52b9342f23 Reviewed-by: Oswald Buddenhagen Reviewed-by: Erik Verbruggen --- config.tests/unix/ptrsize.test | 35 --------------- config.tests/unix/ptrsize/ptrsizetest.cpp | 53 ----------------------- config.tests/unix/ptrsize/ptrsizetest.pro | 3 -- configure | 13 ------ src/corelib/global/qglobal.cpp | 4 +- src/corelib/global/qglobal.h | 12 ----- src/corelib/global/qprocessordetection.h | 35 +++++++++++---- tools/configure/configureapp.cpp | 7 --- 8 files changed, 28 insertions(+), 134 deletions(-) delete mode 100755 config.tests/unix/ptrsize.test delete mode 100644 config.tests/unix/ptrsize/ptrsizetest.cpp delete mode 100644 config.tests/unix/ptrsize/ptrsizetest.pro diff --git a/config.tests/unix/ptrsize.test b/config.tests/unix/ptrsize.test deleted file mode 100755 index 7d7bde57e5..0000000000 --- a/config.tests/unix/ptrsize.test +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/sh - -QMKSPEC=$1 -VERBOSE=$2 -SRCDIR=$3 -OUTDIR=$4 - -LFLAGS=$SYSROOT_FLAG -CXXFLAGS=$SYSROOT_FLAG - -# debuggery -[ "$VERBOSE" = "yes" ] && echo "Testing size of pointers ... ($*)" - -# build and run a test program -test -d "$OUTDIR/config.tests/unix/ptrsize" || mkdir -p "$OUTDIR/config.tests/unix/ptrsize" -"$OUTDIR/bin/qmake" -nocache -spec "$QMKSPEC" "CONFIG-=app_bundle" "QMAKE_LFLAGS*=$LFLAGS" "QMAKE_CXXFLAGS*=$CXXFLAGS" "$SRCDIR/config.tests/unix/ptrsize/ptrsizetest.pro" -o "$OUTDIR/config.tests/unix/ptrsize/Makefile" >/dev/null 2>&1 -cd "$OUTDIR/config.tests/unix/ptrsize" - -if [ "$VERBOSE" = "yes" ]; then - ($MAKE clean && $MAKE) -else - ($MAKE clean && $MAKE) >/dev/null 2>&1 -fi -RETVAL=$? - -if [ "$RETVAL" -ne 0 ]; then - PTRSIZE=4 -else - PTRSIZE=8 -fi - - -# done -[ "$VERBOSE" = "yes" ] && echo "Pointer size: $PTRSIZE" -exit $PTRSIZE diff --git a/config.tests/unix/ptrsize/ptrsizetest.cpp b/config.tests/unix/ptrsize/ptrsizetest.cpp deleted file mode 100644 index 826095d0e9..0000000000 --- a/config.tests/unix/ptrsize/ptrsizetest.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the config.tests of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/* Sample program for configure to test pointer size on target -platforms. -*/ - -template -struct QPointerSizeTest -{ -}; - -template<> -struct QPointerSizeTest<8> -{ - enum { PointerSize = 8 }; -}; - -int main( int, char ** ) -{ - return QPointerSizeTest::PointerSize; -} - diff --git a/config.tests/unix/ptrsize/ptrsizetest.pro b/config.tests/unix/ptrsize/ptrsizetest.pro deleted file mode 100644 index a7ae38a5d9..0000000000 --- a/config.tests/unix/ptrsize/ptrsizetest.pro +++ /dev/null @@ -1,3 +0,0 @@ -SOURCES = ptrsizetest.cpp -CONFIG -= qt dylib -CONFIG += debug console diff --git a/configure b/configure index 85de53ca63..16e8fb4402 100755 --- a/configure +++ b/configure @@ -6738,19 +6738,6 @@ if [ "$CFG_FRAMEWORK" = "yes" ]; then echo "#define QT_MAC_FRAMEWORK_BUILD" fi -if [ "$XPLATFORM_MAC" = "yes" ]; then - cat <&3 - echo "#define QT_POINTER_SIZE $?" -fi - if [ "$CFG_ATOMIC64" = "no" ]; then echo "#define QT_NO_STD_ATOMIC64" fi diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 02220d0db2..ed8a9163d4 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -120,9 +120,7 @@ Q_CORE_EXPORT void *qMemSet(void *dest, int c, size_t n); // (if this list becomes too long, consider factoring into a separate file) Q_STATIC_ASSERT_X(sizeof(int) == 4, "Qt assumes that int is 32 bits"); Q_STATIC_ASSERT_X(UCHAR_MAX == 255, "Qt assumes that char is 8 bits"); -#ifndef QT_BOOTSTRAPPED -Q_STATIC_ASSERT_X(QT_POINTER_SIZE == sizeof(void *), "configure test ptrsize failed to correctly determine QT_POINTER_SIZE"); -#endif +Q_STATIC_ASSERT_X(QT_POINTER_SIZE == sizeof(void *), "QT_POINTER_SIZE defined incorrectly"); /*! \class QFlag diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index d86e410194..db8c60831f 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -193,18 +193,6 @@ typedef unsigned long long quint64; /* 64 bit unsigned */ typedef qint64 qlonglong; typedef quint64 qulonglong; -#ifndef QT_POINTER_SIZE -# if defined(Q_OS_WIN64) || (defined(Q_OS_WINRT) && defined(_M_X64)) -# define QT_POINTER_SIZE 8 -# elif defined(Q_OS_WIN32) || defined(Q_OS_WINCE) || defined(Q_OS_WINRT) -# define QT_POINTER_SIZE 4 -# elif defined(Q_OS_ANDROID) -# define QT_POINTER_SIZE 4 // ### Add auto-detection to Windows configure -# elif !defined(QT_BOOTSTRAPPED) -# error could not determine QT_POINTER_SIZE -# endif -#endif - /* Useful type definitions for Qt */ diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h index a026224021..4b75872bb6 100644 --- a/src/corelib/global/qprocessordetection.h +++ b/src/corelib/global/qprocessordetection.h @@ -91,6 +91,7 @@ # define Q_PROCESSOR_ARM # if defined(__aarch64__) # define Q_PROCESSOR_ARM_64 +# define Q_PROCESSOR_WORDSIZE 8 # else # define Q_PROCESSOR_ARM_32 # endif @@ -228,6 +229,7 @@ # endif # if defined(_MIPS_ARCH_MIPS64) || defined(__mips64) # define Q_PROCESSOR_MIPS_64 +# define Q_PROCESSOR_WORDSIZE 8 # endif # if defined(__MIPSEL__) # define Q_BYTE_ORDER Q_LITTLE_ENDIAN @@ -252,6 +254,7 @@ # define Q_PROCESSOR_POWER # if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__) # define Q_PROCESSOR_POWER_64 +# define Q_PROCESSOR_WORDSIZE 8 # else # define Q_PROCESSOR_POWER_32 # endif @@ -322,6 +325,28 @@ # endif #endif +/* + Size of a pointer and the machine register size. We detect a 64-bit system by: + * GCC and compatible compilers (Clang, ICC on OS X and Windows) always define + __SIZEOF_POINTER__. This catches all known cases of ILP32 builds on 64-bit + processors. + * Most other Unix compilers define __LP64__ or _LP64 on 64-bit mode + (Long and Pointer 64-bit) + * If Q_PROCESSOR_WORDSIZE was defined above, it's assumed to match the pointer + size. + Otherwise, we assume to be 32-bit and then check in qglobal.cpp that it is right. +*/ + +#if defined __SIZEOF_POINTER__ +# define QT_POINTER_SIZE __SIZEOF_POINTER__ +#elif defined(__LP64__) || defined(_LP64) +# define QT_POINTER_SIZE 8 +#elif defined(Q_PROCESSOR_WORDSIZE) +# define QT_POINTER_SIZE Q_PROCESSOR_WORDSIZE +#else +# define QT_POINTER_SIZE 4 +#endif + /* Define Q_PROCESSOR_WORDSIZE to be the size of the machine's word (usually, the size of the register). On some architectures where a pointer could be @@ -330,14 +355,8 @@ Falls back to QT_POINTER_SIZE if not set explicitly for the platform. */ #ifndef Q_PROCESSOR_WORDSIZE -# ifdef __SIZEOF_POINTER__ - /* GCC & friends define this */ -# define Q_PROCESSOR_WORDSIZE __SIZEOF_POINTER__ -# elif defined(_LP64) || defined(__LP64__) || defined(WIN64) || defined(_WIN64) -# define Q_PROCESSOR_WORDSIZE 8 -# else -# define Q_PROCESSOR_WORDSIZE QT_POINTER_SIZE -# endif +# define Q_PROCESSOR_WORDSIZE QT_POINTER_SIZE #endif + #endif // QPROCESSORDETECTION_H diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 886a383122..6c3217baeb 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -2579,11 +2579,6 @@ void Configure::autoDetection() i.value() = defaultTo(i.key()); } - if (tryCompileProject("unix/ptrsize")) - dictionary["QT_POINTER_SIZE"] = "8"; - else - dictionary["QT_POINTER_SIZE"] = "4"; - cout << "Done running configuration tests." << endl; } @@ -3762,8 +3757,6 @@ void Configure::generateConfigfiles() if (dictionary["REDUCE_RELOCATIONS"] == "yes") qconfigList += "QT_REDUCE_RELOCATIONS"; if (dictionary["QT_GETIFADDRS"] == "no") qconfigList += "QT_NO_GETIFADDRS"; - qconfigList += QString("QT_POINTER_SIZE=%1").arg(dictionary["QT_POINTER_SIZE"]); - qconfigList.sort(); for (int i = 0; i < qconfigList.count(); ++i) tmpStream << addDefine(qconfigList.at(i)); From 39e023b805cf2be207ef7086f6951e789e020bda Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 26 Oct 2015 15:20:41 +0100 Subject: [PATCH 035/133] Remove historical +4 padding in QFontEngine::alphaMapForGlyph() Back in the old days, we would pad the output from the font engines to work around problems with the GL1 paint engine such as issues with linear sampling, etc. This is no longer needed. Padding is moved into the glyph cache, and in addition to reducing performance, the extra padding is also making alphaMapForGlyph() and alphaMapBoundingBox() fall out of sync when you fall back to QPainterPath drawing the glyph. The result of this was that, when prepared, the glyph cache was sometimes not made large enough to hold what alphaMapForGlyph() actually produced, depending on the size and order of glyphs, and glyphs ending up at the end of rows would sometimes be missing from the output. [ChangeLog][Text] Fixed some instances of missing glyphs when drawing large fonts. Change-Id: Ia5982392fe1637f6ebc740db9f226fbb91f75166 Task-number: QTBUG-47547 Reviewed-by: Gunnar Sletta Reviewed-by: Konstantin Ritt --- src/gui/text/qfontengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 6567859a5b..a0eedee6b9 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -961,7 +961,7 @@ QImage QFontEngine::alphaMapForGlyph(glyph_t glyph) pt.y = -glyph_y; // the baseline QPainterPath path; path.setFillRule(Qt::WindingFill); - QImage im(glyph_width + 4, glyph_height, QImage::Format_ARGB32_Premultiplied); + QImage im(glyph_width, glyph_height, QImage::Format_ARGB32_Premultiplied); im.fill(Qt::transparent); QPainter p(&im); p.setRenderHint(QPainter::Antialiasing); From f8eeabcf5ca4615fcb3ed783dbd321f4998a7651 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 23 Oct 2015 16:32:59 +0200 Subject: [PATCH 036/133] QNetworkReplyHttpImpl: convert some QDateTime::currentDateTime() to currentDateTimeUtc() The latter is much faster as it doesn't have to deal with time zones. This change is safe, because the QDateTime is only used to compare against a copy of itself, adjusted by some seconds, which doen't care which TZ the date-time is in, to get a time_t, which is much faster done from a UTC time, and to calculate the seconds to expirationTime, which, from a quick glance around, seem to be mostly, if not exclusively, in UTC. secsTo() works across time zones, but the comparison between UTC date-times is fastest. Credits to Milian Wolff, from whose QtWS15 talk this advice is taken. Change-Id: I22aa5350b29493f01fb503ef5ec68a964ca95cf3 Reviewed-by: Lars Knoll --- src/network/access/qnetworkreplyhttpimpl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index 63fca2bda2..c29b132217 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -512,7 +512,7 @@ bool QNetworkReplyHttpImplPrivate::loadFromCacheIfAllowed(QHttpNetworkRequest &h return false; } - QDateTime currentDateTime = QDateTime::currentDateTime(); + QDateTime currentDateTime = QDateTime::currentDateTimeUtc(); QDateTime expirationDate = metaData.expirationDate(); bool response_is_fresh; @@ -545,7 +545,7 @@ bool QNetworkReplyHttpImplPrivate::loadFromCacheIfAllowed(QHttpNetworkRequest &h date_value = dateHeader.toTime_t(); } - int now = currentDateTime.toUTC().toTime_t(); + int now = currentDateTime.toTime_t(); int request_time = now; int response_time = now; From 29a7f5571cb3619898d8d05c09f7df4ece915aed Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 17 Oct 2015 17:48:34 +0200 Subject: [PATCH 037/133] QtWidgets: use printf-style qWarning/qDebug where possible (I) The printf-style version of QDebug expands to a lot less code than the std::ostream-style version. Of course, you pay in type safety (but compilers warn about it these days), you cannot stream complex Qt types and streaming QStrings is awkward, but in many cases you actually improve on readability. But the main reason is that something that's not supposed to be executed under normal operation has no business bloating executable code size. This is not an attempt at converting all qWarnings() to printf-style, only the low-hanging fruit. In this first part, replace qWarning() << "..."; with qWarning("..."); Change-Id: I1f6869b024103c98262f1deae014e0d7337a541c Reviewed-by: Friedemann Kleint Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/widgets/dialogs/qfiledialog.cpp | 4 ++-- src/widgets/dialogs/qfilesystemmodel.cpp | 2 +- .../src_gui_graphicsview_qgraphicsview.cpp | 2 +- .../graphicsview/qgraphicslinearlayout.cpp | 2 +- .../graphicsview/qgraphicsproxywidget.cpp | 20 +++++++++---------- src/widgets/graphicsview/qgraphicswidget.cpp | 2 +- src/widgets/graphicsview/qsimplex_p.cpp | 8 ++++---- src/widgets/itemviews/qtableview.cpp | 7 ++++--- src/widgets/itemviews/qtreewidget.cpp | 2 +- src/widgets/kernel/qopenglwidget.cpp | 4 ++-- src/widgets/kernel/qwidget.cpp | 2 +- src/widgets/styles/qmacstyle_mac.mm | 4 ++-- src/widgets/util/qflickgesture.cpp | 8 ++++---- src/widgets/util/qscroller.cpp | 2 +- src/widgets/widgets/qdockwidget.cpp | 2 +- src/widgets/widgets/qtoolbarlayout.cpp | 2 +- 16 files changed, 37 insertions(+), 36 deletions(-) diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 443213d0de..cd26a6759f 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -977,7 +977,7 @@ void QFileDialog::setDirectoryUrl(const QUrl &directory) else if (directory.isLocalFile()) setDirectory(directory.toLocalFile()); else if (d->usingWidgets()) - qWarning() << "Non-native QFileDialog supports only local files"; + qWarning("Non-native QFileDialog supports only local files"); } /*! @@ -1087,7 +1087,7 @@ void QFileDialog::selectUrl(const QUrl &url) else if (url.isLocalFile()) selectFile(url.toLocalFile()); else - qWarning() << "Non-native QFileDialog supports only local files"; + qWarning("Non-native QFileDialog supports only local files"); } #ifdef Q_OS_UNIX diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp index 67af7f8107..b1e77540e7 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -473,7 +473,7 @@ void QFileSystemModel::timerEvent(QTimerEvent *event) d->fileInfoGatherer.fetchExtendedInformation(d->toFetch.at(i).dir, QStringList(d->toFetch.at(i).file)); } else { - // qDebug() << "yah!, you saved a little gerbil soul"; + // qDebug("yah!, you saved a little gerbil soul"); } } #endif diff --git a/src/widgets/doc/snippets/code/src_gui_graphicsview_qgraphicsview.cpp b/src/widgets/doc/snippets/code/src_gui_graphicsview_qgraphicsview.cpp index 2f6865c9dd..074b214f80 100644 --- a/src/widgets/doc/snippets/code/src_gui_graphicsview_qgraphicsview.cpp +++ b/src/widgets/doc/snippets/code/src_gui_graphicsview_qgraphicsview.cpp @@ -116,7 +116,7 @@ void CustomView::mousePressEvent(QMouseEvent *event) if (QGraphicsItem *item = itemAt(event->pos())) { qDebug() << "You clicked on item" << item; } else { - qDebug() << "You didn't click on an item."; + qDebug("You didn't click on an item."); } } //! [6] diff --git a/src/widgets/graphicsview/qgraphicslinearlayout.cpp b/src/widgets/graphicsview/qgraphicslinearlayout.cpp index efdf6a595c..0384364ad4 100644 --- a/src/widgets/graphicsview/qgraphicslinearlayout.cpp +++ b/src/widgets/graphicsview/qgraphicslinearlayout.cpp @@ -512,7 +512,7 @@ void QGraphicsLinearLayout::setGeometry(const QRectF &rect) d->engine.setGeometries(effectiveRect, d->styleInfo()); #ifdef QGRIDLAYOUTENGINE_DEBUG if (qt_graphicsLayoutDebug()) { - qDebug() << "post dump"; + qDebug("post dump"); dump(1); } #endif diff --git a/src/widgets/graphicsview/qgraphicsproxywidget.cpp b/src/widgets/graphicsview/qgraphicsproxywidget.cpp index edb0f4e0ff..88bed7cf0e 100644 --- a/src/widgets/graphicsview/qgraphicsproxywidget.cpp +++ b/src/widgets/graphicsview/qgraphicsproxywidget.cpp @@ -1168,7 +1168,7 @@ void QGraphicsProxyWidget::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { Q_D(QGraphicsProxyWidget); #ifdef GRAPHICSPROXYWIDGET_DEBUG - qDebug() << "QGraphicsProxyWidget::hoverMoveEvent"; + qDebug("QGraphicsProxyWidget::hoverMoveEvent"); #endif // Ignore events on the window frame. if (!d->widget || !rect().contains(event->pos())) { @@ -1208,7 +1208,7 @@ void QGraphicsProxyWidget::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { Q_D(QGraphicsProxyWidget); #ifdef GRAPHICSPROXYWIDGET_DEBUG - qDebug() << "QGraphicsProxyWidget::mouseMoveEvent"; + qDebug("QGraphicsProxyWidget::mouseMoveEvent"); #endif d->sendWidgetMouseEvent(event); } @@ -1220,7 +1220,7 @@ void QGraphicsProxyWidget::mousePressEvent(QGraphicsSceneMouseEvent *event) { Q_D(QGraphicsProxyWidget); #ifdef GRAPHICSPROXYWIDGET_DEBUG - qDebug() << "QGraphicsProxyWidget::mousePressEvent"; + qDebug("QGraphicsProxyWidget::mousePressEvent"); #endif d->sendWidgetMouseEvent(event); } @@ -1232,7 +1232,7 @@ void QGraphicsProxyWidget::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event { Q_D(QGraphicsProxyWidget); #ifdef GRAPHICSPROXYWIDGET_DEBUG - qDebug() << "QGraphicsProxyWidget::mouseDoubleClickEvent"; + qDebug("QGraphicsProxyWidget::mouseDoubleClickEvent"); #endif d->sendWidgetMouseEvent(event); } @@ -1245,7 +1245,7 @@ void QGraphicsProxyWidget::wheelEvent(QGraphicsSceneWheelEvent *event) { Q_D(QGraphicsProxyWidget); #ifdef GRAPHICSPROXYWIDGET_DEBUG - qDebug() << "QGraphicsProxyWidget::wheelEvent"; + qDebug("QGraphicsProxyWidget::wheelEvent"); #endif if (!d->widget) return; @@ -1283,7 +1283,7 @@ void QGraphicsProxyWidget::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { Q_D(QGraphicsProxyWidget); #ifdef GRAPHICSPROXYWIDGET_DEBUG - qDebug() << "QGraphicsProxyWidget::mouseReleaseEvent"; + qDebug("QGraphicsProxyWidget::mouseReleaseEvent"); #endif d->sendWidgetMouseEvent(event); } @@ -1295,7 +1295,7 @@ void QGraphicsProxyWidget::keyPressEvent(QKeyEvent *event) { Q_D(QGraphicsProxyWidget); #ifdef GRAPHICSPROXYWIDGET_DEBUG - qDebug() << "QGraphicsProxyWidget::keyPressEvent"; + qDebug("QGraphicsProxyWidget::keyPressEvent"); #endif d->sendWidgetKeyEvent(event); } @@ -1307,7 +1307,7 @@ void QGraphicsProxyWidget::keyReleaseEvent(QKeyEvent *event) { Q_D(QGraphicsProxyWidget); #ifdef GRAPHICSPROXYWIDGET_DEBUG - qDebug() << "QGraphicsProxyWidget::keyReleaseEvent"; + qDebug("QGraphicsProxyWidget::keyReleaseEvent"); #endif d->sendWidgetKeyEvent(event); } @@ -1318,7 +1318,7 @@ void QGraphicsProxyWidget::keyReleaseEvent(QKeyEvent *event) void QGraphicsProxyWidget::focusInEvent(QFocusEvent *event) { #ifdef GRAPHICSPROXYWIDGET_DEBUG - qDebug() << "QGraphicsProxyWidget::focusInEvent"; + qDebug("QGraphicsProxyWidget::focusInEvent"); #endif Q_D(QGraphicsProxyWidget); @@ -1357,7 +1357,7 @@ void QGraphicsProxyWidget::focusInEvent(QFocusEvent *event) void QGraphicsProxyWidget::focusOutEvent(QFocusEvent *event) { #ifdef GRAPHICSPROXYWIDGET_DEBUG - qDebug() << "QGraphicsProxyWidget::focusOutEvent"; + qDebug("QGraphicsProxyWidget::focusOutEvent"); #endif Q_D(QGraphicsProxyWidget); if (d->widget) { diff --git a/src/widgets/graphicsview/qgraphicswidget.cpp b/src/widgets/graphicsview/qgraphicswidget.cpp index 67311ed2c3..8ffb60411c 100644 --- a/src/widgets/graphicsview/qgraphicswidget.cpp +++ b/src/widgets/graphicsview/qgraphicswidget.cpp @@ -2398,7 +2398,7 @@ bool QGraphicsWidget::close() #if 0 void QGraphicsWidget::dumpFocusChain() { - qDebug() << "=========== Dumping focus chain =============="; + qDebug("=========== Dumping focus chain =============="); int i = 0; QGraphicsWidget *next = this; QSet visited; diff --git a/src/widgets/graphicsview/qsimplex_p.cpp b/src/widgets/graphicsview/qsimplex_p.cpp index 1aeade6640..b827ab1400 100644 --- a/src/widgets/graphicsview/qsimplex_p.cpp +++ b/src/widgets/graphicsview/qsimplex_p.cpp @@ -140,7 +140,7 @@ bool QSimplex::setConstraints(const QList &newConstraints) // Remove constraints of type Var == K and replace them for their value. if (!simplifyConstraints(&constraints)) { - qWarning() << "QSimplex: No feasible solution!"; + qWarning("QSimplex: No feasible solution!"); clearDataStructures(); return false; } @@ -230,7 +230,7 @@ bool QSimplex::setConstraints(const QList &newConstraints) matrix = (qreal *)malloc(sizeof(qreal) * columns * rows); if (!matrix) { - qWarning() << "QSimplex: Unable to allocate memory!"; + qWarning("QSimplex: Unable to allocate memory!"); return false; } for (int i = columns * rows - 1; i >= 0; --i) @@ -281,7 +281,7 @@ bool QSimplex::setConstraints(const QList &newConstraints) // Otherwise, we clean up our structures and report there is // no feasible solution. if ((valueAt(0, columns - 1) != 0.0) && (qAbs(valueAt(0, columns - 1)) > 0.00001)) { - qWarning() << "QSimplex: No feasible solution!"; + qWarning("QSimplex: No feasible solution!"); clearDataStructures(); return false; } @@ -471,7 +471,7 @@ bool QSimplex::iterate() // Find Pivot row for column int pivotRow = pivotRowForColumn(pivotColumn); if (pivotRow == -1) { - qWarning() << "QSimplex: Unbounded problem!"; + qWarning("QSimplex: Unbounded problem!"); return false; } diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp index 0af4a26494..89bd9dbcb1 100644 --- a/src/widgets/itemviews/qtableview.cpp +++ b/src/widgets/itemviews/qtableview.cpp @@ -670,13 +670,14 @@ void QTableViewPrivate::trimHiddenSelections(QItemSelectionRange *range) const void QTableViewPrivate::setSpan(int row, int column, int rowSpan, int columnSpan) { if (row < 0 || column < 0 || rowSpan <= 0 || columnSpan <= 0) { - qWarning() << "QTableView::setSpan: invalid span given: (" << row << ',' << column << ',' << rowSpan << ',' << columnSpan << ')'; + qWarning("QTableView::setSpan: invalid span given: (%d, %d, %d, %d)", + row, column, rowSpan, columnSpan); return; } QSpanCollection::Span *sp = spans.spanAt(column, row); if (sp) { if (sp->top() != row || sp->left() != column) { - qWarning() << "QTableView::setSpan: span cannot overlap"; + qWarning("QTableView::setSpan: span cannot overlap"); return; } if (rowSpan == 1 && columnSpan == 1) { @@ -688,7 +689,7 @@ void QTableViewPrivate::setSpan(int row, int column, int rowSpan, int columnSpan spans.updateSpan(sp, old_height); return; } else if (rowSpan == 1 && columnSpan == 1) { - qWarning() << "QTableView::setSpan: single cell span won't be added"; + qWarning("QTableView::setSpan: single cell span won't be added"); return; } sp = new QSpanCollection::Span(row, column, rowSpan, columnSpan); diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp index db4451c99a..676893ebf0 100644 --- a/src/widgets/itemviews/qtreewidget.cpp +++ b/src/widgets/itemviews/qtreewidget.cpp @@ -3281,7 +3281,7 @@ QMimeData *QTreeWidget::mimeData(const QList items) const for (int i = 0; i < items.count(); ++i) { QTreeWidgetItem *item = items.at(i); if (!item) { - qWarning() << "QTreeWidget::mimeData: Null-item passed"; + qWarning("QTreeWidget::mimeData: Null-item passed"); return 0; } diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index 65a70ceb02..389539bb18 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -647,8 +647,8 @@ GLuint QOpenGLWidgetPrivate::textureId() const { Q_Q(const QOpenGLWidget); if (!q->isWindow() && q->internalWinId()) { - qWarning() << "QOpenGLWidget cannot be used as a native child widget." - << "Consider setting Qt::WA_DontCreateNativeAncestors and Qt::AA_DontCreateNativeWidgetSiblings."; + qWarning("QOpenGLWidget cannot be used as a native child widget. Consider setting " + "Qt::WA_DontCreateNativeAncestors and Qt::AA_DontCreateNativeWidgetSiblings"); return 0; } return resolvedFbo ? resolvedFbo->texture() : (fbo ? fbo->texture() : 0); diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index a006246454..773471533e 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -12099,7 +12099,7 @@ QOpenGLContext *QWidgetPrivate::shareContext() const return 0; #else if (!extra || !extra->topextra || !extra->topextra->window) { - qWarning() << "Asking for share context for widget that does not have a window handle"; + qWarning("Asking for share context for widget that does not have a window handle"); return 0; } QWidgetPrivate *that = const_cast(this); diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index e8da137654..a1c5e82ad1 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -7191,7 +7191,7 @@ CGContextRef qt_mac_cg_context(const QPaintDevice *pdev) ret = CGBitmapContextCreate(image->bits(), image->width(), image->height(), 8, image->bytesPerLine(), colorspace, flags); } else { - qDebug() << "qt_mac_cg_context: Unsupported pixmap class"; + qDebug("qt_mac_cg_context: Unsupported pixmap class"); } CGContextTranslateCTM(ret, 0, pm->height()); @@ -7203,7 +7203,7 @@ CGContextRef qt_mac_cg_context(const QPaintDevice *pdev) //CGContextRef ret = static_cast(static_cast(pdev)->macCGHandle()); ///CGContextRetain(ret); //return ret; - qDebug() << "qt_mac_cg_context: not implemented: Widget class"; + qDebug("qt_mac_cg_context: not implemented: Widget class"); return 0; } return 0; diff --git a/src/widgets/util/qflickgesture.cpp b/src/widgets/util/qflickgesture.cpp index 8eadc42625..c7e0861a0f 100644 --- a/src/widgets/util/qflickgesture.cpp +++ b/src/widgets/util/qflickgesture.cpp @@ -155,9 +155,9 @@ public: mouseTarget = QApplication::widgetAt(pressDelayEvent->globalPos()); mouseButton = pressDelayEvent->button(); mouseEventSource = pressDelayEvent->source(); - qFGDebug() << "QFG: consuming/delaying mouse press"; + qFGDebug("QFG: consuming/delaying mouse press"); } else { - qFGDebug() << "QFG: NOT consuming/delaying mouse press"; + qFGDebug("QFG: NOT consuming/delaying mouse press"); } e->setAccepted(true); } @@ -194,7 +194,7 @@ public: void scrollerWasIntercepted() { - qFGDebug() << "QFG: deleting delayed mouse press, since scroller was only intercepted"; + qFGDebug("QFG: deleting delayed mouse press, since scroller was only intercepted"); if (pressDelayEvent) { // we still haven't even sent the press, so just throw it away now if (pressDelayTimer) { @@ -210,7 +210,7 @@ public: { if (pressDelayEvent) { // we still haven't even sent the press, so just throw it away now - qFGDebug() << "QFG: deleting delayed mouse press, since scroller is active now"; + qFGDebug("QFG: deleting delayed mouse press, since scroller is active now"); if (pressDelayTimer) { killTimer(pressDelayTimer); pressDelayTimer = 0; diff --git a/src/widgets/util/qscroller.cpp b/src/widgets/util/qscroller.cpp index 563c501356..0065ccf6b3 100644 --- a/src/widgets/util/qscroller.cpp +++ b/src/widgets/util/qscroller.cpp @@ -1668,7 +1668,7 @@ bool QScrollerPrivate::releaseWhileDragging(const QPointF &position, qint64 time void QScrollerPrivate::timerEventWhileScrolling() { - qScrollerDebug() << "QScroller::timerEventWhileScrolling()"; + qScrollerDebug("QScroller::timerEventWhileScrolling()"); setContentPositionHelperScrolling(); if (xSegments.isEmpty() && ySegments.isEmpty()) diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp index 8b0263fc0c..b30f49bea6 100644 --- a/src/widgets/widgets/qdockwidget.cpp +++ b/src/widgets/widgets/qdockwidget.cpp @@ -245,7 +245,7 @@ bool QDockWidgetLayout::nativeWindowDeco(bool floating) const void QDockWidgetLayout::addItem(QLayoutItem*) { - qWarning() << "QDockWidgetLayout::addItem(): please use QDockWidgetLayout::setWidget()"; + qWarning("QDockWidgetLayout::addItem(): please use QDockWidgetLayout::setWidget()"); return; } diff --git a/src/widgets/widgets/qtoolbarlayout.cpp b/src/widgets/widgets/qtoolbarlayout.cpp index d478b028a6..42fd93fda2 100644 --- a/src/widgets/widgets/qtoolbarlayout.cpp +++ b/src/widgets/widgets/qtoolbarlayout.cpp @@ -153,7 +153,7 @@ void QToolBarLayout::checkUsePopupMenu() void QToolBarLayout::addItem(QLayoutItem*) { - qWarning() << "QToolBarLayout::addItem(): please use addAction() instead"; + qWarning("QToolBarLayout::addItem(): please use addAction() instead"); return; } From 8b9346c7404287b4c546b49c23f24ccbef0f8b6e Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Mon, 26 Oct 2015 15:28:36 +0100 Subject: [PATCH 038/133] Item Views: Avoid reentrant call in updateEditorGeometries() This may result in incrementing an invalid iterator after the iterator's container has changed. Also, for this to happen, the view needs to have an active editor. The reentrant call happens as follows in QTreeView, after the model adds new rows to the view: QTreeView::rowsInserted() QAbstractItemView::rowsInserted() QAbstractItemView::updateEditorGeometries() QTreeView::visualRect() QAbstractItemViewPrivate::executePostedLayout() QTreeView::doItemsLayout() QAbstractItemView::doItemsLayout() QTreeView::updateGeometries() QAbstractItemView::updateGeometries() QAbstractItemView::updateEditorGeometries() Other concrete item view classes may be prone to the same issue. The fix consists in relayouting the items if needed, which should trigger calling updateEditorGeometries() again. This doesn't invalidate previous optimizations regarding item relayouting since we only force relayouting when it'll be done by visualRect(). Change-Id: Id31507fdc8d9a84d50265298191d690d1a06792b Task-number: QTBUG-48968 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/widgets/itemviews/qabstractitemview.cpp | 5 +++ .../tst_qabstractitemview.cpp | 38 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 3bb4d0624f..ad7be840d0 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -2636,6 +2636,11 @@ void QAbstractItemView::updateEditorGeometries() Q_D(QAbstractItemView); if(d->editorIndexHash.isEmpty()) return; + if (d->delayedPendingLayout) { + // doItemsLayout() will end up calling this function again + d->executePostedLayout(); + return; + } QStyleOptionViewItem option = d->viewOptionsV1(); QEditorIndexHash::iterator it = d->editorIndexHash.begin(); QWidgetList editorsToRelease; diff --git a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp index fac3f5857b..3a17f7c690 100644 --- a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp +++ b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp @@ -250,6 +250,7 @@ private slots: void QTBUG39324_settingSameInstanceOfIndexWidget(); void sizeHintChangeTriggersLayout(); void shiftSelectionAfterChangingModelContents(); + void QTBUG48968_reentrant_updateEditorGeometries(); }; class MyAbstractItemDelegate : public QAbstractItemDelegate @@ -1990,5 +1991,42 @@ void tst_QAbstractItemView::shiftSelectionAfterChangingModelContents() QVERIFY(selected.contains(indexE)); } +void tst_QAbstractItemView::QTBUG48968_reentrant_updateEditorGeometries() +{ + + QStandardItemModel *m = new QStandardItemModel(this); + for (int i=0; i<10; ++i) { + QStandardItem *item = new QStandardItem(QString("Item number %1").arg(i)); + item->setEditable(true); + for (int j=0; j<5; ++j) { + QStandardItem *child = new QStandardItem(QString("Child Item number %1").arg(j)); + item->setChild(j, 0, child); + } + m->setItem(i, 0, item); + } + + QTreeView tree; + tree.setModel(m); + tree.setRootIsDecorated(false); + QObject::connect(&tree, SIGNAL(doubleClicked(QModelIndex)), &tree, SLOT(setRootIndex(QModelIndex))); + tree.show(); + QTest::qWaitForWindowActive(&tree); + + // Trigger editing idx + QModelIndex idx = m->index(1, 0); + const QPoint pos = tree.visualRect(idx).center(); + QTest::mouseClick(tree.viewport(), Qt::LeftButton, Qt::NoModifier, pos); + QTest::mouseDClick(tree.viewport(), Qt::LeftButton, Qt::NoModifier, pos); + + // Add more children to idx + QStandardItem *item = m->itemFromIndex(idx); + for (int j=5; j<10; ++j) { + QStandardItem *child = new QStandardItem(QString("Child Item number %1").arg(j)); + item->setChild(j, 0, child); + } + + // No crash, all fine. +} + QTEST_MAIN(tst_QAbstractItemView) #include "tst_qabstractitemview.moc" From 69032adda0bf10bb51a44bbfc87752608a5f86a6 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 23 Oct 2015 10:53:15 +0200 Subject: [PATCH 039/133] Windows QPA: Fix debug operators. Enclose all debug operators within QT_NO_DEBUG_STREAM, declare all public ones and make the others static. Add operators for POINT and WINDOWPLACEMENT. Task-number: QTBUG-48449 Change-Id: I33f2dba2bf486a8f5cb11f11f4e2b37cce086def Reviewed-by: Joerg Bornemann --- .../platforms/windows/qwindowsclipboard.cpp | 2 + .../windows/qwindowsdialoghelpers.cpp | 2 + .../platforms/windows/qwindowsdrag.cpp | 6 +-- .../windows/qwindowsfontdatabase.cpp | 2 + .../platforms/windows/qwindowsfontdatabase.h | 4 ++ .../windows/qwindowsfontdatabase_ft.cpp | 2 +- .../platforms/windows/qwindowsglcontext.cpp | 52 ++++++++++--------- .../platforms/windows/qwindowsglcontext.h | 6 ++- .../platforms/windows/qwindowsmime.cpp | 4 +- src/plugins/platforms/windows/qwindowsmime.h | 2 +- .../windows/qwindowsopengltester.cpp | 2 + .../platforms/windows/qwindowsopengltester.h | 2 + .../platforms/windows/qwindowsscreen.cpp | 2 + .../windows/qwindowstabletsupport.cpp | 4 ++ .../platforms/windows/qwindowstabletsupport.h | 2 + .../platforms/windows/qwindowswindow.cpp | 48 +++++++++++------ .../platforms/windows/qwindowswindow.h | 9 ++-- 17 files changed, 98 insertions(+), 53 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp index 97459a4d97..8936b96b1f 100644 --- a/src/plugins/platforms/windows/qwindowsclipboard.cpp +++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp @@ -69,6 +69,7 @@ static const char formatTextHtmlC[] = "text/html"; \ingroup qt-lighthouse-win */ +#ifndef QT_NO_DEBUG_STREAM static QDebug operator<<(QDebug d, const QMimeData *mimeData) { QDebugStateSaver saver(d); @@ -93,6 +94,7 @@ static QDebug operator<<(QDebug d, const QMimeData *mimeData) d << ')'; return d; } +#endif // !QT_NO_DEBUG_STREAM /*! \class QWindowsClipboardRetrievalMimeData diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index da0ba27e3a..b983ba3354 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -360,6 +360,7 @@ public: QT_BEGIN_NAMESPACE +#ifndef QT_NO_DEBUG_STREAM /* Output UID (IID, CLSID) as C++ constants. * The constants are contained in the Windows SDK libs, but not for MinGW. */ static inline QString guidToString(const GUID &g) @@ -385,6 +386,7 @@ inline QDebug operator<<(QDebug d, const GUID &g) d << guidToString(g); return d; } +#endif // !QT_NO_DEBUG_STREAM // Return an allocated wchar_t array from a QString, reserve more memory if desired. static wchar_t *qStringToWCharArray(const QString &s, size_t reserveSize = 0) diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp index d24cba3c68..870e7fec07 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.cpp +++ b/src/plugins/platforms/windows/qwindowsdrag.cpp @@ -249,7 +249,7 @@ private: QWindowsDragCursorWindow *m_touchDragWindow; ULONG m_refs; -#ifndef QT_NO_DEBUG_OUTPUT +#ifndef QT_NO_DEBUG_STREAM friend QDebug operator<<(QDebug, const QWindowsOleDropSource::CursorEntry &); #endif }; @@ -271,14 +271,14 @@ QWindowsOleDropSource::~QWindowsOleDropSource() qCDebug(lcQpaMime) << __FUNCTION__; } -#ifndef QT_NO_DEBUG_OUTPUT +#ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const QWindowsOleDropSource::CursorEntry &e) { d << "CursorEntry:" << e.pixmap.size() << '#' << e.cacheKey << "HCURSOR" << e.cursor->cursor << "hotspot:" << e.hotSpot; return d; } -#endif // !QT_NO_DEBUG_OUTPUT +#endif // !QT_NO_DEBUG_STREAM static qreal dragScaleFactor() { diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index 3b27964b0e..9531d30e06 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -606,6 +606,7 @@ static inline bool initDirectWrite(QWindowsFontEngineData *d) \ingroup qt-lighthouse-win */ +#ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const QFontDef &def) { QDebugStateSaver saver(d); @@ -617,6 +618,7 @@ QDebug operator<<(QDebug d, const QFontDef &def) << def.hintingPreference; return d; } +#endif // !QT_NO_DEBUG_STREAM static inline QFontDatabase::WritingSystem writingSystemFromCharSet(uchar charSet) { diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.h b/src/plugins/platforms/windows/qwindowsfontdatabase.h index efb5421996..10b6315aab 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.h +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.h @@ -118,6 +118,10 @@ private: QMap m_uniqueFontData; }; +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug, const QFontDef &def); +#endif + QT_END_NAMESPACE #endif // QWINDOWSFONTDATABASE_H diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp index 795554698c..16cc2afef6 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp @@ -355,7 +355,7 @@ static bool addFontToDatabase(const QString &faceName, const QFont::Weight weight = QPlatformFontDatabase::weightFromInteger(tm->tmWeight); const QFont::Stretch stretch = QFont::Unstretched; -#ifndef QT_NO_DEBUG_OUTPUT +#ifndef QT_NO_DEBUG_STREAM if (QWindowsContext::verbose > 2) { QString message; QTextStream str(&message); diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp index e372acc747..a06707b84c 100644 --- a/src/plugins/platforms/windows/qwindowsglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp @@ -284,6 +284,7 @@ static inline void initPixelFormatDescriptor(PIXELFORMATDESCRIPTOR *d) d->nVersion = 1; } +#ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const PIXELFORMATDESCRIPTOR &pd) { QDebugStateSaver saver(d); @@ -326,6 +327,32 @@ QDebug operator<<(QDebug d, const PIXELFORMATDESCRIPTOR &pd) return d; } +QDebug operator<<(QDebug d, const QOpenGLStaticContext &s) +{ + QDebugStateSaver saver(d); + d.nospace(); + d << "OpenGL: " << s.vendor << ',' << s.renderer << " default " + << s.defaultFormat; + if (s.extensions & QOpenGLStaticContext::SampleBuffers) + d << ",SampleBuffers"; + if (s.hasExtensions()) + d << ", Extension-API present"; + d << "\nExtensions: " << (s.extensionNames.count(' ') + 1); + if (QWindowsContext::verbose > 1) + d << s.extensionNames; + return d; +} + +QDebug operator<<(QDebug d, const QWindowsOpenGLContextFormat &f) +{ + QDebugStateSaver saver(d); + d.nospace(); + d << "ContextFormat: v" << (f.version >> 8) << '.' << (f.version & 0xFF) + << " profile: " << f.profile << " options: " << f.options; + return d; +} +#endif // !QT_NO_DEBUG_STREAM + // Check whether an obtained PIXELFORMATDESCRIPTOR matches the request. static inline bool isAcceptableFormat(const QWindowsOpenGLAdditionalFormat &additional, @@ -900,15 +927,6 @@ void QWindowsOpenGLContextFormat::apply(QSurfaceFormat *format) const format->setOption(QSurfaceFormat::DeprecatedFunctions); } -QDebug operator<<(QDebug d, const QWindowsOpenGLContextFormat &f) -{ - QDebugStateSaver saver(d); - d.nospace(); - d << "ContextFormat: v" << (f.version >> 8) << '.' << (f.version & 0xFF) - << " profile: " << f.profile << " options: " << f.options; - return d; -} - /*! \class QOpenGLTemporaryContext \brief A temporary context that can be instantiated on the stack. @@ -1013,22 +1031,6 @@ QOpenGLStaticContext *QOpenGLStaticContext::create(bool softwareRendering) return result; } -QDebug operator<<(QDebug d, const QOpenGLStaticContext &s) -{ - QDebugStateSaver saver(d); - d.nospace(); - d << "OpenGL: " << s.vendor << ',' << s.renderer << " default " - << s.defaultFormat; - if (s.extensions & QOpenGLStaticContext::SampleBuffers) - d << ",SampleBuffers"; - if (s.hasExtensions()) - d << ", Extension-API present"; - d << "\nExtensions: " << (s.extensionNames.count(' ') + 1); - if (QWindowsContext::verbose > 1) - d << s.extensionNames; - return d; -} - /*! \class QWindowsGLContext \brief Open GL context. diff --git a/src/plugins/platforms/windows/qwindowsglcontext.h b/src/plugins/platforms/windows/qwindowsglcontext.h index 516fa0707e..ba617f13ce 100644 --- a/src/plugins/platforms/windows/qwindowsglcontext.h +++ b/src/plugins/platforms/windows/qwindowsglcontext.h @@ -85,7 +85,11 @@ struct QWindowsOpenGLContextFormat QSurfaceFormat::FormatOptions options; }; +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug d, const PIXELFORMATDESCRIPTOR &); QDebug operator<<(QDebug d, const QWindowsOpenGLContextFormat &); +QDebug operator<<(QDebug d, const QOpenGLStaticContext &s); +#endif struct QWindowsOpengl32DLL { @@ -224,8 +228,6 @@ public: static QWindowsOpengl32DLL opengl32; }; -QDebug operator<<(QDebug d, const QOpenGLStaticContext &); - class QWindowsGLContext : public QWindowsOpenGLContext { public: diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp index 52a4ca26dc..0a2ba9b0e7 100644 --- a/src/plugins/platforms/windows/qwindowsmime.cpp +++ b/src/plugins/platforms/windows/qwindowsmime.cpp @@ -378,7 +378,7 @@ static bool canGetData(int cf, IDataObject * pDataObj) return true; } -#ifndef QT_NO_DEBUG_OUTPUT +#ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const FORMATETC &tc) { QDebugStateSaver saver(d); @@ -443,7 +443,7 @@ QDebug operator<<(QDebug d, IDataObject *dataObj) d << ')'; return d; } -#endif // !QT_NO_DEBUG_OUTPUT +#endif // !QT_NO_DEBUG_STREAM /*! \class QWindowsMime diff --git a/src/plugins/platforms/windows/qwindowsmime.h b/src/plugins/platforms/windows/qwindowsmime.h index 17fddef1bc..1ec0dccdf8 100644 --- a/src/plugins/platforms/windows/qwindowsmime.h +++ b/src/plugins/platforms/windows/qwindowsmime.h @@ -93,7 +93,7 @@ private: mutable int m_internalMimeCount; }; -#ifndef QT_NO_DEBUG_OUTPUT +#ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug, const FORMATETC &); QDebug operator<<(QDebug d, IDataObject *); #endif diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp index befd06f1a2..e32a7e32af 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.cpp +++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp @@ -98,6 +98,7 @@ GpuDescription GpuDescription::detect() #endif } +#ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const GpuDescription &gd) { QDebugStateSaver s(d); @@ -109,6 +110,7 @@ QDebug operator<<(QDebug d, const GpuDescription &gd) << ", version=" << gd.driverVersion << ", " << gd.description << ')'; return d; } +#endif // !QT_NO_DEBUG_STREAM // Return printable string formatted like the output of the dxdiag tool. QString GpuDescription::toString() const diff --git a/src/plugins/platforms/windows/qwindowsopengltester.h b/src/plugins/platforms/windows/qwindowsopengltester.h index 3cd8bf4d4b..f22031aa4e 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.h +++ b/src/plugins/platforms/windows/qwindowsopengltester.h @@ -60,7 +60,9 @@ struct GpuDescription QByteArray description; }; +#ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const GpuDescription &gd); +#endif class QWindowsOpenGLTester { diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp index e6abfb2403..c603b2bd09 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -172,6 +172,7 @@ static inline WindowsScreenDataList monitorData() return result; } +#ifndef QT_NO_DEBUG_STREAM static QDebug operator<<(QDebug dbg, const QWindowsScreenData &d) { QDebugStateSaver saver(dbg); @@ -192,6 +193,7 @@ static QDebug operator<<(QDebug dbg, const QWindowsScreenData &d) dbg << " lock screen"; return dbg; } +#endif // !QT_NO_DEBUG_STREAM // Return the cursor to be shared by all screens (virtual desktop). static inline QSharedPointer sharedCursor() diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp index 3951401273..b27811df9e 100644 --- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp +++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp @@ -302,8 +302,11 @@ static inline QTabletEvent::PointerType pointerType(unsigned currentCursor) return QTabletEvent::UnknownPointer; } +#ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const QWindowsTabletDeviceData &t) { + QDebugStateSaver saver(d); + d.nospace(); d << "TabletDevice id:" << t.uniqueId << " pressure: " << t.minPressure << ".." << t.maxPressure << " tan pressure: " << t.minTanPressure << ".." << t.maxTanPressure << " area:" << t.minX << t.minY < 100) { + // Such a loop is unlikely to contribute something useful to the + // file collection, and may cause considerable delay. + traceMsg("skipping excessive loop in cumulative mode"); + return ReturnFalse; + } if (start < end) { for (int i = start; i <= end; i++) list << ProString(QString::number(i)); From bbf2f1dbbfd862cb7bfb47e62ad54740990e5b82 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 8 Aug 2013 18:01:22 +0200 Subject: [PATCH 043/133] don't complain about missing include()s during cumulative evaluation it produces simply too many false positives. Change-Id: I3dfa109866450babe5c16f84665ad22024d99e42 Reviewed-by: Joerg Bornemann (cherry picked from qttools/08bae158320f6d73bf44fcf43f45f51a01334544) Reviewed-by: Joerg Bornemann --- qmake/library/qmakebuiltins.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index 02d5d5dd31..51ba6dc0a0 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -1387,6 +1387,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( } QString parseInto; LoadFlags flags = 0; + if (m_cumulative) + flags = LoadSilent; if (args.count() >= 2) { parseInto = args.at(1).toQString(m_tmp2); if (args.count() >= 3 && isTrue(args.at(2), m_tmp3)) From 771724d2f47aefb24b1627a7e60cf3a90bcbe772 Mon Sep 17 00:00:00 2001 From: Daniel Teske Date: Fri, 6 Sep 2013 15:14:38 +0200 Subject: [PATCH 044/133] ProParser: Plug raw data leak QProcessEnvironment caches keys, so we must not pass it QStrings created with fromRawData() Task-number: QTCREATORBUG-9142 Change-Id: I29fade02f3bc4110fafb1b04d44f2e653951a2ae Reviewed-by: Oswald Buddenhagen (cherry picked from qtcreator/99f15f1706868c4b2f84bc4164451bd69b3b8188) Reviewed-by: Joerg Bornemann --- qmake/library/qmakeevaluator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp index a1c2b5fcea..73ea10daf8 100644 --- a/qmake/library/qmakeevaluator.cpp +++ b/qmake/library/qmakeevaluator.cpp @@ -452,7 +452,7 @@ void QMakeEvaluator::evaluateExpression( break; } case TokEnvVar: { const ProString &var = pro->getStr(tokPtr); - const ProString &val = ProString(m_option->getEnv(var.toQString(m_tmp1))); + const ProString &val = ProString(m_option->getEnv(var.toQString())); debugMsg(2, "env var %s => %s", dbgStr(var), dbgStr(val)); addStr(val, ret, pending, joined); break; } From eba9769b7e794cf1df204d8365a84e7f70c5a510 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Tue, 14 Jan 2014 14:21:10 +0100 Subject: [PATCH 045/133] QmakeParser: Do not leak temporaries into cache of files This prevents an access to free'd memory when opening qtcreator.pro. Looks like qml2puppet.pro gets added to that cache in QMakeVfs::writeFile with part of the including pro-file's filename in it. That part gets cleaned when that containing ProFile goes out of scope, leaving a key in QMakeVfs::m_files free'd but accessible. Change-Id: I80b43d2fbb66c214647497ea97e6e3a587e274d6 Reviewed-by: Oswald Buddenhagen (cherry picked from qtcreator/336c3159617cdb3edd35021b5fb312d4d43f9a84) Reviewed-by: Joerg Bornemann --- qmake/library/qmakebuiltins.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index 51ba6dc0a0..4398937015 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -1556,7 +1556,9 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( if (!args.at(2).toQString(m_tmp1).compare(fL1S("append"), Qt::CaseInsensitive)) mode = QIODevice::Append; } - return writeFile(QString(), resolvePath(args.at(0).toQString(m_tmp1)), mode, contents); + QString path = resolvePath(args.at(0).toQString(m_tmp1)); + path.detach(); // make sure to not leak m_tmp1 into the map of written files. + return writeFile(QString(), path, mode, contents); } case T_TOUCH: { if (args.count() != 2) { From 07ada2fb60d46e688c380148b23f0362a285a32f Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 5 Feb 2014 19:54:01 +0100 Subject: [PATCH 046/133] micro-optimization: use ProStringList::join(QChar) overload Change-Id: I25c6205df78da7fbee0ad1b04476f528f376b7a6 Reviewed-by: Daniel Teske (cherry picked from qtcreator/701a82d3a2185702c09dfecb361853fc18947807) Reviewed-by: Joerg Bornemann --- qmake/library/qmakebuiltins.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index 4398937015..bb07ad44a3 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -1551,7 +1551,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( if (args.count() >= 2) { const ProStringList &vals = values(args.at(1).toKey()); if (!vals.isEmpty()) - contents = vals.join(fL1S("\n")) + QLatin1Char('\n'); + contents = vals.join(QLatin1Char('\n')) + QLatin1Char('\n'); if (args.count() >= 3) if (!args.at(2).toQString(m_tmp1).compare(fL1S("append"), Qt::CaseInsensitive)) mode = QIODevice::Append; From a8010f2d0387cf13f54cf01d2bc0877fbd055351 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 5 Feb 2014 21:26:37 +0100 Subject: [PATCH 047/133] fix raw data leak in $$sprintf() it could be only triggered by abusing the function (no expansion actually done), and nobody is using this to start with, but still ... Change-Id: I3d4a23ae4d1eea07955572d8213094e0dc218f6d Reviewed-by: Daniel Teske (cherry picked from qtcreator/cdc2a0f72334268684e0407e9b04b3188e00d4bf) Reviewed-by: Joerg Bornemann --- qmake/library/qmakebuiltins.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index bb07ad44a3..f57d9c89a7 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -514,7 +514,7 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( QString tmp = args.at(0).toQString(m_tmp1); for (int i = 1; i < args.count(); ++i) tmp = tmp.arg(args.at(i).toQString(m_tmp2)); - ret << ProString(tmp); + ret << (tmp.isSharedWith(m_tmp1) ? args.at(0) : ProString(tmp).setSource(args.at(0))); } break; case E_FORMAT_NUMBER: From b4e6409feadc5c0f33338df2ea824b28345561a0 Mon Sep 17 00:00:00 2001 From: Daniel Teske Date: Fri, 7 Mar 2014 12:56:59 +0100 Subject: [PATCH 048/133] add ProFile::tokPtrEnd() just syncing up with qtcreator. Change-Id: I2bda6961f6f1164bdc58acd78fa3d2221977f0cf Reviewed-by: Oswald Buddenhagen (cherry picked from qtcreator/765ad6c3d28813d4baa0aeafd03076ba76557d3d) Reviewed-by: Joerg Bornemann --- qmake/library/proitems.h | 1 + 1 file changed, 1 insertion(+) diff --git a/qmake/library/proitems.h b/qmake/library/proitems.h index 9430d28521..e4ef1d1586 100644 --- a/qmake/library/proitems.h +++ b/qmake/library/proitems.h @@ -342,6 +342,7 @@ public: const QString &items() const { return m_proitems; } QString *itemsRef() { return &m_proitems; } const ushort *tokPtr() const { return (const ushort *)m_proitems.constData(); } + const ushort *tokPtrEnd() const { return (const ushort *)m_proitems.constData() + m_proitems.size(); } void ref() { m_refCount.ref(); } void deref() { if (!m_refCount.deref()) delete this; } From 193c6d2ebbac453f12c24def302f08f3b85e6d2a Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 22 May 2014 15:21:36 +0200 Subject: [PATCH 049/133] avoid that a bad qmakespec path crashes the evaluator assigning a relative path to QMAKESPEC or QMAKESPEC_ORIGINAL (in the qt4 windows legacy code) would lead to an assert further down the line. just ignore such attempts silently. Task-number: QTCREATORBUG-8477 Change-Id: Ie53d0ef004c743284b85de4e89f112e0161ff4b7 Reviewed-by: Daniel Teske (cherry picked from qtcreator/e017a1dc8b2030e509d6198315e9f6a9869667e7) Reviewed-by: Joerg Bornemann --- qmake/library/qmakeevaluator.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp index 73ea10daf8..efda9df7d4 100644 --- a/qmake/library/qmakeevaluator.cpp +++ b/qmake/library/qmakeevaluator.cpp @@ -912,8 +912,11 @@ void QMakeEvaluator::visitProVariable( m_featureRoots = 0; else if (varName == statics.strQMAKESPEC) { if (!values(varName).isEmpty()) { - m_qmakespec = values(varName).first().toQString(); - m_featureRoots = 0; + QString spec = values(varName).first().toQString(); + if (IoUtils::isAbsolutePath(spec)) { + m_qmakespec = spec; + m_featureRoots = 0; + } } } #ifdef PROEVALUATOR_FULL @@ -1159,8 +1162,11 @@ bool QMakeEvaluator::loadSpecInternal() // the source of the qmake.conf at the end of the default/qmake.conf in // the QMAKESPEC_ORIGINAL variable. const ProString &orig_spec = first(ProKey("QMAKESPEC_ORIGINAL")); - if (!orig_spec.isEmpty()) - m_qmakespec = orig_spec.toQString(); + if (!orig_spec.isEmpty()) { + QString spec = orig_spec.toQString(); + if (IoUtils::isAbsolutePath(spec)) + m_qmakespec = spec; + } # endif #endif valuesRef(ProKey("QMAKESPEC")) = ProString(m_qmakespec); From 7b1a8e047cd2823246568cabf9b604888b3e8bd9 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 26 Jun 2014 12:37:39 +0200 Subject: [PATCH 050/133] consider qt resource paths absolute this fixes an assertion failure with qt4 mingw specs when PATH contains a "." element. Task-number: QTCREATORBUG-12528 Change-Id: I2b6b7e02cf38881d40bd78bb0d705f7d58d0736c Reviewed-by: Christian Kandeler (cherry picked from qtcreator/d0428a05220ed0550dd84cdb8299a1fb37b0fe72) Reviewed-by: Christian Kandeler --- qmake/library/ioutils.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/qmake/library/ioutils.cpp b/qmake/library/ioutils.cpp index 04be215246..a2f3e8ec3d 100644 --- a/qmake/library/ioutils.cpp +++ b/qmake/library/ioutils.cpp @@ -68,6 +68,10 @@ bool IoUtils::isRelativePath(const QString &path) { if (path.startsWith(QLatin1Char('/'))) return false; +#ifdef QMAKE_BUILTIN_PRFS + if (path.startsWith(QLatin1String(":/"))) + return false; +#endif #ifdef Q_OS_WIN if (path.startsWith(QLatin1Char('\\'))) return false; From ba2d6bb968b1a3589fc4e1afe3fd7a6cb23f3622 Mon Sep 17 00:00:00 2001 From: hjk Date: Sat, 23 Aug 2014 01:19:53 +0200 Subject: [PATCH 051/133] Use Qt 5's QStringList::join(QChar) Less typing and less cycles than join(QString) where appropriate Change-Id: I6ebc0e17e4d7fd9845864dd95b7de4ba4dad6906 Reviewed-by: Eike Ziller (cherry picked from qtcreator/6431ab2c799553623ec3fe6a79f1e85484558dd6) Reviewed-by: Joerg Bornemann --- qmake/library/qmakeglobals.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qmake/library/qmakeglobals.cpp b/qmake/library/qmakeglobals.cpp index 55ce404410..dd13b94d92 100644 --- a/qmake/library/qmakeglobals.cpp +++ b/qmake/library/qmakeglobals.cpp @@ -197,11 +197,11 @@ QMakeGlobals::ArgumentReturn QMakeGlobals::addCommandLineArguments( void QMakeGlobals::commitCommandLineArguments(QMakeCmdLineParserState &state) { if (!state.preconfigs.isEmpty()) - state.precmds << (fL1S("CONFIG += ") + state.preconfigs.join(fL1S(" "))); - precmds = state.precmds.join(fL1S("\n")); + state.precmds << (fL1S("CONFIG += ") + state.preconfigs.join(QLatin1Char(' '))); + precmds = state.precmds.join(QLatin1Char('\n')); if (!state.postconfigs.isEmpty()) - state.postcmds << (fL1S("CONFIG += ") + state.postconfigs.join(fL1S(" "))); - postcmds = state.postcmds.join(fL1S("\n")); + state.postcmds << (fL1S("CONFIG += ") + state.postconfigs.join(QLatin1Char(' '))); + postcmds = state.postcmds.join(QLatin1Char('\n')); if (xqmakespec.isEmpty()) xqmakespec = qmakespec; From b7205053ed696566072cf0e332de39b3c8ce22a8 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 29 Aug 2014 13:18:41 +0200 Subject: [PATCH 052/133] Remove Qt version checks. Qt 5.3 is the minimum requirement these days. Remove all fallback code from sources and project files. Change-Id: If6188a471197acadda4d6baee71804ba1a8026c6 Reviewed-by: Eike Ziller (cherry picked from qtcreator/847f10e9ccc8c3541782a790e04c85c6b4c701da) Reviewed-by: Joerg Bornemann --- qmake/library/proitems.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/qmake/library/proitems.cpp b/qmake/library/proitems.cpp index a610da6b69..5fb70df3b1 100644 --- a/qmake/library/proitems.cpp +++ b/qmake/library/proitems.cpp @@ -212,11 +212,7 @@ ProString &ProString::prepend(const ProString &other) ProString &ProString::append(const QLatin1String other) { const char *latin1 = other.latin1(); -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) int size = other.size(); -#else - int size = strlen(latin1); -#endif if (size) { QChar *ptr = prepareExtend(size, 0, m_length); for (int i = 0; i < size; i++) From 99a4a62977347654bee77513661df538c9ee4ab3 Mon Sep 17 00:00:00 2001 From: Daniel Teske Date: Tue, 9 Sep 2014 15:16:27 +0200 Subject: [PATCH 053/133] QMakeGlobals::expandEnvVars: Make sane Use indexOf() to match individual characters, which is a lot faster than QRegExp. As a side effect, don't try to expand what we just inserted. Change-Id: I964fbd92055f2f2649e7d8ed5739cf1fc7cae927 Reviewed-by: Oswald Buddenhagen Reviewed-by: Daniel Teske (cherry picked from qtcreator/2cc17a61eb6d0fee80fd388fcc5be03a59e4f2b5) Reviewed-by: Joerg Bornemann --- qmake/library/qmakeglobals.cpp | 42 +++++++++++++++------------------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/qmake/library/qmakeglobals.cpp b/qmake/library/qmakeglobals.cpp index dd13b94d92..8bb5199519 100644 --- a/qmake/library/qmakeglobals.cpp +++ b/qmake/library/qmakeglobals.cpp @@ -74,27 +74,8 @@ QT_BEGIN_NAMESPACE #define fL1S(s) QString::fromLatin1(s) -namespace { // MSVC doesn't seem to know the semantics of "static" ... - -static struct { - QRegExp reg_variableName; -} statics; - -} - -static void initStatics() -{ - if (!statics.reg_variableName.isEmpty()) - return; - - statics.reg_variableName.setPattern(QLatin1String("\\$\\(.*\\)")); - statics.reg_variableName.setMinimal(true); -} - QMakeGlobals::QMakeGlobals() { - initStatics(); - do_cache = true; #ifdef PROEVALUATOR_DEBUG @@ -292,11 +273,24 @@ QStringList QMakeGlobals::getPathListEnv(const QString &var) const QString QMakeGlobals::expandEnvVars(const QString &str) const { QString string = str; - int rep; - QRegExp reg_variableName = statics.reg_variableName; // Copy for thread safety - while ((rep = reg_variableName.indexIn(string)) != -1) - string.replace(rep, reg_variableName.matchedLength(), - getEnv(string.mid(rep + 2, reg_variableName.matchedLength() - 3))); + int startIndex = 0; + forever { + startIndex = string.indexOf(QLatin1Char('$'), startIndex); + if (startIndex < 0) + break; + if (string.length() < startIndex + 3) + break; + if (string.at(startIndex + 1) != QLatin1Char('(')) { + startIndex++; + continue; + } + int endIndex = string.indexOf(QLatin1Char(')'), startIndex + 2); + if (endIndex < 0) + break; + QString value = getEnv(string.mid(startIndex + 2, endIndex - startIndex - 2)); + string.replace(startIndex, endIndex - startIndex + 1, value); + startIndex += value.length(); + } return string; } From 33486e0ae7d40045029f9e24bebdf7a6829f756c Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 24 Oct 2014 10:28:28 +0200 Subject: [PATCH 054/133] Use QFileInfo::exist(f) instead of QFileInfo(f).exists() if possible Faster. Change-Id: I91aa67462e11ff3258600d7f158de79942d0dc81 Reviewed-by: Marc Reilly Reviewed-by: Christian Stenger (cherry picked from qtcreator/a439483d704113286370e7e93e0e6bc16199d8ab) Reviewed-by: Joerg Bornemann --- qmake/library/qmakeevaluator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp index efda9df7d4..e220d59517 100644 --- a/qmake/library/qmakeevaluator.cpp +++ b/qmake/library/qmakeevaluator.cpp @@ -1921,7 +1921,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFeatureFile( } #ifdef QMAKE_BUILTIN_PRFS fn.prepend(QLatin1String(":/qmake/features/")); - if (QFileInfo(fn).exists()) + if (QFileInfo::exists(fn)) goto cool; #endif fn = QLatin1String(""); // Indicate failed lookup. See comment above. From 08be8691f7ba5e522cbc000b1880941128ad5f8c Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Fri, 23 Oct 2015 21:21:38 +0300 Subject: [PATCH 055/133] Fix QStorageInfo on BSD4 systems MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - On NetBSD, the defines were not properly defined; - On all other BSD systems, we use statfs which does not have f_frsize member, revert to using f_bsize there. Task-number: QTBUG-48267 Change-Id: Ia1ed484ac61a615fcbb5b45affb516b5e86a64b0 Reviewed-by: Oswald Buddenhagen Reviewed-by: Lisandro Damián Nicanor Pérez Meyer Reviewed-by: Thiago Macieira --- src/corelib/io/qstorageinfo_unix.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp index bf1e6ce245..6ae3338cbd 100644 --- a/src/corelib/io/qstorageinfo_unix.cpp +++ b/src/corelib/io/qstorageinfo_unix.cpp @@ -68,8 +68,8 @@ #if defined(Q_OS_BSD4) # if defined(Q_OS_NETBSD) - define QT_STATFSBUF struct statvfs - define QT_STATFS ::statvfs +# define QT_STATFSBUF struct statvfs +# define QT_STATFS ::statvfs # else # define QT_STATFSBUF struct statfs # define QT_STATFS ::statfs @@ -506,9 +506,15 @@ void QStorageInfoPrivate::retrieveVolumeInfo() valid = true; ready = true; +#if defined(Q_OS_BSD4) && !defined(Q_OS_NETBSD) + bytesTotal = statfs_buf.f_blocks * statfs_buf.f_bsize; + bytesFree = statfs_buf.f_bfree * statfs_buf.f_bsize; + bytesAvailable = statfs_buf.f_bavail * statfs_buf.f_bsize; +#else bytesTotal = statfs_buf.f_blocks * statfs_buf.f_frsize; bytesFree = statfs_buf.f_bfree * statfs_buf.f_frsize; bytesAvailable = statfs_buf.f_bavail * statfs_buf.f_frsize; +#endif #if defined(Q_OS_ANDROID) || defined (Q_OS_BSD4) #if defined(_STATFS_F_FLAGS) readOnly = (statfs_buf.f_flags & ST_RDONLY) != 0; From 95b1982e4779160a42000661986a31aab6bafbb5 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 23 Oct 2015 09:20:21 +0200 Subject: [PATCH 056/133] Return early if there is no text at the offset Change-Id: I9d0b1e6e054a48bac34fb4e51b656c475f5638b4 Reviewed-by: Frederik Gladhorn --- src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index 84d60df3ef..6769f4ab0c 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -54,6 +54,14 @@ static void convertLineOffset(QAccessibleTextInterface *text, int &line, int &of do { curStart = curEnd; text->textAtOffset(curStart, QAccessible::LineBoundary, &curStart, &curEnd); + // If the text is empty then we just return + if (curStart == -1 || curEnd == -1) { + if (start) + *start = 0; + if (end) + *end = 0; + return; + } ++curLine; { // check for a case where a single word longer than the text edit's width and gets wrapped From a91c40868bbdc1b2d2dd3b5f8b47aae9e8589a81 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 22 Oct 2015 10:29:18 +0200 Subject: [PATCH 057/133] Check if the session is valid before connecting to it Since there are circumstances where the session is not yet created after start() is called then we should check if the session is valid before connecting to it. Change-Id: I94236f76e4be2433a8c96eb91ce2d4b4d42f2fd9 Reviewed-by: Richard J. Moore --- src/network/access/qnetworkreplyhttpimpl.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index c1956ae99f..76c2f57380 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -1679,8 +1679,9 @@ void QNetworkReplyHttpImplPrivate::_q_startOperation() #endif } else { #ifndef QT_NO_BEARERMANAGEMENT - QObject::connect(session.data(), SIGNAL(stateChanged(QNetworkSession::State)), - q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)), Qt::QueuedConnection); + if (session) + QObject::connect(session.data(), SIGNAL(stateChanged(QNetworkSession::State)), + q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)), Qt::QueuedConnection); #endif } From 1e32ade79ced64597ef4148f16e0d8a329733c4e Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Fri, 11 Sep 2015 12:15:03 +0300 Subject: [PATCH 058/133] QIODevice: fix interleaving read() and write() in text mode under Windows Skip the correct number of bytes in the read buffer when expanding '\n' into "\r\n" upon writing. Change-Id: I5b01fc47c330dee5c83001abf0acd7d63d790b96 Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qiodevice.cpp | 7 ++-- .../corelib/io/qiodevice/tst_qiodevice.cpp | 41 +++++++++++++++++++ 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index c80c78bd3b..3b1cd196d2 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -1289,6 +1289,7 @@ qint64 QIODevice::write(const char *data, qint64 maxSize) const char *startOfBlock = data; qint64 writtenSoFar = 0; + const qint64 savedPos = d->pos; forever { const char *endOfBlock = startOfBlock; @@ -1300,7 +1301,7 @@ qint64 QIODevice::write(const char *data, qint64 maxSize) qint64 ret = writeData(startOfBlock, blockSize); if (ret <= 0) { if (writtenSoFar && !sequential) - d->buffer.skip(writtenSoFar); + d->buffer.skip(d->pos - savedPos); return writtenSoFar ? writtenSoFar : ret; } if (!sequential) { @@ -1316,7 +1317,7 @@ qint64 QIODevice::write(const char *data, qint64 maxSize) qint64 ret = writeData("\r\n", 2); if (ret <= 0) { if (writtenSoFar && !sequential) - d->buffer.skip(writtenSoFar); + d->buffer.skip(d->pos - savedPos); return writtenSoFar ? writtenSoFar : ret; } if (!sequential) { @@ -1329,7 +1330,7 @@ qint64 QIODevice::write(const char *data, qint64 maxSize) } if (writtenSoFar && !sequential) - d->buffer.skip(writtenSoFar); + d->buffer.skip(d->pos - savedPos); return writtenSoFar; } #endif diff --git a/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp b/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp index 565ca18899..334f5aba05 100644 --- a/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp +++ b/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp @@ -59,6 +59,7 @@ private slots: void peekBug(); void readAllKeepPosition(); + void writeInTextMode(); }; void tst_QIODevice::initTestCase() @@ -628,5 +629,45 @@ void tst_QIODevice::readAllKeepPosition() QCOMPARE(resultArray, buffer.buffer()); } +class RandomAccessBuffer : public QIODevice +{ +public: + RandomAccessBuffer(const char *data) : QIODevice(), buf(data) { } + +protected: + qint64 readData(char *data, qint64 maxSize) Q_DECL_OVERRIDE + { + maxSize = qMin(maxSize, qint64(buf.size() - pos())); + memcpy(data, buf.constData() + pos(), maxSize); + return maxSize; + } + qint64 writeData(const char *data, qint64 maxSize) Q_DECL_OVERRIDE + { + maxSize = qMin(maxSize, qint64(buf.size() - pos())); + memcpy(buf.data() + pos(), data, maxSize); + return maxSize; + } + +private: + QByteArray buf; +}; + +// Test write() on skipping correct number of bytes in read buffer +void tst_QIODevice::writeInTextMode() +{ + // Unlike other platforms, Windows implementation expands '\n' into + // "\r\n" sequence in write(). Ensure that write() properly works with + // a read buffer on random-access devices. +#ifndef Q_OS_WIN + QSKIP("This is a Windows-only test"); +#else + RandomAccessBuffer buffer("one\r\ntwo\r\nthree\r\n"); + buffer.open(QBuffer::ReadWrite | QBuffer::Text); + QCOMPARE(buffer.readLine(), QByteArray("one\n")); + QCOMPARE(buffer.write("two\n"), 4); + QCOMPARE(buffer.readLine(), QByteArray("three\n")); +#endif +} + QTEST_MAIN(tst_QIODevice) #include "tst_qiodevice.moc" From 474bee61e4a1c6797ff876bd0ae25ba87d33a4ec Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 23 Oct 2015 16:32:59 +0200 Subject: [PATCH 059/133] QtNetwork: convert some QDateTime::currentDateTime() to currentDateTimeUtc() The latter is much faster as it doesn't have to deal with time zones. This change is safe, because the QDateTimes are only used for comparison with other QDateTimes, which, from a quick glance around, seem to be mostly, if not exclusively, in UTC. Comparsions work across time zones, but the comparison between UTC date-times is fastest. Credits to Milian Wolff, from whose QtWS15 talk this advice is taken. Change-Id: I6859d886d8dc8e0a52fbe394fbb7b93a87b4739a Reviewed-by: Milian Wolff Reviewed-by: Friedemann Kleint Reviewed-by: Lars Knoll --- src/network/access/qnetworkcookiejar.cpp | 4 ++-- src/network/ssl/qsslcertificate.h | 2 +- src/network/ssl/qsslcontext_openssl.cpp | 4 +++- src/network/ssl/qsslsocket_openssl.cpp | 3 ++- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/network/access/qnetworkcookiejar.cpp b/src/network/access/qnetworkcookiejar.cpp index 3cefb28f68..39f94a451f 100644 --- a/src/network/access/qnetworkcookiejar.cpp +++ b/src/network/access/qnetworkcookiejar.cpp @@ -216,7 +216,7 @@ QList QNetworkCookieJar::cookiesForUrl(const QUrl &url) const // It does not implement a very good cross-domain verification yet. Q_D(const QNetworkCookieJar); - QDateTime now = QDateTime::currentDateTime(); + const QDateTime now = QDateTime::currentDateTimeUtc(); QList result; bool isEncrypted = url.scheme().toLower() == QLatin1String("https"); @@ -265,7 +265,7 @@ QList QNetworkCookieJar::cookiesForUrl(const QUrl &url) const bool QNetworkCookieJar::insertCookie(const QNetworkCookie &cookie) { Q_D(QNetworkCookieJar); - QDateTime now = QDateTime::currentDateTime(); + const QDateTime now = QDateTime::currentDateTimeUtc(); bool isDeletion = !cookie.isSessionCookie() && cookie.expirationDate() < now; diff --git a/src/network/ssl/qsslcertificate.h b/src/network/ssl/qsslcertificate.h index af605b0629..d58cfcf5d1 100644 --- a/src/network/ssl/qsslcertificate.h +++ b/src/network/ssl/qsslcertificate.h @@ -97,7 +97,7 @@ public: bool isNull() const; #if QT_DEPRECATED_SINCE(5,0) QT_DEPRECATED inline bool isValid() const { - const QDateTime currentTime = QDateTime::currentDateTime(); + const QDateTime currentTime = QDateTime::currentDateTimeUtc(); return currentTime >= effectiveDate() && currentTime <= expiryDate() && !isBlacklisted(); diff --git a/src/network/ssl/qsslcontext_openssl.cpp b/src/network/ssl/qsslcontext_openssl.cpp index b88ab54038..68caaeb6dc 100644 --- a/src/network/ssl/qsslcontext_openssl.cpp +++ b/src/network/ssl/qsslcontext_openssl.cpp @@ -215,6 +215,8 @@ init_context: return sslContext; } + const QDateTime now = QDateTime::currentDateTimeUtc(); + // Add all our CAs to this store. foreach (const QSslCertificate &caCertificate, sslContext->sslConfiguration.caCertificates()) { // From https://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html: @@ -228,7 +230,7 @@ init_context: // certificates mixed with valid ones. // // See also: QSslSocketBackendPrivate::verify() - if (caCertificate.expiryDate() >= QDateTime::currentDateTime()) { + if (caCertificate.expiryDate() >= now) { q_X509_STORE_add_cert(q_SSL_CTX_get_cert_store(sslContext->ctx), (X509 *)caCertificate.handle()); } } diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index a8e4c61e9a..dd47dfc45f 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -1660,6 +1660,7 @@ QList QSslSocketBackendPrivate::verify(const QList & setDefaultCaCertificates(defaultCaCertificates() + systemCaCertificates()); } + const QDateTime now = QDateTime::currentDateTimeUtc(); foreach (const QSslCertificate &caCertificate, QSslConfiguration::defaultConfiguration().caCertificates()) { // From https://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html: // @@ -1672,7 +1673,7 @@ QList QSslSocketBackendPrivate::verify(const QList & // certificates mixed with valid ones. // // See also: QSslContext::fromConfiguration() - if (caCertificate.expiryDate() >= QDateTime::currentDateTime()) { + if (caCertificate.expiryDate() >= now) { q_X509_STORE_add_cert(certStore, reinterpret_cast(caCertificate.handle())); } } From c66b492cedbd96831e02269aa65d38b8a4b55df0 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 27 Oct 2015 15:13:34 +0100 Subject: [PATCH 060/133] fix vcxproj linker options Commit 4bb004de94380304d8950e860d1823975927ec59 broke the linker options in generated Visual Studio projects. We need to call fixLibFlags on QMAKE_LIBS and QMAKE_LIBS_PRIVATE. Task-number: QTBUG-48936 Change-Id: I2f12bf0117d27104cd34f2f43fdeb7b948fa375e Reviewed-by: Oswald Buddenhagen --- qmake/generators/win32/msvc_vcproj.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index b1e0745e03..47f99a5c8e 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -1207,12 +1207,13 @@ void VcprojGenerator::initLinkerTool() if (!project->values("DEF_FILE").isEmpty()) conf.linker.ModuleDefinitionFile = project->first("DEF_FILE").toQString(); - foreach (const ProString &libs, project->values("QMAKE_LIBS") + project->values("QMAKE_LIBS_PRIVATE")) { - if (libs.left(9).toQString().toUpper() == "/LIBPATH:") { - ProStringList l = ProStringList(libs); - conf.linker.parseOptions(l); - } else { - conf.linker.AdditionalDependencies << escapeFilePath(libs.toQString()); + static const char * const lflags[] = { "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", 0 }; + for (int i = 0; lflags[i]; i++) { + foreach (const ProString &lib, fixLibFlags(lflags[i])) { + if (lib.startsWith("/LIBPATH:")) + conf.linker.AdditionalLibraryDirectories << lib.mid(9).toQString(); + else + conf.linker.AdditionalDependencies << lib.toQString(); } } From 7daae2c2c706fd5d1c1ae44ace6847bc297803a0 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 19 Oct 2015 14:25:37 +0200 Subject: [PATCH 061/133] Windows: Delay-initialize pluggable touch devices. Move touch device initialization code to QWindowsContext and replace the assert on the touch device in QWindowsMouseHandler by a call to the initTouch(). Task-number: QTBUG-48849 Change-Id: If8573b8283ef94e7fd015f6edc626e3c8cc0b139 Reviewed-by: Joni Poikelin Reviewed-by: Oliver Wolff Reviewed-by: Andreas Holzammer Reviewed-by: Friedemann Kleint --- .../platforms/windows/qwindowscontext.cpp | 45 ++++++++++++++++--- .../platforms/windows/qwindowscontext.h | 3 ++ .../platforms/windows/qwindowsintegration.cpp | 12 +---- .../windows/qwindowsmousehandler.cpp | 17 +++++-- .../platforms/windows/qwindowsmousehandler.h | 1 + 5 files changed, 57 insertions(+), 21 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 3f355db607..00049bd0d6 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -33,6 +33,7 @@ ****************************************************************************/ #include "qwindowscontext.h" +#include "qwindowsintegration.h" #include "qwindowswindow.h" #include "qwindowskeymapper.h" #include "qwindowsguieventdispatcher.h" @@ -201,12 +202,14 @@ void QWindowsUser32DLL::init() bool QWindowsUser32DLL::initTouch() { - QSystemLibrary library(QStringLiteral("user32")); - isTouchWindow = (IsTouchWindow)(library.resolve("IsTouchWindow")); - registerTouchWindow = (RegisterTouchWindow)(library.resolve("RegisterTouchWindow")); - unregisterTouchWindow = (UnregisterTouchWindow)(library.resolve("UnregisterTouchWindow")); - getTouchInputInfo = (GetTouchInputInfo)(library.resolve("GetTouchInputInfo")); - closeTouchInputHandle = (CloseTouchInputHandle)(library.resolve("CloseTouchInputHandle")); + if (!isTouchWindow && QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7) { + QSystemLibrary library(QStringLiteral("user32")); + isTouchWindow = (IsTouchWindow)(library.resolve("IsTouchWindow")); + registerTouchWindow = (RegisterTouchWindow)(library.resolve("RegisterTouchWindow")); + unregisterTouchWindow = (UnregisterTouchWindow)(library.resolve("UnregisterTouchWindow")); + getTouchInputInfo = (GetTouchInputInfo)(library.resolve("GetTouchInputInfo")); + closeTouchInputHandle = (CloseTouchInputHandle)(library.resolve("CloseTouchInputHandle")); + } return isTouchWindow && registerTouchWindow && unregisterTouchWindow && getTouchInputInfo && closeTouchInputHandle; } @@ -359,6 +362,36 @@ QWindowsContext::~QWindowsContext() m_instance = 0; } +bool QWindowsContext::initTouch() +{ + return initTouch(QWindowsIntegration::instance()->options()); +} + +bool QWindowsContext::initTouch(unsigned integrationOptions) +{ + if (d->m_systemInfo & QWindowsContext::SI_SupportsTouch) + return true; + + QTouchDevice *touchDevice = d->m_mouseHandler.ensureTouchDevice(); + if (!touchDevice) + return false; + +#ifndef Q_OS_WINCE + if (!QWindowsContext::user32dll.initTouch()) { + delete touchDevice; + return false; + } +#endif // !Q_OS_WINCE + + if (!(integrationOptions & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch)) + touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation); + + QWindowSystemInterface::registerTouchDevice(touchDevice); + + d->m_systemInfo |= QWindowsContext::SI_SupportsTouch; + return true; +} + void QWindowsContext::setTabletAbsoluteRange(int a) { #if !defined(QT_NO_TABLETEVENT) && !defined(Q_OS_WINCE) diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h index d2a3481b28..641e3ed41f 100644 --- a/src/plugins/platforms/windows/qwindowscontext.h +++ b/src/plugins/platforms/windows/qwindowscontext.h @@ -170,6 +170,9 @@ public: explicit QWindowsContext(); ~QWindowsContext(); + bool initTouch(); + bool initTouch(unsigned integrationOptions); // For calls from QWindowsIntegration::QWindowsIntegration() only. + int defaultDPI() const; QString registerWindowClass(const QWindow *w); diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 79df6ce720..089c3cd0fe 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -230,17 +230,7 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList ¶mL << __FUNCTION__ << "DpiAwareness=" << dpiAwareness <<",Scaling=" << QWindowsScaling::factor(); - QTouchDevice *touchDevice = m_context.touchDevice(); - if (touchDevice) { -#ifdef Q_OS_WINCE - touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation); -#else - if (!(m_options & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch)) { - touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation); - } -#endif - QWindowSystemInterface::registerTouchDevice(touchDevice); - } + m_context.initTouch(m_options); } QWindowsIntegrationPrivate::~QWindowsIntegrationPrivate() diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp index e6b80f2b93..e83354157b 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp +++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp @@ -150,12 +150,19 @@ static inline QTouchDevice *createTouchDevice() QWindowsMouseHandler::QWindowsMouseHandler() : m_windowUnderMouse(0), m_trackedWindow(0), - m_touchDevice(createTouchDevice()), + m_touchDevice(Q_NULLPTR), m_leftButtonDown(false), m_previousCaptureWindow(0) { } +QTouchDevice *QWindowsMouseHandler::ensureTouchDevice() +{ + if (!m_touchDevice) + m_touchDevice = createTouchDevice(); + return m_touchDevice; +} + Qt::MouseButtons QWindowsMouseHandler::queryMouseButtons() { Qt::MouseButtons result = 0; @@ -480,7 +487,11 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND, typedef QWindowSystemInterface::TouchPoint QTouchPoint; typedef QList QTouchPointList; - Q_ASSERT(m_touchDevice); + if (!QWindowsContext::instance()->initTouch()) { + qWarning("Unable to initialize touch handling."); + return true; + } + const QRect screenGeometry = window->screen()->geometry(); const int winTouchPointCount = msg.wParam; @@ -491,8 +502,6 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND, touchPoints.reserve(winTouchPointCount); Qt::TouchPointStates allStates = 0; - Q_ASSERT(QWindowsContext::user32dll.getTouchInputInfo); - QWindowsContext::user32dll.getTouchInputInfo((HANDLE) msg.lParam, msg.wParam, winTouchInputs.data(), sizeof(TOUCHINPUT)); const qreal screenPosFactor = 0.01 / qreal(QWindowsScaling::factor()); for (int i = 0; i < winTouchPointCount; ++i) { diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.h b/src/plugins/platforms/windows/qwindowsmousehandler.h index 61aa8d6084..4b5078567d 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.h +++ b/src/plugins/platforms/windows/qwindowsmousehandler.h @@ -52,6 +52,7 @@ public: QWindowsMouseHandler(); QTouchDevice *touchDevice() const { return m_touchDevice; } + QTouchDevice *ensureTouchDevice(); bool translateMouseEvent(QWindow *widget, HWND hwnd, QtWindows::WindowsEventType t, MSG msg, From 616f690761a5329b201a903dc2607818c38e41f5 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Tue, 27 Oct 2015 12:12:43 +0100 Subject: [PATCH 062/133] Doc: Use a navigation separator in the simple offline template As we cannot style the navigation elements freely with the restricted version of CSS that QTextBrowser supports, we need to inject separator elements between the prev/next page links. This change adds a 'bullet' character wrapped in a as a separator. A rule is added to the standard offline CSS to hide the separator as it's not needed there. Change-Id: I13220a2a60e2d3063f94bc7dff0e4320d0bed4f6 Reviewed-by: Martin Smith --- doc/global/qt-html-templates-offline-simple.qdocconf | 3 +++ doc/global/template/style/offline-simple.css | 8 ++++---- doc/global/template/style/offline.css | 1 + 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/doc/global/qt-html-templates-offline-simple.qdocconf b/doc/global/qt-html-templates-offline-simple.qdocconf index cd924c64e3..4a65cc3c57 100644 --- a/doc/global/qt-html-templates-offline-simple.qdocconf +++ b/doc/global/qt-html-templates-offline-simple.qdocconf @@ -25,6 +25,9 @@ HTML.postpostheader = \ "
\n" \ "
\n" +HTML.navigationseparator = \ + "\n" + # Add some padding around code snippets, as we cannot # currectly style them for QTextBrowser using only CSS. codeindent = 2 diff --git a/doc/global/template/style/offline-simple.css b/doc/global/template/style/offline-simple.css index 3e1c527761..b11cb6a137 100644 --- a/doc/global/template/style/offline-simple.css +++ b/doc/global/template/style/offline-simple.css @@ -136,12 +136,12 @@ code { p.naviNextPrevious { text-align: right; - margin-right: 40px; + margin-right: 20px; } -q.prevPage, a.nextPage { - margin-left: 30px; - } +span.naviSeparator { + white-space: pre; +} .toc h3 { margin: 0px 0px 10px 6px; diff --git a/doc/global/template/style/offline.css b/doc/global/template/style/offline.css index 1936b16bda..123d753290 100644 --- a/doc/global/template/style/offline.css +++ b/doc/global/template/style/offline.css @@ -192,6 +192,7 @@ Top navigation margin-left: 30px; } +.naviSeparator { display: none } /* ----------- footer and license From 07a6f15a94684cba9cff0fa1fb2921faee3c5780 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Wed, 28 Oct 2015 10:58:08 +0100 Subject: [PATCH 063/133] Doc: corrected minor language mistake MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-42977 Change-Id: Icdd70a41c9ef72224992d59342f4f97c65de78fc Reviewed-by: Topi Reiniö --- src/corelib/kernel/qsharedmemory.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qsharedmemory.cpp b/src/corelib/kernel/qsharedmemory.cpp index cef0ef0f7d..267cf95814 100644 --- a/src/corelib/kernel/qsharedmemory.cpp +++ b/src/corelib/kernel/qsharedmemory.cpp @@ -127,8 +127,8 @@ QSharedMemoryPrivate::makePlatformSafeKey(const QString &key, specified. Interoperation with non-Qt applications is achieved by first creating a default shared memory with QSharedMemory() and then setting a native key with setNativeKey(). When using native keys, shared memory is not protected against - multiple accesses on it (e.g. unable to lock()) and a user-defined mechanism - should be used to achieve a such protection. + multiple accesses on it (for example, unable to lock()) and a user-defined mechanism + should be used to achieve such protection. */ /*! From 9b30c159426333b73565dd97dd705b1b11b8c1fc Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 27 Oct 2015 14:55:51 -0700 Subject: [PATCH 064/133] QLocale: Add Q_ENUM for QLocale::Script Change-Id: I7e6338336dd6468ead24ffff141129d557330f00 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/tools/qlocale.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h index 0cbfa6710c..729fd73a5d 100644 --- a/src/corelib/tools/qlocale.h +++ b/src/corelib/tools/qlocale.h @@ -831,6 +831,7 @@ public: Q_ENUM(Language) Q_ENUM(Country) + Q_ENUM(Script) enum MeasurementSystem { MetricSystem, From a90869861cbc9927af2bbab5a94630e47b33fd5c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 27 Oct 2015 15:45:40 -0700 Subject: [PATCH 065/133] QLocale: Actually get the language script for the system locale The Windows code was always returning AnyScript, which in turn made QLocale::textDirection() for the default and system locales always return LTR, even if the Windows UI was in RTL mode. [ChangeLog][QtCore][QLocale] Fixed a bug that caused QLocale::textDirection() to always return Qt::LeftToRight and QLocale::script() to return QLocale::AnyScript on for the Windows system locale. Task-number: QTBUG-49031 Change-Id: I7e6338336dd6468ead24ffff14112c8d348eedba Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/tools/qlocale_win.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qlocale_win.cpp b/src/corelib/tools/qlocale_win.cpp index 4781bab172..574453f4ca 100644 --- a/src/corelib/tools/qlocale_win.cpp +++ b/src/corelib/tools/qlocale_win.cpp @@ -807,6 +807,7 @@ QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const case ZeroDigit: return d->zeroDigit(); case LanguageId: + case ScriptId: case CountryId: { QString locale = QString::fromLatin1(getWinLocaleName()); QLocale::Language lang; @@ -815,12 +816,12 @@ QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const QLocalePrivate::getLangAndCountry(locale, lang, script, cntry); if (type == LanguageId) return lang; + if (type == ScriptId) + return script == QLocale::AnyScript ? fallbackUiLocale().script() : script; if (cntry == QLocale::AnyCountry) return fallbackUiLocale().country(); return cntry; } - case ScriptId: - return QVariant(QLocale::AnyScript); case MeasurementSystem: return d->measurementSystem(); case AMText: From 26238aca8c442736f380eb523ef48468f892bdb7 Mon Sep 17 00:00:00 2001 From: Romain Pokrzywka Date: Mon, 19 Oct 2015 14:49:27 -0700 Subject: [PATCH 066/133] Fix crash on process exit when the evdevtouch plugin is loaded The QGuiApplicationPrivate object is already destroyed by the time the plugins are cleaned up during the application destruction, causing a segmentation fault in updateInputDeviceCount(). There's no point in calling updateInputDeviceCount() in the destructor anyway as the whole process is on its way out that stage, and we don't support unloading plugins during the application lifetime otherwise, so the call can just be removed from the destructor. Change-Id: Id819d73cb8234ccedb6ea7c3e39950589ee680a1 Reviewed-by: Friedemann Kleint Reviewed-by: Laszlo Agocs --- src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp b/src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp index 35a685ff21..57028495c5 100644 --- a/src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp +++ b/src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp @@ -91,7 +91,6 @@ QEvdevTouchManager::QEvdevTouchManager(const QString &key, const QString &specif QEvdevTouchManager::~QEvdevTouchManager() { qDeleteAll(m_activeDevices); - updateInputDeviceCount(); } void QEvdevTouchManager::addDevice(const QString &deviceNode) From b20d6cded7be8b86bed93ee705420bfb01700c5b Mon Sep 17 00:00:00 2001 From: Joni Poikelin Date: Thu, 29 Oct 2015 09:43:33 +0200 Subject: [PATCH 067/133] Fix QDomNamedNodeMap::item crash with negative index Task-number: QTBUG-49113 Change-Id: I62dee4c112b73a25628657bc3d2ae675f26b87d8 Reviewed-by: David Faure --- src/xml/dom/qdom.cpp | 2 +- tests/auto/xml/dom/qdom/tst_qdom.cpp | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp index 943d5c28a4..5e4946a814 100644 --- a/src/xml/dom/qdom.cpp +++ b/src/xml/dom/qdom.cpp @@ -3142,7 +3142,7 @@ QDomNodePrivate* QDomNamedNodeMapPrivate::removeNamedItem(const QString& name) QDomNodePrivate* QDomNamedNodeMapPrivate::item(int index) const { - if (index >= length()) + if (index >= length() || index < 0) return 0; return *(map.constBegin() + index); } diff --git a/tests/auto/xml/dom/qdom/tst_qdom.cpp b/tests/auto/xml/dom/qdom/tst_qdom.cpp index a4a3f1f6b3..04cd0b300f 100644 --- a/tests/auto/xml/dom/qdom/tst_qdom.cpp +++ b/tests/auto/xml/dom/qdom/tst_qdom.cpp @@ -119,6 +119,7 @@ private slots: void cloneDTD_QTBUG8398() const; void DTDNotationDecl(); void DTDEntityDecl(); + void QTBUG49113_dontCrashWithNegativeIndex() const; void cleanupTestCase() const; @@ -1979,5 +1980,13 @@ void tst_QDom::DTDEntityDecl() QCOMPARE(doctype.namedItem(QString("logo")).toEntity().notationName(), QString("gif")); } +void tst_QDom::QTBUG49113_dontCrashWithNegativeIndex() const +{ + QDomDocument doc; + QDomElement elem = doc.appendChild(doc.createElement("root")).toElement(); + QDomNode node = elem.attributes().item(-1); + QVERIFY(node.isNull()); +} + QTEST_MAIN(tst_QDom) #include "tst_qdom.moc" From d020e0781cf8647d87f7088350e40adf4f0cf8fe Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 22 Oct 2015 11:31:58 -0700 Subject: [PATCH 068/133] Workaround: don't create ELF version scripts for Android Somehow qmake doesn't add the correct rules for the Android makefiles, so the build fails when cross-compiling from Windows. The reason for that is unknown (could be related to that "qt_android_deps" config, but that isn't used anywhere in qmake or the buildsystem). This isn't likely to be a problem, since there are no global installs of Qt on Android. Change-Id: I1d0f78915b5942aab07cffff140f95ce32324030 Reviewed-by: Thiago Macieira --- mkspecs/features/qt_module.prf | 4 ++-- src/corelib/global/qversiontagging.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf index 10911fa6df..193629b532 100644 --- a/mkspecs/features/qt_module.prf +++ b/mkspecs/features/qt_module.prf @@ -187,6 +187,8 @@ equals(QT_ARCH, i386):contains(QT_CPU_FEATURES.$$QT_ARCH, sse2):compiler_support QMAKE_CXXFLAGS += -mfpmath=sse } +android: CONFIG += qt_android_deps no_linker_version_script + unix:!isEmpty(QMAKE_LFLAGS_VERSION_SCRIPT):!no_linker_version_script:!static { verscript = $$OUT_PWD/$${TARGET}.version QMAKE_LFLAGS += $${QMAKE_LFLAGS_VERSION_SCRIPT}$$verscript @@ -226,8 +228,6 @@ unix:!isEmpty(QMAKE_LFLAGS_VERSION_SCRIPT):!no_linker_version_script:!static { unset(verscript_content) } -android: CONFIG += qt_android_deps - #install directives load(qt_installs) diff --git a/src/corelib/global/qversiontagging.cpp b/src/corelib/global/qversiontagging.cpp index fc81d9bb93..e7524f39ef 100644 --- a/src/corelib/global/qversiontagging.cpp +++ b/src/corelib/global/qversiontagging.cpp @@ -36,7 +36,7 @@ #define SYM QT_MANGLE_NAMESPACE(qt_version_tag) //#define SSYM QT_STRINGIFY(SYM) -#if defined(Q_CC_GNU) && defined(Q_OF_ELF) +#if defined(Q_CC_GNU) && defined(Q_OF_ELF) && !defined(Q_OS_ANDROID) # define make_versioned_symbol2(sym, m, n, separator) \ Q_CORE_EXPORT extern const char sym ## _ ## m ## _ ## n = 0; \ asm(".symver " QT_STRINGIFY(sym) "_" QT_STRINGIFY(m) "_" QT_STRINGIFY(n) ", " \ From 0667ba3f24c2637adab41b6ea8e7c08f933a6cf3 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Thu, 29 Oct 2015 11:52:24 +0200 Subject: [PATCH 069/133] Disable tst_QSslCertificate::subjectAndIssuerAttributes completely MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As a follow-up for 5c1b9bbdf14a9537bd66aedbfd1c72bde0c899e0 disable the test on all platforms, since it fails on newer openssl. This was now also happening on Windows, so until a fix is there, skip the test. Change-Id: I6c8822c0ac5411b1114e9cd426219574ab1c9b54 Reviewed-by: Simon Hausmann Reviewed-by: Jędrzej Nowacki --- tests/auto/network/ssl/qsslcertificate/BLACKLIST | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/network/ssl/qsslcertificate/BLACKLIST b/tests/auto/network/ssl/qsslcertificate/BLACKLIST index 2e376fa2a9..25509a5ca8 100644 --- a/tests/auto/network/ssl/qsslcertificate/BLACKLIST +++ b/tests/auto/network/ssl/qsslcertificate/BLACKLIST @@ -1,3 +1,3 @@ # OpenSSL version is too new. Rich will fix :) [subjectAndIssuerAttributes] -osx +* From 132b032a2f2220a60037e1fbc5273bbeee7763eb Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 24 Oct 2015 02:44:36 +0200 Subject: [PATCH 070/133] src/gui/painting/painting.pri: add missing qdatabuffer_p.h Change-Id: I40ae6beb14058948030e63a2535ff72a6b8072c1 Reviewed-by: Gunnar Sletta --- src/gui/painting/painting.pri | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index 791b5f1a9a..2e2532a25f 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -9,6 +9,7 @@ HEADERS += \ painting/qcolor.h \ painting/qcolor_p.h \ painting/qcosmeticstroker_p.h \ + painting/qdatabuffer_p.h \ painting/qdrawhelper_p.h \ painting/qdrawhelper_x86_p.h \ painting/qdrawingprimitive_sse2_p.h \ From f7f4dde80e13ff1c05a9399297ffb746ab505e62 Mon Sep 17 00:00:00 2001 From: Rafael Roquetto Date: Wed, 28 Oct 2015 14:56:16 -0200 Subject: [PATCH 071/133] Fix C++11 compiler detection for QNX. 1. _HAS_DINKUM_CLIB is defined whenever a C header is included, even when Dinkum is disabled. 2. _HAS_* macros are always defined, as either 0 or 1. Change-Id: I727b854a6a733e2028e6facc327e264d0c4c9e90 Reviewed-by: Thiago Macieira --- src/corelib/global/qcompilerdetection.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index 8595c51368..2ff75d7561 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -922,24 +922,26 @@ # if defined(Q_OS_QNX) // QNX: test if we are using libcpp (Dinkumware-based). // Older versions (QNX 650) do not support C++11 features -// _HAS_CPP0X is defined by toolchains that actually include +// _HAS_* macros are set to 1 by toolchains that actually include // Dinkum C++11 libcpp. -# if defined(_HAS_DINKUM_CLIB) && !defined(_HAS_CPP0X) +# if !__GLIBCXX__ +# if !_HAS_CPP0X // Disable C++11 features that depend on library support # undef Q_COMPILER_INITIALIZER_LISTS # undef Q_COMPILER_RVALUE_REFS # undef Q_COMPILER_REF_QUALIFIERS # undef Q_COMPILER_UNICODE_STRINGS # undef Q_COMPILER_NOEXCEPT -# endif -# if defined(_HAS_DINKUM_CLIB) && !defined(_HAS_NULLPTR_T) +# endif // !_HAS_CPP0X +# if !_HAS_NULLPTR_T # undef Q_COMPILER_NULLPTR -# endif -# if defined(_HAS_DINKUM_CLIB) && !defined(_HAS_CONSTEXPR) +# endif //!_HAS_NULLPTR_T +# if !_HAS_CONSTEXPR // The libcpp is missing constexpr keywords on important functions like std::numeric_limits<>::min() // Disable constexpr support on QNX even if the compiler supports it # undef Q_COMPILER_CONSTEXPR -# endif +# endif // !_HAS_CONSTEXPR +# endif // !__GLIBCXX__ # endif // Q_OS_QNX # if (defined(Q_CC_CLANG) || defined(Q_CC_INTEL)) && defined(Q_OS_MAC) && defined(__GNUC_LIBSTD__) \ && ((__GNUC_LIBSTD__-0) * 100 + __GNUC_LIBSTD_MINOR__-0 <= 402) From ff3ba1045e8322caa0293b05aecbff4411963ea2 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 29 Oct 2015 16:49:04 +0100 Subject: [PATCH 072/133] State machine: fix removeConflictingTransitions() Since QSet<>::intersect() modifies the original set, exitSetT1 has wrong content for next iterations. Use intersects() instead. Change-Id: I09e0961ec6dfb34ade88d48d1e009529aeab82b4 Reviewed-by: Simon Hausmann --- src/corelib/statemachine/qstatemachine.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index 31b079af0c..20d5ed890b 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -624,7 +624,7 @@ void QStateMachinePrivate::removeConflictingTransitions(QList exitSetT1 = computeExitSet_Unordered(t1, cache); + const QSet exitSetT1 = computeExitSet_Unordered(t1, cache); QList::iterator t2It = filteredTransitions.begin(); while (t2It != filteredTransitions.end()) { QAbstractTransition *t2 = *t2It; @@ -636,7 +636,7 @@ void QStateMachinePrivate::removeConflictingTransitions(QList exitSetT2 = computeExitSet_Unordered(t2, cache); - if (exitSetT1.intersect(exitSetT2).isEmpty()) { + if (!exitSetT1.intersects(exitSetT2)) { // No conflict, no cry. Next patient please. ++t2It; } else { From f86e6643b6eda10ccfdfb5e71fd4ac3d527aa9e0 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 29 Oct 2015 15:17:53 +0100 Subject: [PATCH 073/133] Compile-fix: add missing declaration in debug. QAbstractSocketPrivate::readFromSocket() had a qDebug() that references its q->... so it also needs its Q_Q() declaration. Only relevant when QABSTRACTSOCKET_DEBUG is enabled (which it normally isn't). Change-Id: Ib82fd032fb2c4143a0987b9162377d0d7e968e95 Reviewed-by: Thiago Macieira --- src/network/socket/qabstractsocket.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 8d9975dcdb..1831d25718 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -1248,6 +1248,10 @@ void QAbstractSocketPrivate::_q_forceDisconnect() */ bool QAbstractSocketPrivate::readFromSocket() { +#ifdef QABSTRACTSOCKET_DEBUG + Q_Q(QAbstractSocket); +#endif + // Find how many bytes we can read from the socket layer. qint64 bytesToRead = socketEngine->bytesAvailable(); if (bytesToRead == 0) { From 5a7f69f82434498124f060386d518a099d3aca16 Mon Sep 17 00:00:00 2001 From: Dyami Caliri Date: Wed, 28 Oct 2015 13:47:24 -0700 Subject: [PATCH 074/133] Fix Vista style compilation with QT_NO_ACCESSIBILITY A recent change uses an accessibility function even if accessibility is disabled. Change-Id: Ibf9afbb90120772065743b2f9dd3615e4e6a2f37 Reviewed-by: Gabriel de Dietrich --- src/widgets/styles/qwindowsvistastyle.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp index b8ed82fee3..375ada6a64 100644 --- a/src/widgets/styles/qwindowsvistastyle.cpp +++ b/src/widgets/styles/qwindowsvistastyle.cpp @@ -657,10 +657,12 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt newStyle = !qobject_cast(view); selectionBehavior = view->selectionBehavior(); selectionMode = view->selectionMode(); - } else if (!widget) { + } +#ifndef QT_NO_ACCESSIBILITY + else if (!widget) { newStyle = !QStyleHelper::hasAncestor(option->styleObject, QAccessible::MenuItem) ; } - +#endif if (newStyle && (vopt = qstyleoption_cast(option))) { bool selected = vopt->state & QStyle::State_Selected; const bool hover = selectionMode != QAbstractItemView::NoSelection && (vopt->state & QStyle::State_MouseOver); From 11638dad106cee87eec2f6cafbfd6c7879c5e689 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 30 Oct 2015 12:56:24 +0100 Subject: [PATCH 075/133] Add a test case for conflicting transitions This tests a fix: ff3ba1045e8322caa0293b05aecbff4411963ea2 Change-Id: I623b4e270c7eba1af0c4c023e83b6eea50fb45a1 Reviewed-by: Simon Hausmann --- .../qstatemachine/tst_qstatemachine.cpp | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp index 28df7cce7b..cfbb88a123 100644 --- a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp @@ -249,6 +249,7 @@ private slots: void qtbug_44783(); void internalTransition(); void conflictingTransition(); + void conflictingTransition2(); void qtbug_46059(); void qtbug_46703(); }; @@ -6448,6 +6449,71 @@ void tst_QStateMachine::conflictingTransition() QVERIFY(machine.isRunning()); } +void tst_QStateMachine::conflictingTransition2() +{ + SignalEmitter emitter; + + QStateMachine machine; + QState s0(&machine); + QState p0(QState::ParallelStates, &s0); + QState p0s1(&p0); + QState p0s2(&p0); + QState p0s3(&p0); + QState s1(&machine); + + machine.setInitialState(&s0); + s0.setInitialState(&p0); + + QSignalTransition *t1 = new QSignalTransition(&emitter, SIGNAL(signalWithNoArg())); + p0s1.addTransition(t1); + QSignalTransition *t2 = p0s2.addTransition(&emitter, SIGNAL(signalWithNoArg()), &p0s1); + QSignalTransition *t3 = p0s3.addTransition(&emitter, SIGNAL(signalWithNoArg()), &s1); + QSignalSpy t1Spy(t1, &QAbstractTransition::triggered); + QSignalSpy t2Spy(t2, &QAbstractTransition::triggered); + QSignalSpy t3Spy(t3, &QAbstractTransition::triggered); + QVERIFY(t1Spy.isValid()); + QVERIFY(t2Spy.isValid()); + QVERIFY(t3Spy.isValid()); + + s0.setObjectName("s0"); + p0.setObjectName("p0"); + p0s1.setObjectName("p0s1"); + p0s2.setObjectName("p0s2"); + p0s3.setObjectName("p0s3"); + s1.setObjectName("s1"); + t1->setObjectName("p0s1->p0s1"); + t2->setObjectName("p0s2->p0s1"); + t3->setObjectName("p0s3->s1"); + + machine.start(); + + QTRY_COMPARE(machine.configuration().contains(&s0), true); + QTRY_COMPARE(machine.configuration().contains(&p0), true); + QTRY_COMPARE(machine.configuration().contains(&p0s1), true); + QTRY_COMPARE(machine.configuration().contains(&p0s2), true); + QTRY_COMPARE(machine.configuration().contains(&p0s3), true); + QTRY_COMPARE(machine.configuration().contains(&s1), false); + + QCOMPARE(t1Spy.count(), 0); + QCOMPARE(t2Spy.count(), 0); + QCOMPARE(t3Spy.count(), 0); + + emitter.emitSignalWithNoArg(); + + QTRY_COMPARE(machine.configuration().contains(&s0), true); + QTRY_COMPARE(machine.configuration().contains(&p0), true); + QTRY_COMPARE(machine.configuration().contains(&p0s1), true); + QTRY_COMPARE(machine.configuration().contains(&p0s2), true); + QTRY_COMPARE(machine.configuration().contains(&p0s3), true); + QTRY_COMPARE(machine.configuration().contains(&s1), false); + + QCOMPARE(t1Spy.count(), 1); + QCOMPARE(t2Spy.count(), 1); + QCOMPARE(t3Spy.count(), 0); // t3 got preempted by t2 + + QVERIFY(machine.isRunning()); +} + void tst_QStateMachine::qtbug_46059() { QStateMachine machine; From d946507727b363326d05f48da93c2af04bdda76d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 29 Oct 2015 14:10:36 +0100 Subject: [PATCH 076/133] Testlib: Avoid formatting unneeded messages. Brings down gui/painting/qcolor from 7s to 3s, reducing the calls to printf() helpers from 16E6 to 10E6. Task-number: QTBUG-38890 Change-Id: I34065e6f09fc9a14920b06aa6936908229f3f9c4 Reviewed-by: Frederik Gladhorn --- src/testlib/qtestresult.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/testlib/qtestresult.cpp b/src/testlib/qtestresult.cpp index c65927ba7c..24689c6e87 100644 --- a/src/testlib/qtestresult.cpp +++ b/src/testlib/qtestresult.cpp @@ -235,17 +235,17 @@ bool QTestResult::verify(bool statement, const char *statementStr, { QTEST_ASSERT(statementStr); - char msg[1024]; + char msg[1024] = {'\0'}; if (QTestLog::verboseLevel() >= 2) { qsnprintf(msg, 1024, "QVERIFY(%s)", statementStr); QTestLog::info(msg, file, line); } - const char * format = QTest::expectFailMode - ? "'%s' returned TRUE unexpectedly. (%s)" - : "'%s' returned FALSE. (%s)"; - qsnprintf(msg, 1024, format, statementStr, description ? description : ""); + if (!statement && !QTest::expectFailMode) + qsnprintf(msg, 1024, "'%s' returned FALSE. (%s)", statementStr, description ? description : ""); + else if (statement && QTest::expectFailMode) + qsnprintf(msg, 1024, "'%s' returned TRUE unexpectedly. (%s)", statementStr, description ? description : ""); return checkStatement(statement, msg, file, line); } @@ -259,7 +259,7 @@ bool QTestResult::compare(bool success, const char *failureMsg, QTEST_ASSERT(actual); const size_t maxMsgLen = 1024; - char msg[maxMsgLen]; + char msg[maxMsgLen] = {'\0'}; if (QTestLog::verboseLevel() >= 2) { qsnprintf(msg, maxMsgLen, "QCOMPARE(%s, %s)", actual, expected); @@ -269,9 +269,11 @@ bool QTestResult::compare(bool success, const char *failureMsg, if (!failureMsg) failureMsg = "Compared values are not the same"; - if (success && QTest::expectFailMode) { - qsnprintf(msg, maxMsgLen, - "QCOMPARE(%s, %s) returned TRUE unexpectedly.", actual, expected); + if (success) { + if (QTest::expectFailMode) { + qsnprintf(msg, maxMsgLen, + "QCOMPARE(%s, %s) returned TRUE unexpectedly.", actual, expected); + } } else if (val1 || val2) { size_t len1 = mbstowcs(NULL, actual, maxMsgLen); // Last parameter is not ignored on QNX size_t len2 = mbstowcs(NULL, expected, maxMsgLen); // (result is never larger than this). From 5814cd9d27362db2b5cf06f3ddde3e8eafc5bcc8 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Mon, 26 Oct 2015 00:08:01 +0200 Subject: [PATCH 077/133] winrt: initialize EGL display with automatic Trim and WARP The minimum feature level is now detected before requesting a display. If it is less than 9_3, use the WARP device instead. Task-Id: QTBUG-44495 Task-Id: QTBUG-44694 Change-Id: I9f81f4f92269fab73c291f7373aa07236c7e5f98 Reviewed-by: Oliver Wolff Reviewed-by: Maurice Kalinowski --- .../platforms/winrt/qwinrteglcontext.cpp | 17 ++++++++++++++++- src/plugins/platforms/winrt/winrt.pro | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.cpp b/src/plugins/platforms/winrt/qwinrteglcontext.cpp index 9cb45336d6..b902a02483 100644 --- a/src/plugins/platforms/winrt/qwinrteglcontext.cpp +++ b/src/plugins/platforms/winrt/qwinrteglcontext.cpp @@ -40,6 +40,8 @@ #include +#include + #include #define EGL_EGLEXT_PROTOTYPES #include @@ -79,8 +81,21 @@ void QWinRTEGLContext::initialize() { Q_D(QWinRTEGLContext); + // Test if the hardware supports at least level 9_3 + D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_9_3 }; // minimum feature level + HRESULT hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, featureLevels, 1, + D3D11_SDK_VERSION, nullptr, nullptr, nullptr); + EGLint deviceType = SUCCEEDED(hr) ? EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE + : EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE; + eglBindAPI(EGL_OPENGL_ES_API); - d->eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); + const EGLint displayAttributes[] = { + EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, + EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, deviceType, + EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, true, + EGL_NONE, + }; + d->eglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, displayAttributes); if (d->eglDisplay == EGL_NO_DISPLAY) qCritical("Failed to initialize EGL display: 0x%x", eglGetError()); diff --git a/src/plugins/platforms/winrt/winrt.pro b/src/plugins/platforms/winrt/winrt.pro index 2718ea62bb..be6aad02d1 100644 --- a/src/plugins/platforms/winrt/winrt.pro +++ b/src/plugins/platforms/winrt/winrt.pro @@ -10,7 +10,7 @@ QT += core-private gui-private platformsupport-private DEFINES *= QT_NO_CAST_FROM_ASCII __WRL_NO_DEFAULT_LIB__ GL_GLEXT_PROTOTYPES -LIBS += $$QMAKE_LIBS_CORE -ldwrite +LIBS += $$QMAKE_LIBS_CORE -ldwrite -ld3d11 INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/freetype/include SOURCES = \ From ccbb1b4409474d3a29e7314ac21ea84357423738 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Fri, 30 Oct 2015 08:27:30 +0100 Subject: [PATCH 078/133] winrt: store egldisplay globally The QWinRTEGLContext must not store the display, as it might get destroyed while other objects still need it, for instance QWinRTWindow to delete the surface. Rather create a global static for creating the display once and delete it when application lifecycle ends. Change-Id: Id176b6934e1d1327f5bb70ad0d258de91f675041 Reviewed-by: Andrew Knight --- .../platforms/winrt/qwinrteglcontext.cpp | 45 ++++++++++++------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.cpp b/src/plugins/platforms/winrt/qwinrteglcontext.cpp index b902a02483..c0ff92f738 100644 --- a/src/plugins/platforms/winrt/qwinrteglcontext.cpp +++ b/src/plugins/platforms/winrt/qwinrteglcontext.cpp @@ -51,11 +51,26 @@ QT_BEGIN_NAMESPACE +struct WinRTEGLDisplay +{ + WinRTEGLDisplay() { + eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (eglDisplay == EGL_NO_DISPLAY) + qCritical("Failed to initialize EGL display: 0x%x", eglGetError()); + } + ~WinRTEGLDisplay() { + eglTerminate(eglDisplay); + } + + EGLDisplay eglDisplay; +}; + +Q_GLOBAL_STATIC(WinRTEGLDisplay, g) + class QWinRTEGLContextPrivate { public: QSurfaceFormat format; - EGLDisplay eglDisplay; EGLConfig eglConfig; EGLContext eglContext; }; @@ -72,9 +87,7 @@ QWinRTEGLContext::~QWinRTEGLContext() { Q_D(QWinRTEGLContext); if (d->eglContext != EGL_NO_CONTEXT) - eglDestroyContext(d->eglDisplay, d->eglContext); - if (d->eglDisplay != EGL_NO_DISPLAY) - eglTerminate(d->eglDisplay); + eglDestroyContext(g->eglDisplay, d->eglContext); } void QWinRTEGLContext::initialize() @@ -89,20 +102,21 @@ void QWinRTEGLContext::initialize() : EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE; eglBindAPI(EGL_OPENGL_ES_API); + const EGLint displayAttributes[] = { EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, deviceType, EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, true, EGL_NONE, }; - d->eglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, displayAttributes); - if (d->eglDisplay == EGL_NO_DISPLAY) + g->eglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, displayAttributes); + if (g->eglDisplay == EGL_NO_DISPLAY) qCritical("Failed to initialize EGL display: 0x%x", eglGetError()); - if (!eglInitialize(d->eglDisplay, nullptr, nullptr)) + if (!eglInitialize(g->eglDisplay, nullptr, nullptr)) qCritical("Failed to initialize EGL: 0x%x", eglGetError()); - d->eglConfig = q_configFromGLFormat(d->eglDisplay, d->format); + d->eglConfig = q_configFromGLFormat(g->eglDisplay, d->format); const EGLint flags = d->format.testOption(QSurfaceFormat::DebugContext) ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0; @@ -112,7 +126,7 @@ void QWinRTEGLContext::initialize() EGL_CONTEXT_FLAGS_KHR, flags, EGL_NONE }; - d->eglContext = eglCreateContext(d->eglDisplay, d->eglConfig, nullptr, attributes); + d->eglContext = eglCreateContext(g->eglDisplay, d->eglConfig, nullptr, attributes); if (d->eglContext == EGL_NO_CONTEXT) { qWarning("QEGLPlatformContext: Failed to create context: %x", eglGetError()); return; @@ -126,37 +140,36 @@ bool QWinRTEGLContext::makeCurrent(QPlatformSurface *windowSurface) QWinRTWindow *window = static_cast(windowSurface); if (window->eglSurface() == EGL_NO_SURFACE) - window->createEglSurface(d->eglDisplay, d->eglConfig); + window->createEglSurface(g->eglDisplay, d->eglConfig); EGLSurface surface = window->eglSurface(); if (surface == EGL_NO_SURFACE) return false; - const bool ok = eglMakeCurrent(d->eglDisplay, surface, surface, d->eglContext); + const bool ok = eglMakeCurrent(g->eglDisplay, surface, surface, d->eglContext); if (!ok) { qWarning("QEGLPlatformContext: eglMakeCurrent failed: %x", eglGetError()); return false; } - eglSwapInterval(d->eglDisplay, d->format.swapInterval()); + eglSwapInterval(g->eglDisplay, d->format.swapInterval()); return true; } void QWinRTEGLContext::doneCurrent() { - Q_D(const QWinRTEGLContext); - const bool ok = eglMakeCurrent(d->eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + const bool ok = eglMakeCurrent(g->eglDisplay, EGL_NO_SURFACE, + EGL_NO_SURFACE, EGL_NO_CONTEXT); if (!ok) qWarning("QEGLPlatformContext: eglMakeCurrent failed: %x", eglGetError()); } void QWinRTEGLContext::swapBuffers(QPlatformSurface *windowSurface) { - Q_D(QWinRTEGLContext); Q_ASSERT(windowSurface->surface()->surfaceType() == QSurface::OpenGLSurface); const QWinRTWindow *window = static_cast(windowSurface); - eglSwapBuffers(d->eglDisplay, window->eglSurface()); + eglSwapBuffers(g->eglDisplay, window->eglSurface()); } QSurfaceFormat QWinRTEGLContext::format() const From 25dcc90d799fba3e3f0391783ed07cb22cd1115a Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Fri, 30 Oct 2015 09:43:45 +0100 Subject: [PATCH 079/133] winrt: Exit application properly After returning from main() it is not sufficient to exit the main thread, it also needs to be ensured that the Xaml::IApplication object gets notified by invoking Exit. Task-number: QTBUG-49141 Change-Id: I8ca434be5f17ddddd465ede2a79585c28c51b3ef Reviewed-by: Andrew Knight --- src/winmain/qtmain_winrt.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/winmain/qtmain_winrt.cpp b/src/winmain/qtmain_winrt.cpp index 3553d966d8..473c41ab8e 100644 --- a/src/winmain/qtmain_winrt.cpp +++ b/src/winmain/qtmain_winrt.cpp @@ -156,7 +156,9 @@ public: AppContainer *app = reinterpret_cast(param); int argc = app->args.count(); char **argv = app->args.data(); - return main(argc, argv); + const int res = main(argc, argv); + app->core->Exit(); + return res; }, this, CREATE_SUSPENDED, nullptr); HRESULT hr; From b347697a9d1e1c4521a10e3243d3eed7ac68a31c Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Thu, 29 Oct 2015 11:24:33 +0100 Subject: [PATCH 080/133] winrt: Only destroy existing egl surfaces Running for instance the widget auto tests reveals a lot of egl warnings due to items being created and not shown. Hence no surface was created but tried to be destroyed when window was deleted. Change-Id: I5c99eeb94a8fc2cfeb98f85445e013de61ff9ca9 Reviewed-by: Oliver Wolff Reviewed-by: Andrew Knight --- src/plugins/platforms/winrt/qwinrtwindow.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp index c5b06a5d8a..0d43e76c1a 100644 --- a/src/plugins/platforms/winrt/qwinrtwindow.cpp +++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp @@ -175,6 +175,9 @@ QWinRTWindow::~QWinRTWindow() }); RETURN_VOID_IF_FAILED("Failed to completely destroy window resources, likely because the application is shutting down"); + if (!d->surface) + return; + EGLBoolean value = eglDestroySurface(d->display, d->surface); d->surface = EGL_NO_SURFACE; if (value == EGL_FALSE) From 25717bedfbd29191c8722fd96641fbd24d17e171 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Thu, 29 Oct 2015 13:23:02 +0100 Subject: [PATCH 081/133] tst_qudpsocket::multicast - blacklist several combinations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Different multicast tests fail on different platforms for different reasons. Blacklist them to get rid of insignificant and later fix/un-blacklist. Change-Id: I91548366c7666478ea1cc446bbf337becfdefd49 Task-number: QTBUG-46612 Reviewed-by: Tony Sarajärvi --- tests/auto/network/socket/qudpsocket/BLACKLIST | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 tests/auto/network/socket/qudpsocket/BLACKLIST diff --git a/tests/auto/network/socket/qudpsocket/BLACKLIST b/tests/auto/network/socket/qudpsocket/BLACKLIST new file mode 100644 index 0000000000..3e936aebf6 --- /dev/null +++ b/tests/auto/network/socket/qudpsocket/BLACKLIST @@ -0,0 +1,8 @@ +[multicast:same bind, group ipv6 address] +* +[multicast:valid bind, group ipv6 address] +osx +[multicast:dual bind, group ipv6 address] +osx +[multicast:same bind, group ipv4 address] +osx From 74a2e29705c283a6f52cf007a14a552cf529d051 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 17 Mar 2015 14:40:30 +0100 Subject: [PATCH 082/133] QCommonStyle: Select high-dpi pixmaps from icons Pass a QWindow pointer to QIcon::pixmap(), which allows it to select a pixmap based on the target device pixel ratio. Change-Id: Ib592de2a25060658b70b4e4ab7ff5fbaa9b60260 Task-number: QTBUG-44424 Task-number: QTBUG-38100 Reviewed-by: Timur Pocheptsov --- src/widgets/styles/qcommonstyle.cpp | 62 ++++++++++++++++------------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index a4ecfc547b..83e68d5f5f 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -80,6 +80,11 @@ QT_BEGIN_NAMESPACE +static QWindow *qt_getWindow(const QWidget *widget) +{ + return widget ? widget->window()->windowHandle() : 0; +} + /*! \class QCommonStyle \brief The QCommonStyle class encapsulates the common Look and Feel of a GUI. @@ -395,7 +400,7 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q mode = QIcon::Disabled; QIcon::State state = opt->state & State_Sunken ? QIcon::On : QIcon::Off; - QPixmap pixmap = d->tabBarcloseButtonIcon.pixmap(size, mode, state); + QPixmap pixmap = d->tabBarcloseButtonIcon.pixmap(qt_getWindow(widget), QSize(size, size), mode, state); proxy()->drawItemPixmap(p, opt->rect, Qt::AlignCenter, pixmap); break; } @@ -1237,7 +1242,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, if (button->state & State_On) state = QIcon::On; - QPixmap pixmap = button->icon.pixmap(button->iconSize, mode, state); + QPixmap pixmap = button->icon.pixmap(qt_getWindow(widget), button->iconSize, mode, state); int pixmapWidth = pixmap.width() / pixmap.devicePixelRatio(); int pixmapHeight = pixmap.height() / pixmap.devicePixelRatio(); @@ -1314,7 +1319,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, QPixmap pix; QRect textRect = btn->rect; if (!btn->icon.isNull()) { - pix = btn->icon.pixmap(btn->iconSize, btn->state & State_Enabled ? QIcon::Normal : QIcon::Disabled); + pix = btn->icon.pixmap(qt_getWindow(widget), btn->iconSize, btn->state & State_Enabled ? QIcon::Normal : QIcon::Disabled); proxy()->drawItemPixmap(p, btn->rect, alignment, pix); if (btn->direction == Qt::RightToLeft) textRect.setRight(textRect.right() - btn->iconSize.width() - 4); @@ -1355,7 +1360,8 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, | Qt::TextSingleLine; if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget)) alignment |= Qt::TextHideMnemonic; - QPixmap pix = mbi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize), (mbi->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled); + int iconExtent = proxy()->pixelMetric(PM_SmallIconSize); + QPixmap pix = mbi->icon.pixmap(qt_getWindow(widget), QSize(iconExtent, iconExtent), (mbi->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled); if (!pix.isNull()) proxy()->drawItemPixmap(p,mbi->rect, alignment, pix); else @@ -1519,8 +1525,9 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, if (const QStyleOptionHeader *header = qstyleoption_cast(opt)) { QRect rect = header->rect; if (!header->icon.isNull()) { + int iconExtent = proxy()->pixelMetric(PM_SmallIconSize); QPixmap pixmap - = header->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize), (header->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled); + = header->icon.pixmap(qt_getWindow(widget), QSize(iconExtent, iconExtent), (header->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled); int pixw = pixmap.width() / pixmap.devicePixelRatio(); QRect aligned = alignedRect(header->direction, QFlag(header->iconAlignment), pixmap.size() / pixmap.devicePixelRatio(), rect); @@ -1579,7 +1586,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, mode = QIcon::Active; else mode = QIcon::Normal; - pm = toolbutton->icon.pixmap(toolbutton->rect.size().boundedTo(toolbutton->iconSize), + pm = toolbutton->icon.pixmap(qt_getWindow(widget), toolbutton->rect.size().boundedTo(toolbutton->iconSize), mode, state); pmSize = pm.size() / pm.devicePixelRatio(); } @@ -1800,7 +1807,8 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, if (const QStyleOptionToolBox *tb = qstyleoption_cast(opt)) { bool enabled = tb->state & State_Enabled; bool selected = tb->state & State_Selected; - QPixmap pm = tb->icon.pixmap(proxy()->pixelMetric(QStyle::PM_SmallIconSize, tb, widget), + int iconExtent = proxy()->pixelMetric(QStyle::PM_SmallIconSize, tb, widget); + QPixmap pm = tb->icon.pixmap(qt_getWindow(widget), QSize(iconExtent, iconExtent), enabled ? QIcon::Normal : QIcon::Disabled); QRect cr = subElementRect(QStyle::SE_ToolBoxTabContents, tb, widget); @@ -1875,7 +1883,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, tr = proxy()->subElementRect(SE_TabBarTabText, opt, widget); //we compute tr twice because the style may override subElementRect if (!tabV2.icon.isNull()) { - QPixmap tabIcon = tabV2.icon.pixmap(tabV2.iconSize, + QPixmap tabIcon = tabV2.icon.pixmap(qt_getWindow(widget), tabV2.iconSize, (tabV2.state & State_Enabled) ? QIcon::Normal : QIcon::Disabled, (tabV2.state & State_Selected) ? QIcon::On @@ -2077,7 +2085,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, if (!cb->currentIcon.isNull()) { QIcon::Mode mode = cb->state & State_Enabled ? QIcon::Normal : QIcon::Disabled; - QPixmap pixmap = cb->currentIcon.pixmap(cb->iconSize, mode); + QPixmap pixmap = cb->currentIcon.pixmap(qt_getWindow(widget), cb->iconSize, mode); QRect iconRect(editRect); iconRect.setWidth(cb->iconSize.width() + 4); iconRect = alignedRect(cb->direction, @@ -2376,7 +2384,7 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt, if (!btn->icon.isNull()) { iconRect = itemPixmapRect(cr, Qt::AlignAbsolute | Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, - btn->icon.pixmap(btn->iconSize, QIcon::Normal)); + btn->icon.pixmap(qt_getWindow(widget), btn->iconSize, QIcon::Normal)); if (!textRect.isEmpty()) textRect.translate(iconRect.right() + 4, 0); } @@ -2424,7 +2432,7 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt, } if (!btn->icon.isNull()) { iconRect = itemPixmapRect(cr, Qt::AlignAbsolute | Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, - btn->icon.pixmap(btn->iconSize, QIcon::Normal)); + btn->icon.pixmap(qt_getWindow(widget), btn->iconSize, QIcon::Normal)); if (!textRect.isEmpty()) textRect.translate(iconRect.right() + 4, 0); } @@ -3398,9 +3406,9 @@ void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCompl || qobject_cast(widget) #endif ) - pm = proxy()->standardIcon(SP_DockWidgetCloseButton, &tool, widget).pixmap(10, 10); + pm = proxy()->standardIcon(SP_DockWidgetCloseButton, &tool, widget).pixmap(qt_getWindow(widget), QSize(10, 10)); else - pm = proxy()->standardIcon(SP_TitleBarCloseButton, &tool, widget).pixmap(10, 10); + pm = proxy()->standardIcon(SP_TitleBarCloseButton, &tool, widget).pixmap(qt_getWindow(widget), QSize(10, 10)); tool.rect = ir; tool.state = down ? State_Sunken : State_Raised; proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget); @@ -3419,7 +3427,7 @@ void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCompl ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarMaxButton, widget); down = tb->activeSubControls & SC_TitleBarMaxButton && (opt->state & State_Sunken); - pm = proxy()->standardIcon(SP_TitleBarMaxButton, &tool, widget).pixmap(10, 10); + pm = proxy()->standardIcon(SP_TitleBarMaxButton, &tool, widget).pixmap(qt_getWindow(widget), QSize(10, 10)); tool.rect = ir; tool.state = down ? State_Sunken : State_Raised; proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget); @@ -3437,7 +3445,7 @@ void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCompl && !(tb->titleBarState & Qt::WindowMinimized)) { ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarMinButton, widget); down = tb->activeSubControls & SC_TitleBarMinButton && (opt->state & State_Sunken); - pm = proxy()->standardIcon(SP_TitleBarMinButton, &tool, widget).pixmap(10, 10); + pm = proxy()->standardIcon(SP_TitleBarMinButton, &tool, widget).pixmap(qt_getWindow(widget), QSize(10, 10)); tool.rect = ir; tool.state = down ? State_Sunken : State_Raised; proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget); @@ -3459,7 +3467,7 @@ void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCompl if (drawNormalButton) { ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarNormalButton, widget); down = tb->activeSubControls & SC_TitleBarNormalButton && (opt->state & State_Sunken); - pm = proxy()->standardIcon(SP_TitleBarNormalButton, &tool, widget).pixmap(10, 10); + pm = proxy()->standardIcon(SP_TitleBarNormalButton, &tool, widget).pixmap(qt_getWindow(widget), QSize(10, 10)); tool.rect = ir; tool.state = down ? State_Sunken : State_Raised; proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget); @@ -3477,7 +3485,7 @@ void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCompl && !(tb->titleBarState & Qt::WindowMinimized)) { ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarShadeButton, widget); down = (tb->activeSubControls & SC_TitleBarShadeButton && (opt->state & State_Sunken)); - pm = proxy()->standardIcon(SP_TitleBarShadeButton, &tool, widget).pixmap(10, 10); + pm = proxy()->standardIcon(SP_TitleBarShadeButton, &tool, widget).pixmap(qt_getWindow(widget), QSize(10, 10)); tool.rect = ir; tool.state = down ? State_Sunken : State_Raised; proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget); @@ -3495,7 +3503,7 @@ void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCompl ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarUnshadeButton, widget); down = tb->activeSubControls & SC_TitleBarUnshadeButton && (opt->state & State_Sunken); - pm = proxy()->standardIcon(SP_TitleBarUnshadeButton, &tool, widget).pixmap(10, 10); + pm = proxy()->standardIcon(SP_TitleBarUnshadeButton, &tool, widget).pixmap(qt_getWindow(widget), QSize(10, 10)); tool.rect = ir; tool.state = down ? State_Sunken : State_Raised; proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget); @@ -3511,7 +3519,7 @@ void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCompl ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarContextHelpButton, widget); down = tb->activeSubControls & SC_TitleBarContextHelpButton && (opt->state & State_Sunken); - pm = proxy()->standardIcon(SP_TitleBarContextHelpButton, &tool, widget).pixmap(10, 10); + pm = proxy()->standardIcon(SP_TitleBarContextHelpButton, &tool, widget).pixmap(qt_getWindow(widget), QSize(10, 10)); tool.rect = ir; tool.state = down ? State_Sunken : State_Raised; proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget); @@ -3528,7 +3536,7 @@ void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCompl tb->icon.paint(p, ir); } else { int iconSize = proxy()->pixelMetric(PM_SmallIconSize, tb, widget); - pm = proxy()->standardIcon(SP_TitleBarMenuButton, &tool, widget).pixmap(iconSize, iconSize); + pm = proxy()->standardIcon(SP_TitleBarMenuButton, &tool, widget).pixmap(qt_getWindow(widget), QSize(iconSize, iconSize)); tool.rect = ir; p->save(); proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm); @@ -3715,7 +3723,7 @@ void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCompl } btnOpt.rect = proxy()->subControlRect(CC_MdiControls, opt, SC_MdiCloseButton, widget); proxy()->drawPrimitive(PE_PanelButtonCommand, &btnOpt, p, widget); - QPixmap pm = proxy()->standardIcon(SP_TitleBarCloseButton).pixmap(16, 16); + QPixmap pm = proxy()->standardIcon(SP_TitleBarCloseButton).pixmap(qt_getWindow(widget), QSize(16, 16)); proxy()->drawItemPixmap(p, btnOpt.rect.translated(bsx, bsy), Qt::AlignCenter, pm); } if (opt->subControls & QStyle::SC_MdiNormalButton) { @@ -3732,7 +3740,7 @@ void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCompl } btnOpt.rect = proxy()->subControlRect(CC_MdiControls, opt, SC_MdiNormalButton, widget); proxy()->drawPrimitive(PE_PanelButtonCommand, &btnOpt, p, widget); - QPixmap pm = proxy()->standardIcon(SP_TitleBarNormalButton).pixmap(16, 16); + QPixmap pm = proxy()->standardIcon(SP_TitleBarNormalButton).pixmap(qt_getWindow(widget), QSize(16, 16)); proxy()->drawItemPixmap(p, btnOpt.rect.translated(bsx, bsy), Qt::AlignCenter, pm); } if (opt->subControls & QStyle::SC_MdiMinButton) { @@ -3749,7 +3757,7 @@ void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCompl } btnOpt.rect = proxy()->subControlRect(CC_MdiControls, opt, SC_MdiMinButton, widget); proxy()->drawPrimitive(PE_PanelButtonCommand, &btnOpt, p, widget); - QPixmap pm = proxy()->standardIcon(SP_TitleBarMinButton).pixmap(16, 16); + QPixmap pm = proxy()->standardIcon(SP_TitleBarMinButton).pixmap(qt_getWindow(widget), QSize(16, 16)); proxy()->drawItemPixmap(p, btnOpt.rect.translated(bsx, bsy), Qt::AlignCenter, pm); } } @@ -5762,8 +5770,8 @@ QIcon QCommonStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption const QList sizes = baseIcon.availableSizes(QIcon::Normal, QIcon::Off); for (int i = 0 ; i < sizes.size() ; ++i) { int size = sizes[i].width(); - QPixmap basePixmap = baseIcon.pixmap(size); - QPixmap linkPixmap = linkIcon.pixmap(size/2); + QPixmap basePixmap = baseIcon.pixmap(qt_getWindow(widget), QSize(size, size)); + QPixmap linkPixmap = linkIcon.pixmap(qt_getWindow(widget), QSize(size / 2, size / 2)); QPainter painter(&basePixmap); painter.drawPixmap(size/2, size/2, linkPixmap); icon.addPixmap(basePixmap); @@ -5779,8 +5787,8 @@ QIcon QCommonStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption const QList sizes = baseIcon.availableSizes(QIcon::Normal, QIcon::Off); for (int i = 0 ; i < sizes.size() ; ++i) { int size = sizes[i].width(); - QPixmap basePixmap = baseIcon.pixmap(size); - QPixmap linkPixmap = linkIcon.pixmap(size/2); + QPixmap basePixmap = baseIcon.pixmap(qt_getWindow(widget), QSize(size, size)); + QPixmap linkPixmap = linkIcon.pixmap(qt_getWindow(widget), QSize(size / 2, size / 2)); QPainter painter(&basePixmap); painter.drawPixmap(size/2, size/2, linkPixmap); icon.addPixmap(basePixmap); From 8793ad8175191db9abfb9f034017b9a8fe095f5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 17 Mar 2015 15:02:47 +0100 Subject: [PATCH 083/133] QMacStyle: Select high-dpi pixmaps from icons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pass a QWindow pointer to QIcon::pixmap(), which allows it to select a pixmap based on the target device pixel ratio. Change-Id: Ifb8e49c0eff0a42233a90eee3dfb995c2441bfd6 Task-number: QTBUG-38100 Reviewed-by: Morten Johan Sørvig --- src/widgets/styles/qmacstyle_mac.mm | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index a1c5e82ad1..8dbc1aace8 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -93,6 +93,11 @@ QT_USE_NAMESPACE +static QWindow *qt_getWindow(const QWidget *widget) +{ + return widget ? widget->window()->windowHandle() : 0; +} + @interface QT_MANGLE_NAMESPACE(NotificationReceiver) : NSObject { QMacStylePrivate *mPrivate; } @@ -3124,7 +3129,7 @@ QPixmap QMacStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOpt size = 64; break; } - return icon.pixmap(size, size); + return icon.pixmap(qt_getWindow(widget), QSize(size, size)); } void QMacStyle::setFocusRectPolicy(QWidget *w, FocusRectPolicy policy) @@ -3685,7 +3690,8 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter QIcon::Mode mode = QIcon::Disabled; if (opt->state & State_Enabled) mode = QIcon::Normal; - QPixmap pixmap = header->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize), mode); + int iconExtent = proxy()->pixelMetric(PM_SmallIconSize); + QPixmap pixmap = header->icon.pixmap(window, QSize(iconExtent, iconExtent), mode); QRect pixr = header->rect; pixr.setY(header->rect.center().y() - (pixmap.height() / pixmap.devicePixelRatio() - 1) / 2); @@ -3737,7 +3743,9 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter : QIcon::Disabled; QIcon::State iconState = (tb->state & State_On) ? QIcon::On : QIcon::Off; - QPixmap pixmap = tb->icon.pixmap(tb->rect.size().boundedTo(tb->iconSize), iconMode, iconState); + QPixmap pixmap = tb->icon.pixmap(window, + tb->rect.size().boundedTo(tb->iconSize), + iconMode, iconState); // Draw the text if it's needed. if (tb->toolButtonStyle != Qt::ToolButtonIconOnly) { @@ -4067,7 +4075,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter QIcon::State state = QIcon::Off; if (btn.state & State_On) state = QIcon::On; - QPixmap pixmap = btn.icon.pixmap(btn.iconSize, mode, state); + QPixmap pixmap = btn.icon.pixmap(window, btn.iconSize, mode, state); int pixmapWidth = pixmap.width() / pixmap.devicePixelRatio(); int pixmapHeight = pixmap.height() / pixmap.devicePixelRatio(); contentW += pixmapWidth + QMacStylePrivate::PushButtonContentPadding; @@ -4517,7 +4525,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter if (const QComboBox *comboBox = qobject_cast(w)) { iconSize = comboBox->iconSize(); } - QPixmap pixmap = mi->icon.pixmap(iconSize, mode); + QPixmap pixmap = mi->icon.pixmap(window, iconSize, mode); int pixw = pixmap.width() / pixmap.devicePixelRatio(); int pixh = pixmap.height() / pixmap.devicePixelRatio(); QRect cr(xpos, contentRect.y(), checkcol, contentRect.height()); @@ -4622,10 +4630,11 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter } if (!mi->icon.isNull()) { + int iconExtent = proxy()->pixelMetric(PM_SmallIconSize); drawItemPixmap(p, mi->rect, Qt::AlignCenter | Qt::TextHideMnemonic | Qt::TextDontClip | Qt::TextSingleLine, - mi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize), + mi->icon.pixmap(window, QSize(iconExtent, iconExtent), (mi->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled)); } else { drawItemText(p, mi->rect, @@ -5867,9 +5876,11 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex x += iw; else x += br.width() / 2 - p->fontMetrics().width(titlebar->text) / 2; - if (iw) + if (iw) { + int iconExtent = proxy()->pixelMetric(PM_SmallIconSize); p->drawPixmap(x - iw, y, - titlebar->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize), QIcon::Normal)); + titlebar->icon.pixmap(window, QSize(iconExtent, iconExtent), QIcon::Normal)); + } drawItemText(p, br, Qt::AlignCenter, opt->palette, tds == kThemeStateActive, titlebar->text, QPalette::Text); p->restore(); From 779656299897c5d85fd7bfd0f766cb45c3d82e4e Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 24 Oct 2015 02:45:31 +0200 Subject: [PATCH 084/133] QDataBuffer: disable copy special member functions The compiler-generated ones would break class invariants. This internal class so far isn't copied. This patch makes sure that it stays that way. Change-Id: I8bf75058edaf2adf148ae9edff4bf4e9a3b3368d Reviewed-by: Gunnar Sletta --- src/gui/painting/qdatabuffer_p.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/painting/qdatabuffer_p.h b/src/gui/painting/qdatabuffer_p.h index 0a4a3d5c9e..3fe39efdde 100644 --- a/src/gui/painting/qdatabuffer_p.h +++ b/src/gui/painting/qdatabuffer_p.h @@ -53,6 +53,7 @@ QT_BEGIN_NAMESPACE template class QDataBuffer { + Q_DISABLE_COPY(QDataBuffer); public: QDataBuffer(int res) { From 550cd1d68c01e62b465c393b35a5f2c76b2d1fc5 Mon Sep 17 00:00:00 2001 From: Takao Fujiwara Date: Fri, 30 Oct 2015 14:43:21 +0900 Subject: [PATCH 085/133] IBus: Implement QPlatformInputContext::locale() Listen to "GlobalEngineChanged" dbus signal. Task-number: QTBUG-48772 Change-Id: Ia186a66c75fb3ce2fdf5ef9e358c1807f674594b Reviewed-by: Lars Knoll --- .../ibus/qibusplatforminputcontext.cpp | 33 +++++- .../ibus/qibusplatforminputcontext.h | 6 +- .../platforminputcontexts/ibus/qibusproxy.cpp | 29 +++++ .../platforminputcontexts/ibus/qibusproxy.h | 23 ++++ .../platforminputcontexts/ibus/qibustypes.cpp | 110 +++++++++++++++++- .../platforminputcontexts/ibus/qibustypes.h | 33 ++++++ 6 files changed, 227 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp index dca21245aa..a952123576 100644 --- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp +++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp @@ -58,8 +58,6 @@ QT_BEGIN_NAMESPACE -Q_LOGGING_CATEGORY(qtQpaInputMethods, "qt.qpa.input.methods") - enum { debug = 0 }; class QIBusPlatformInputContextPrivate @@ -87,6 +85,7 @@ public: bool busConnected; QString predit; bool needsSurroundingText; + QLocale locale; }; @@ -412,6 +411,11 @@ void QIBusPlatformInputContext::filterEventFinished(QDBusPendingCallWatcher *cal call->deleteLater(); } +QLocale QIBusPlatformInputContext::locale() const +{ + return d->locale; +} + void QIBusPlatformInputContext::socketChanged(const QString &str) { qCDebug(qtQpaInputMethods) << "socketChanged"; @@ -421,6 +425,8 @@ void QIBusPlatformInputContext::socketChanged(const QString &str) if (d->context) disconnect(d->context); + if (d->bus && d->bus->isValid()) + disconnect(d->bus); if (d->connection) d->connection->disconnectFromBus(QLatin1String("QIBusProxy")); @@ -439,8 +445,26 @@ void QIBusPlatformInputContext::connectToBus() m_socketWatcher.addPath(QIBusPlatformInputContextPrivate::getSocketPath()); } +void QIBusPlatformInputContext::globalEngineChanged(const QString &engine_name) +{ + if (!d->bus || !d->bus->isValid()) + return; + + QIBusEngineDesc desc = d->bus->getGlobalEngine(); + Q_ASSERT(engine_name == desc.engine_name); + QLocale locale(desc.language); + if (d->locale != locale) { + d->locale = locale; + emitLocaleChanged(); + } +} + void QIBusPlatformInputContext::connectToContextSignals() { + if (d->bus && d->bus->isValid()) { + connect(d->bus, SIGNAL(GlobalEngineChanged(QString)), this, SLOT(globalEngineChanged(QString))); + } + if (d->context) { connect(d->context, SIGNAL(CommitText(QDBusVariant)), SLOT(commitText(QDBusVariant))); connect(d->context, SIGNAL(UpdatePreeditText(QDBusVariant,uint,bool)), this, SLOT(updatePreeditText(QDBusVariant,uint,bool))); @@ -461,6 +485,11 @@ QIBusPlatformInputContextPrivate::QIBusPlatformInputContextPrivate() if (!valid) return; initBus(); + + if (bus && bus->isValid()) { + QIBusEngineDesc desc = bus->getGlobalEngine(); + locale = QLocale(desc.language); + } } void QIBusPlatformInputContextPrivate::initBus() diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h index a8efd9deb3..824e9c2073 100644 --- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h +++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h @@ -36,16 +36,14 @@ #include #include +#include #include #include -#include #include #include QT_BEGIN_NAMESPACE -Q_DECLARE_LOGGING_CATEGORY(qtQpaInputMethods) - class QIBusPlatformInputContextPrivate; class QDBusVariant; @@ -90,6 +88,7 @@ public: void commit() Q_DECL_OVERRIDE; void update(Qt::InputMethodQueries) Q_DECL_OVERRIDE; bool filterEvent(const QEvent *event) Q_DECL_OVERRIDE; + QLocale locale() const Q_DECL_OVERRIDE; public Q_SLOTS: void commitText(const QDBusVariant &text); @@ -100,6 +99,7 @@ public Q_SLOTS: void filterEventFinished(QDBusPendingCallWatcher *call); void socketChanged(const QString &str); void connectToBus(); + void globalEngineChanged(const QString &engine_name); private: QIBusPlatformInputContextPrivate *d; diff --git a/src/plugins/platforminputcontexts/ibus/qibusproxy.cpp b/src/plugins/platforminputcontexts/ibus/qibusproxy.cpp index e6b255a06d..9efa6f7eb0 100644 --- a/src/plugins/platforminputcontexts/ibus/qibusproxy.cpp +++ b/src/plugins/platforminputcontexts/ibus/qibusproxy.cpp @@ -9,6 +9,8 @@ * before re-generating it. */ +#include + #include "qibusproxy.h" /* @@ -18,9 +20,36 @@ QIBusProxy::QIBusProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) { + this->connection().connect(service, + path, + this->interface(), // interface + QStringLiteral("GlobalEngineChanged"), + QStringList(), + QString(), // signature + this, SLOT(globalEngineChanged(QString))); } QIBusProxy::~QIBusProxy() { } +QIBusEngineDesc QIBusProxy::getGlobalEngine() +{ + QIBusEngineDesc desc; + QDBusReply reply = GetGlobalEngine(); + QVariant variant = reply.value().variant(); + if (!variant.isValid()) + return desc; + QVariant child = variant.value().variant(); + if (!child.isValid()) + return desc; + const QDBusArgument argument = child.value(); + argument >> desc; + return desc; +} + +void QIBusProxy::globalEngineChanged(const QString &engine_name) +{ + emit GlobalEngineChanged(engine_name); +} + diff --git a/src/plugins/platforminputcontexts/ibus/qibusproxy.h b/src/plugins/platforminputcontexts/ibus/qibusproxy.h index 69443a524d..bbaebe1b96 100644 --- a/src/plugins/platforminputcontexts/ibus/qibusproxy.h +++ b/src/plugins/platforminputcontexts/ibus/qibusproxy.h @@ -20,6 +20,8 @@ #include #include +#include "qibustypes.h" + /* * Proxy class for interface org.freedesktop.IBus */ @@ -29,6 +31,8 @@ class QIBusProxy: public QDBusAbstractInterface public: static inline const char *staticInterfaceName() { return "org.freedesktop.IBus"; } + static inline QString dbusInterfaceProperties() + { return QStringLiteral("org.freedesktop.DBus.Properties"); } public: QIBusProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); @@ -82,7 +86,26 @@ public Q_SLOTS: // METHODS return asyncCallWithArgumentList(QLatin1String("RegisterComponent"), argumentList); } + inline QDBusPendingReply GetGlobalEngine() + { + if (!this->isValid() || this->service().isEmpty() || this->path().isEmpty()) + return QDBusMessage::createError(this->lastError()); + + QDBusMessage msg = QDBusMessage::createMethodCall(this->service(), + this->path(), + dbusInterfaceProperties(), + QStringLiteral("Get")); + msg << this->interface() << QStringLiteral("GlobalEngine"); + return this->connection().asyncCall(msg, this->timeout()); + } + + QIBusEngineDesc getGlobalEngine(); + +private: + void globalEngineChanged(const QString &engine_name); + Q_SIGNALS: // SIGNALS + void GlobalEngineChanged(const QString &engine_name); }; #endif diff --git a/src/plugins/platforminputcontexts/ibus/qibustypes.cpp b/src/plugins/platforminputcontexts/ibus/qibustypes.cpp index f88e5ca5a3..7cf3b24570 100644 --- a/src/plugins/platforminputcontexts/ibus/qibustypes.cpp +++ b/src/plugins/platforminputcontexts/ibus/qibustypes.cpp @@ -37,6 +37,9 @@ QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(qtQpaInputMethods, "qt.qpa.input.methods") +Q_LOGGING_CATEGORY(qtQpaInputMethodsSerialize, "qt.qpa.input.methods.serialize") + QIBusSerializable::QIBusSerializable() { } @@ -202,7 +205,7 @@ QDBusArgument &operator<<(QDBusArgument &argument, const QIBusAttributeList &att const QDBusArgument &operator>>(const QDBusArgument &arg, QIBusAttributeList &attrList) { -// qDebug() << "QIBusAttributeList::fromDBusArgument()" << arg.currentSignature(); + qCDebug(qtQpaInputMethodsSerialize) << "QIBusAttributeList::fromDBusArgument()" << arg.currentSignature(); arg.beginStructure(); arg >> static_cast(attrList); @@ -277,7 +280,7 @@ QDBusArgument &operator<<(QDBusArgument &argument, const QIBusText &text) const QDBusArgument &operator>>(const QDBusArgument &argument, QIBusText &text) { -// qDebug() << "QIBusText::fromDBusArgument()" << arg.currentSignature(); + qCDebug(qtQpaInputMethodsSerialize) << "QIBusText::fromDBusArgument()" << argument.currentSignature(); argument.beginStructure(); argument >> static_cast(text); @@ -291,4 +294,107 @@ const QDBusArgument &operator>>(const QDBusArgument &argument, QIBusText &text) return argument; } +QIBusEngineDesc::QIBusEngineDesc() + : engine_name(""), + longname(""), + description(""), + language(""), + license(""), + author(""), + icon(""), + layout(""), + rank(0), + hotkeys(""), + symbol(""), + setup(""), + layout_variant(""), + layout_option(""), + version(""), + textdomain(""), + iconpropkey("") +{ + name = "IBusEngineDesc"; +} + +QIBusEngineDesc::~QIBusEngineDesc() +{ +} + +QDBusArgument &operator<<(QDBusArgument &argument, const QIBusEngineDesc &desc) +{ + argument.beginStructure(); + + argument << static_cast(desc); + + argument << desc.engine_name; + argument << desc.longname; + argument << desc.description; + argument << desc.language; + argument << desc.license; + argument << desc.author; + argument << desc.icon; + argument << desc.layout; + argument << desc.rank; + argument << desc.hotkeys; + argument << desc.symbol; + argument << desc.setup; + argument << desc.layout_variant; + argument << desc.layout_option; + argument << desc.version; + argument << desc.textdomain; + argument << desc.iconpropkey; + + argument.endStructure(); + return argument; +} + +const QDBusArgument &operator>>(const QDBusArgument &argument, QIBusEngineDesc &desc) +{ + qCDebug(qtQpaInputMethodsSerialize) << "QIBusEngineDesc::fromDBusArgument()" << argument.currentSignature(); + argument.beginStructure(); + + argument >> static_cast(desc); + + argument >> desc.engine_name; + argument >> desc.longname; + argument >> desc.description; + argument >> desc.language; + argument >> desc.license; + argument >> desc.author; + argument >> desc.icon; + argument >> desc.layout; + argument >> desc.rank; + argument >> desc.hotkeys; + argument >> desc.symbol; + argument >> desc.setup; + // Previous IBusEngineDesc supports the arguments between engine_name + // and setup. + if (argument.currentSignature() == "") { + argument.endStructure(); + return argument; + } + argument >> desc.layout_variant; + argument >> desc.layout_option; + // Previous IBusEngineDesc supports the arguments between engine_name + // and layout_option. + if (argument.currentSignature() == "") { + argument.endStructure(); + return argument; + } + argument >> desc.version; + if (argument.currentSignature() == "") { + argument.endStructure(); + return argument; + } + argument >> desc.textdomain; + if (argument.currentSignature() == "") { + argument.endStructure(); + return argument; + } + argument >> desc.iconpropkey; + + argument.endStructure(); + return argument; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforminputcontexts/ibus/qibustypes.h b/src/plugins/platforminputcontexts/ibus/qibustypes.h index cb0d9ff2aa..b4145863bc 100644 --- a/src/plugins/platforminputcontexts/ibus/qibustypes.h +++ b/src/plugins/platforminputcontexts/ibus/qibustypes.h @@ -37,9 +37,13 @@ #include #include #include +#include QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(qtQpaInputMethods) +Q_DECLARE_LOGGING_CATEGORY(qtQpaInputMethodsSerialize) + class QIBusSerializable { public: @@ -100,6 +104,31 @@ public: QIBusAttributeList attributes; }; +class QIBusEngineDesc : public QIBusSerializable +{ +public: + QIBusEngineDesc(); + ~QIBusEngineDesc(); + + QString engine_name; + QString longname; + QString description; + QString language; + QString license; + QString author; + QString icon; + QString layout; + unsigned int rank; + QString hotkeys; + QString symbol; + QString setup; + QString layout_variant; + QString layout_option; + QString version; + QString textdomain; + QString iconpropkey; +}; + QDBusArgument &operator<<(QDBusArgument &argument, const QIBusSerializable &object); const QDBusArgument &operator>>(const QDBusArgument &argument, QIBusSerializable &object); @@ -112,11 +141,15 @@ const QDBusArgument &operator>>(const QDBusArgument &arg, QIBusAttributeList &at QDBusArgument &operator<<(QDBusArgument &argument, const QIBusText &text); const QDBusArgument &operator>>(const QDBusArgument &argument, QIBusText &text); +QDBusArgument &operator<<(QDBusArgument &argument, const QIBusEngineDesc &desc); +const QDBusArgument &operator>>(const QDBusArgument &argument, QIBusEngineDesc &desc); + QT_END_NAMESPACE Q_DECLARE_METATYPE(QIBusSerializable) Q_DECLARE_METATYPE(QIBusAttribute) Q_DECLARE_METATYPE(QIBusAttributeList) Q_DECLARE_METATYPE(QIBusText) +Q_DECLARE_METATYPE(QIBusEngineDesc) #endif From 97b564374b99be4e3c077e6999e61d3d6688cf17 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 2 Nov 2015 09:27:57 +0100 Subject: [PATCH 086/133] qcoreapplication_win.cpp: Correct FIXME comment on qWinMain(). Mention that it is still used by Active Qt. Task-number: QTBUG-49148 Change-Id: Ic31b2f60b25886cd55c5fa516082d79311ab84cc Reviewed-by: Fredrik Orderud Reviewed-by: Oliver Wolff --- src/corelib/kernel/qcoreapplication_win.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp index 396d2f740a..324b664a1a 100644 --- a/src/corelib/kernel/qcoreapplication_win.cpp +++ b/src/corelib/kernel/qcoreapplication_win.cpp @@ -139,9 +139,10 @@ QString QCoreApplicationPrivate::appName() const #if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) -// ### Qt6: FIXME: Remove this function. It is only there since for binary -// compatibility for applications built with Qt 5.3 using qtmain.lib which calls it. -// In Qt 5.4, qtmain.lib was changed to use CommandLineToArgvW() without calling into Qt5Core. +// ### Qt6: FIXME: Consider removing this function. It is here for Active Qt +// servers and for binary for compatibility to applications built with Qt 5.3 +// using qtmain.lib which calls it In Qt 5.4, qtmain.lib was changed to use +// CommandLineToArgvW() without calling into Qt5Core. Q_CORE_EXPORT void qWinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdParam, int cmdShow, int &argc, QVector &argv) From 9b735a46182350e42495053ca741150a06f5c546 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Sat, 31 Oct 2015 19:08:25 +0100 Subject: [PATCH 087/133] WinRT: Add support for QOpenGLWidget Also involves adding support for sharing contexts. Task-number: QTBUG-48663 Change-Id: I0b18846ae70b63a0a21132f820a12ea744c0e936 Reviewed-by: Andrew Knight Reviewed-by: Maurice Kalinowski --- src/plugins/platforms/winrt/qwinrtbackingstore.cpp | 3 ++- src/plugins/platforms/winrt/qwinrteglcontext.cpp | 10 +++++++--- src/plugins/platforms/winrt/qwinrtintegration.cpp | 1 + 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp index ee54bf795c..4517200a2d 100644 --- a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp +++ b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp @@ -66,7 +66,8 @@ QWinRTBackingStore::QWinRTBackingStore(QWindow *window) d->initialized = false; d->screen = static_cast(window->screen()->handle()); - window->setSurfaceType(QSurface::OpenGLSurface); // Required for flipping, but could be done in the swap + if (window->surfaceType() == QSurface::RasterSurface) + window->setSurfaceType(QSurface::OpenGLSurface); } bool QWinRTBackingStore::initialize() diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.cpp b/src/plugins/platforms/winrt/qwinrteglcontext.cpp index c0ff92f738..3fd0278360 100644 --- a/src/plugins/platforms/winrt/qwinrteglcontext.cpp +++ b/src/plugins/platforms/winrt/qwinrteglcontext.cpp @@ -70,9 +70,11 @@ Q_GLOBAL_STATIC(WinRTEGLDisplay, g) class QWinRTEGLContextPrivate { public: + QWinRTEGLContextPrivate() : eglContext(EGL_NO_CONTEXT), eglShareContext(EGL_NO_CONTEXT) { } QSurfaceFormat format; EGLConfig eglConfig; EGLContext eglContext; + EGLContext eglShareContext; }; QWinRTEGLContext::QWinRTEGLContext(QOpenGLContext *context) @@ -81,6 +83,8 @@ QWinRTEGLContext::QWinRTEGLContext(QOpenGLContext *context) Q_D(QWinRTEGLContext); d->format = context->format(); d->format.setRenderableType(QSurfaceFormat::OpenGLES); + if (QPlatformOpenGLContext *shareHandle = context->shareHandle()) + d->eglShareContext = static_cast(shareHandle)->d_ptr->eglContext; } QWinRTEGLContext::~QWinRTEGLContext() @@ -126,7 +130,7 @@ void QWinRTEGLContext::initialize() EGL_CONTEXT_FLAGS_KHR, flags, EGL_NONE }; - d->eglContext = eglCreateContext(g->eglDisplay, d->eglConfig, nullptr, attributes); + d->eglContext = eglCreateContext(g->eglDisplay, d->eglConfig, d->eglShareContext, attributes); if (d->eglContext == EGL_NO_CONTEXT) { qWarning("QEGLPlatformContext: Failed to create context: %x", eglGetError()); return; @@ -136,7 +140,7 @@ void QWinRTEGLContext::initialize() bool QWinRTEGLContext::makeCurrent(QPlatformSurface *windowSurface) { Q_D(QWinRTEGLContext); - Q_ASSERT(windowSurface->surface()->surfaceType() == QSurface::OpenGLSurface); + Q_ASSERT(windowSurface->surface()->supportsOpenGL()); QWinRTWindow *window = static_cast(windowSurface); if (window->eglSurface() == EGL_NO_SURFACE) @@ -166,7 +170,7 @@ void QWinRTEGLContext::doneCurrent() void QWinRTEGLContext::swapBuffers(QPlatformSurface *windowSurface) { - Q_ASSERT(windowSurface->surface()->surfaceType() == QSurface::OpenGLSurface); + Q_ASSERT(windowSurface->surface()->supportsOpenGL()); const QWinRTWindow *window = static_cast(windowSurface); eglSwapBuffers(g->eglDisplay, window->eglSurface()); diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp index 7ee3bf8593..dabb2603b6 100644 --- a/src/plugins/platforms/winrt/qwinrtintegration.cpp +++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp @@ -188,6 +188,7 @@ bool QWinRTIntegration::hasCapability(QPlatformIntegration::Capability cap) cons case ApplicationState: case NonFullScreenWindows: case MultipleWindows: + case RasterGLSurface: return true; default: return QPlatformIntegration::hasCapability(cap); From 635394c84a65d25cba2a9a283230d673bee4a8ae Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Sun, 1 Nov 2015 18:56:52 +0100 Subject: [PATCH 088/133] WinRT: Fix wrong mouse event position for non-fullscreen windows When calling handleMouseEvent and similar, there are two choices when it comes to the global and local position: by specifying the window it is the caller's responsibility to provide a valid local position. When the window is null, QGuiApplication calculates the local position. The winrt plugin chose the former and therefore passing the global position as local is wrong. Task-number: QTBUG-48208 Change-Id: I3e1137cdb5d023296c4d73899da016641303c7df Reviewed-by: Andrew Knight --- src/plugins/platforms/winrt/qwinrtscreen.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index 0fe3262398..d1a69c43f7 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -914,6 +914,11 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args) Point point; pointerPoint->get_Position(&point); QPointF pos(point.X * d->scaleFactor, point.Y * d->scaleFactor); + QPointF localPos = pos; + if (topWindow()) { + const QPointF globalPosDelta = pos - pos.toPoint(); + localPos = topWindow()->mapFromGlobal(pos.toPoint()) + globalPosDelta; + } VirtualKeyModifiers modifiers; args->get_KeyModifiers(&modifiers); @@ -947,7 +952,7 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args) boolean isHorizontal; properties->get_IsHorizontalMouseWheel(&isHorizontal); QPoint angleDelta(isHorizontal ? delta : 0, isHorizontal ? 0 : delta); - QWindowSystemInterface::handleWheelEvent(topWindow(), pos, pos, QPoint(), angleDelta, mods); + QWindowSystemInterface::handleWheelEvent(topWindow(), localPos, pos, QPoint(), angleDelta, mods); break; } @@ -973,7 +978,7 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args) if (isPressed) buttons |= Qt::XButton2; - QWindowSystemInterface::handleMouseEvent(topWindow(), pos, pos, buttons, mods); + QWindowSystemInterface::handleMouseEvent(topWindow(), localPos, pos, buttons, mods); break; } From 70eb13776856a16c9a95191aa3b9b4e0a94c916b Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Thu, 29 Oct 2015 09:54:43 +0100 Subject: [PATCH 089/133] Doc: Fix snippet tags for QString::[last]indexOf() overloads Duplicate identifiers were introduced for QString code snippets, resulting in the wrong snippets to be quoted. Change-Id: I75e9c99cbc73bf39262079f7f53342a6ac90c2a7 Task-number: QTBUG-49111 Reviewed-by: Venugopal Shivashankar --- src/corelib/doc/snippets/qstring/main.cpp | 8 ++++---- src/corelib/tools/qstring.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/corelib/doc/snippets/qstring/main.cpp b/src/corelib/doc/snippets/qstring/main.cpp index d0b5fb00f3..07ff9301bf 100644 --- a/src/corelib/doc/snippets/qstring/main.cpp +++ b/src/corelib/doc/snippets/qstring/main.cpp @@ -408,12 +408,12 @@ void Widget::firstIndexOfFunction() str.indexOf(QRegularExpression("m[aeiou]"), 0); // returns 4 //! [93] - //! [97] + //! [99] QString str = "the minimum"; QRegularExpressionMatch match; str.indexOf(QRegularExpression("m[aeiou]"), 0, &match); // returns 4 // match.captured() == mi - //! [97] + //! [99] } void Widget::insertFunction() @@ -465,12 +465,12 @@ void Widget::lastIndexOfFunction() str.lastIndexOf(QRegularExpression("m[aeiou]")); // returns 8 //! [94] - //! [98] + //! [100] QString str = "the minimum"; QRegularExpressionMatch match; str.lastIndexOf(QRegularExpression("m[aeiou]"), -1, &match); // returns 8 // match.captured() == mu - //! [98] + //! [100] } void Widget::leftFunction() diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 39e0f6825e..13d8a3864b 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -3846,7 +3846,7 @@ int QString::indexOf(const QRegularExpression& re, int from) const Example: - \snippet qstring/main.cpp 97 + \snippet qstring/main.cpp 99 */ int QString::indexOf(const QRegularExpression &re, int from, QRegularExpressionMatch *rmatch) const { @@ -3897,7 +3897,7 @@ int QString::lastIndexOf(const QRegularExpression &re, int from) const Example: - \snippet qstring/main.cpp 98 + \snippet qstring/main.cpp 100 */ int QString::lastIndexOf(const QRegularExpression &re, int from, QRegularExpressionMatch *rmatch) const { From ada4b4aaa5ccb9a41a42eb2b4f8f0e7625e8ef9c Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 27 Oct 2015 12:23:42 +0100 Subject: [PATCH 090/133] Attach all signal spies before setting the watcher's future. Attaching spies afterwards was provoking a warning during tests: QFutureWatcher::connect: connecting after calling setFuture() is likely to produce race Change-Id: I6ee8c3613cecebd1c69b0337139d8a19a33f4a11 Reviewed-by: Marc Mutz --- .../qfuturewatcher/tst_qfuturewatcher.cpp | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp b/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp index 5ec32b1d02..f64d92dcdb 100644 --- a/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp +++ b/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp @@ -313,10 +313,16 @@ void tst_QFutureWatcher::futureSignals() // (QSignalSpy does not trigger it.) connect(&f, SIGNAL(resultReadyAt(int)), &object, SLOT(resultReadyAt(int))); a.reportStarted(); - f.setFuture(a.future()); QSignalSpy progressSpy(&f, &QFutureWatcher::progressValueChanged); + QSignalSpy finishedSpy(&f, &QFutureWatcher::finished); + QSignalSpy resultReadySpy(&f, &QFutureWatcher::resultReadyAt); + QVERIFY(progressSpy.isValid()); + QVERIFY(finishedSpy.isValid()); + QVERIFY(resultReadySpy.isValid()); + f.setFuture(a.future()); + const int progress = 1; a.setProgressValue(progress); QTest::qWait(10); @@ -324,12 +330,6 @@ void tst_QFutureWatcher::futureSignals() QCOMPARE(progressSpy.takeFirst().at(0).toInt(), 0); QCOMPARE(progressSpy.takeFirst().at(0).toInt(), 1); - QSignalSpy finishedSpy(&f, &QFutureWatcher::finished); - QSignalSpy resultReadySpy(&f, &QFutureWatcher::resultReadyAt); - - QVERIFY(finishedSpy.isValid()); - QVERIFY(resultReadySpy.isValid()); - const int result = 10; a.reportResult(&result); QTest::qWait(10); @@ -427,16 +427,15 @@ void tst_QFutureWatcher::disconnectRunningFuture() QFuture f = a.future(); QFutureWatcher *watcher = new QFutureWatcher(); - watcher->setFuture(f); - - SignalSlotObject object; - connect(watcher, SIGNAL(resultReadyAt(int)), &object, SLOT(resultReadyAt(int))); - QSignalSpy finishedSpy(watcher, &QFutureWatcher::finished); QSignalSpy resultReadySpy(watcher, &QFutureWatcher::resultReadyAt); QVERIFY(finishedSpy.isValid()); QVERIFY(resultReadySpy.isValid()); + watcher->setFuture(f); + + SignalSlotObject object; + connect(watcher, SIGNAL(resultReadyAt(int)), &object, SLOT(resultReadyAt(int))); const int result = 10; a.reportResult(&result); From ab1a5f10039429e9114cd905716b31bbec601d60 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 27 Oct 2015 12:02:54 +0100 Subject: [PATCH 091/133] Fix pauseEvents() test to test what should be true, not what is. If the future is finished when a watcher starts watching it, it is perfectly reasonable for the watcher to get the finished message promptly. If you pause the watcher before any message loops get to run, the message presently won't get through until the watcher is resumed, but there is no reason to guarantee that; indeed, one could consider it somewhat perverse behavior. So move the reportFinished() calls to after the pause()s. Also eliminate a used-once local variable and use QTRY_VERIFY() in one place where qWait() was used before. Change-Id: I4bc6091fd7437a4d341be511b7a140f3d72d850e Reviewed-by: Marc Mutz --- .../qfuturewatcher/tst_qfuturewatcher.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp b/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp index f64d92dcdb..c4fad93e4b 100644 --- a/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp +++ b/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp @@ -677,11 +677,6 @@ void tst_QFutureWatcher::pauseEvents() QFutureInterface iface; iface.reportStarted(); - QFuture a = iface.future(); - - int value = 0; - iface.reportFinished(&value); - QFutureWatcher watcher; SignalSlotObject object; @@ -689,14 +684,17 @@ void tst_QFutureWatcher::pauseEvents() QSignalSpy resultReadySpy(&watcher, &QFutureWatcher::resultReadyAt); QVERIFY(resultReadySpy.isValid()); - watcher.setFuture(a); + watcher.setFuture(iface.future()); watcher.pause(); + int value = 0; + iface.reportFinished(&value); + QTest::qWait(10); QCOMPARE(resultReadySpy.count(), 0); watcher.resume(); - QTest::qWait(10); + QTRY_VERIFY2(!resultReadySpy.isEmpty(), "Result didn't arrive"); QCOMPARE(resultReadySpy.count(), 1); } { @@ -705,9 +703,6 @@ void tst_QFutureWatcher::pauseEvents() QFuture a = iface.future(); - int value = 0; - iface.reportFinished(&value); - QFutureWatcher watcher; SignalSlotObject object; @@ -718,6 +713,9 @@ void tst_QFutureWatcher::pauseEvents() watcher.setFuture(a); a.pause(); + int value = 0; + iface.reportFinished(&value); + QFuture b; watcher.setFuture(b); // If we watch b instead, resuming a a.resume(); // should give us no results. From 317b9e9c5fd4ba318658cce2bdef3ef82e1dd288 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Thu, 29 Oct 2015 14:11:29 +0100 Subject: [PATCH 092/133] Support for Wayland servers on i.MX6 A wayland compositor on i.MX6 needs to create the wl_display before creating the EGL display. This wl_display then needs to be exposed so that QWaylandCompositor can use it. Change-Id: Id60f6dd2fbba05140ca0671da6f17dbc2ecce3a3 Reviewed-by: Laszlo Agocs --- .../qpa/wayland-server/wayland-server.pro | 5 + config.tests/qpa/wayland-server/wl.cpp | 40 ++++++++ configure | 10 ++ .../deviceintegration/deviceintegration.pro | 1 + .../eglfs_viv_wl/eglfs_viv_wl.json | 3 + .../eglfs_viv_wl/eglfs_viv_wl.pro | 23 +++++ .../eglfs_viv_wl/qeglfsvivwlintegration.cpp | 93 +++++++++++++++++++ .../eglfs_viv_wl/qeglfsvivwlintegration.h | 60 ++++++++++++ .../eglfs_viv_wl/qeglfsvivwlmain.cpp | 50 ++++++++++ .../eglfs/qeglfsdeviceintegration.cpp | 5 + .../platforms/eglfs/qeglfsdeviceintegration.h | 2 + .../platforms/eglfs/qeglfsintegration.cpp | 9 +- 12 files changed, 299 insertions(+), 2 deletions(-) create mode 100644 config.tests/qpa/wayland-server/wayland-server.pro create mode 100644 config.tests/qpa/wayland-server/wl.cpp create mode 100644 src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.json create mode 100644 src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro create mode 100644 src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.cpp create mode 100644 src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.h create mode 100644 src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlmain.cpp diff --git a/config.tests/qpa/wayland-server/wayland-server.pro b/config.tests/qpa/wayland-server/wayland-server.pro new file mode 100644 index 0000000000..c07740d20f --- /dev/null +++ b/config.tests/qpa/wayland-server/wayland-server.pro @@ -0,0 +1,5 @@ +SOURCES = wl.cpp + +CONFIG -= qt +CONFIG += link_pkgconfig +PKGCONFIG += wayland-server diff --git a/config.tests/qpa/wayland-server/wl.cpp b/config.tests/qpa/wayland-server/wl.cpp new file mode 100644 index 0000000000..ba1756af57 --- /dev/null +++ b/config.tests/qpa/wayland-server/wl.cpp @@ -0,0 +1,40 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the config.tests of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +int main(int, char **) +{ + wl_display_create(); + return 0; +} diff --git a/configure b/configure index 16e8fb4402..f60802a9b5 100755 --- a/configure +++ b/configure @@ -681,6 +681,7 @@ CFG_EGLFS_BRCM=no CFG_EGLFS_EGLDEVICE=no CFG_EGLFS_MALI=no CFG_EGLFS_VIV=no +CFG_EGLFS_VIV_WL=no CFG_DIRECTFB=auto CFG_GBM=auto CFG_LINUXFB=auto @@ -5776,6 +5777,11 @@ if [ "$CFG_EGLFS" != "no" ]; then else CFG_EGLFS_VIV=no fi + if [ "$CFG_EGLFS_VIV" = "yes" ] && compileTest qpa/wayland-server "wayland-server"; then + CFG_EGLFS_VIV_WL=yes + else + CFG_EGLFS_VIV_WL=no + fi else CFG_EGLFS="no" fi @@ -6222,6 +6228,9 @@ if [ "$CFG_EGLFS_MALI" = "yes" ]; then fi if [ "$CFG_EGLFS_VIV" = "yes" ]; then QT_CONFIG="$QT_CONFIG eglfs_viv" + if [ "$CFG_EGLFS_VIV_WL" = "yes" ]; then + QT_CONFIG="$QT_CONFIG eglfs_viv_wl" + fi fi # enable openvg @@ -7299,6 +7308,7 @@ report_support " QPA backends:" report_support " DirectFB ............." "$CFG_DIRECTFB" report_support " EGLFS ................" "$CFG_EGLFS" report_support " EGLFS i.MX6 ........" "$CFG_EGLFS_VIV" +report_support " EGLFS i.MX6 Wayland." "$CFG_EGLFS_VIV_WL" report_support " EGLFS EGLDevice ...." "$CFG_EGLFS_EGLDEVICE" report_support " EGLFS GBM .........." "$CFG_EGLFS_GBM" report_support " EGLFS Mali ........." "$CFG_EGLFS_MALI" diff --git a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro index cf367d930f..266a97dff5 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro @@ -6,3 +6,4 @@ contains(QT_CONFIG, eglfs_egldevice): SUBDIRS += eglfs_kms_egldevice contains(QT_CONFIG, eglfs_brcm): SUBDIRS += eglfs_brcm contains(QT_CONFIG, eglfs_mali): SUBDIRS += eglfs_mali contains(QT_CONFIG, eglfs_viv): SUBDIRS += eglfs_viv +contains(QT_CONFIG, eglfs_viv_wl): SUBDIRS += eglfs_viv_wl diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.json b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.json new file mode 100644 index 0000000000..ced5245fa0 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "eglfs_viv_wl" ] +} diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro new file mode 100644 index 0000000000..26b6a2e9ea --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro @@ -0,0 +1,23 @@ +TARGET = qeglfs-viv-wl-integration + +PLUGIN_TYPE = egldeviceintegrations +PLUGIN_CLASS_NAME = QEglFSVivWaylandIntegrationPlugin +load(qt_plugin) + +QT += core-private gui-private platformsupport-private eglfs_device_lib-private + +INCLUDEPATH += $$PWD/../.. +CONFIG += egl +DEFINES += LINUX=1 EGL_API_FB=1 +LIBS += -lGAL +QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF + +SOURCES += $$PWD/qeglfsvivwlmain.cpp \ + $$PWD/qeglfsvivwlintegration.cpp + +HEADERS += $$PWD/qeglfsvivwlintegration.h + +OTHER_FILES += $$PWD/eglfs_viv_wl.json + +CONFIG += link_pkgconfig +PKGCONFIG_PRIVATE += wayland-server diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.cpp new file mode 100644 index 0000000000..9eebcc772a --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.cpp @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qeglfsvivwlintegration.h" +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +void QEglFSVivWaylandIntegration::platformInit() +{ + QEGLDeviceIntegration::platformInit(); + + int width, height; + + bool multiBufferNotEnabledYet = qEnvironmentVariableIsEmpty("FB_MULTI_BUFFER"); + bool multiBuffer = qEnvironmentVariableIsEmpty("QT_EGLFS_IMX6_NO_FB_MULTI_BUFFER"); + if (multiBufferNotEnabledYet && multiBuffer) { + qWarning() << "QEglFSVivWaylandIntegration will set environment variable FB_MULTI_BUFFER=2 to enable double buffering and vsync.\n" + << "If this is not desired, you can override this via: export QT_EGLFS_IMX6_NO_FB_MULTI_BUFFER=1"; + qputenv("FB_MULTI_BUFFER", "2"); + } + + mWaylandDisplay = wl_display_create(); + mNativeDisplay = fbGetDisplay(mWaylandDisplay); + fbGetDisplayGeometry(mNativeDisplay, &width, &height); + mScreenSize.setHeight(height); + mScreenSize.setWidth(width); +} + +QSize QEglFSVivWaylandIntegration::screenSize() const +{ + return mScreenSize; +} + +EGLNativeDisplayType QEglFSVivWaylandIntegration::platformDisplay() const +{ + return mNativeDisplay; +} + +EGLNativeWindowType QEglFSVivWaylandIntegration::createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) +{ + Q_UNUSED(window) + Q_UNUSED(format) + + EGLNativeWindowType eglWindow = fbCreateWindow(mNativeDisplay, 0, 0, size.width(), size.height()); + return eglWindow; +} + +void QEglFSVivWaylandIntegration::destroyNativeWindow(EGLNativeWindowType window) +{ + fbDestroyWindow(window); +} + +void *QEglFSVivWaylandIntegration::wlDisplay() const +{ + return mWaylandDisplay; +} + + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.h new file mode 100644 index 0000000000..677a1b6337 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.h @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEGLFSVIVINTEGRATION_H +#define QEGLFSVIVINTEGRATION_H + +#include "qeglfsdeviceintegration.h" +struct wl_display; + +QT_BEGIN_NAMESPACE + +class QEglFSVivWaylandIntegration : public QEGLDeviceIntegration +{ +public: + void platformInit() Q_DECL_OVERRIDE; + QSize screenSize() const Q_DECL_OVERRIDE; + EGLNativeWindowType createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) Q_DECL_OVERRIDE; + void destroyNativeWindow(EGLNativeWindowType window) Q_DECL_OVERRIDE; + EGLNativeDisplayType platformDisplay() const Q_DECL_OVERRIDE; + + void *wlDisplay() const Q_DECL_OVERRIDE; +private: + QSize mScreenSize; + EGLNativeDisplayType mNativeDisplay; + wl_display *mWaylandDisplay; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlmain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlmain.cpp new file mode 100644 index 0000000000..a48aa08e40 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlmain.cpp @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qeglfsdeviceintegration.h" +#include "qeglfsvivwlintegration.h" + +QT_BEGIN_NAMESPACE + +class QEglFSVivWaylandIntegrationPlugin : public QEGLDeviceIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QEGLDeviceIntegrationFactoryInterface_iid FILE "eglfs_viv_wl.json") + +public: + QEGLDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSVivWaylandIntegration; } +}; + +QT_END_NAMESPACE + +#include "qeglfsvivwlmain.moc" diff --git a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp index 0c2aa7ad61..10c8091815 100644 --- a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp @@ -334,4 +334,9 @@ bool QEGLDeviceIntegration::supportsSurfacelessContexts() const return true; } +void *QEGLDeviceIntegration::wlDisplay() const +{ + return Q_NULLPTR; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h index d91d67de16..97082df7f5 100644 --- a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h +++ b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h @@ -97,6 +97,8 @@ public: virtual int framebufferIndex() const; virtual bool supportsPBuffers() const; virtual bool supportsSurfacelessContexts() const; + + virtual void *wlDisplay() const; }; class Q_EGLFS_EXPORT QEGLDeviceIntegrationPlugin : public QObject diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index 2df06caa6b..ac6bb34ff1 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -251,7 +251,8 @@ enum ResourceType { EglContext, EglConfig, NativeDisplay, - XlibDisplay + XlibDisplay, + WaylandDisplay }; static int resourceType(const QByteArray &key) @@ -262,7 +263,8 @@ static int resourceType(const QByteArray &key) QByteArrayLiteral("eglcontext"), QByteArrayLiteral("eglconfig"), QByteArrayLiteral("nativedisplay"), - QByteArrayLiteral("display") + QByteArrayLiteral("display"), + QByteArrayLiteral("wl_display") }; const QByteArray *end = names + sizeof(names) / sizeof(names[0]); const QByteArray *result = std::find(names, end, key); @@ -282,6 +284,9 @@ void *QEglFSIntegration::nativeResourceForIntegration(const QByteArray &resource case NativeDisplay: result = reinterpret_cast(nativeDisplay()); break; + case WaylandDisplay: + result = qt_egl_device_integration()->wlDisplay(); + break; default: break; } From dfaffcbf2a20cd7ff781de88ac3e73d9f17d1cdf Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Fri, 30 Oct 2015 15:09:55 +0100 Subject: [PATCH 093/133] QWindowsPipeReader: fix occasional "Unknown error 995" After canceling the asynchronous read operation, the notified() slot receives ERROR_OPERATION_ABORTED. We must not handle this situation as an error. This amends commit 5ce567c5. Task-number: QTBUG-48336 Change-Id: Iff948ceb3ad1f805a9de8c188fbc39ed4c76ba82 Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qwindowspipereader.cpp | 4 +++ .../socket/qlocalsocket/tst_qlocalsocket.cpp | 29 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/corelib/io/qwindowspipereader.cpp b/src/corelib/io/qwindowspipereader.cpp index c1f5d2aace..3200a70c94 100644 --- a/src/corelib/io/qwindowspipereader.cpp +++ b/src/corelib/io/qwindowspipereader.cpp @@ -186,6 +186,10 @@ void QWindowsPipeReader::notified(quint32 numberOfBytesRead, quint32 errorCode, case ERROR_PIPE_NOT_CONNECTED: pipeBroken = true; break; + case ERROR_OPERATION_ABORTED: + if (stopped) + break; + // fall through default: emit winError(errorCode, QLatin1String("QWindowsPipeReader::notified")); pipeBroken = true; diff --git a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp index 4881d86937..9130aff4e2 100644 --- a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp +++ b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp @@ -98,6 +98,7 @@ private slots: void removeServer(); void recycleServer(); + void recycleClientSocket(); void multiConnect(); void writeOnlySocket(); @@ -954,6 +955,34 @@ void tst_QLocalSocket::recycleServer() QVERIFY(server.nextPendingConnection() != 0); } +void tst_QLocalSocket::recycleClientSocket() +{ + const QByteArrayList lines = QByteArrayList() << "Have you heard of that new band" + << "\"1023 Megabytes\"?" + << "They haven't made it to a gig yet."; + QLocalServer server; + const QString serverName = QStringLiteral("recycleClientSocket"); + QVERIFY(server.listen(serverName)); + QLocalSocket client; + QSignalSpy clientReadyReadSpy(&client, SIGNAL(readyRead())); + QSignalSpy clientErrorSpy(&client, SIGNAL(error(QLocalSocket::LocalSocketError))); + for (int i = 0; i < lines.count(); ++i) { + client.abort(); + clientReadyReadSpy.clear(); + client.connectToServer(serverName); + QVERIFY(client.waitForConnected()); + QVERIFY(server.waitForNewConnection()); + QLocalSocket *serverSocket = server.nextPendingConnection(); + QVERIFY(serverSocket); + connect(serverSocket, &QLocalSocket::disconnected, &QLocalSocket::deleteLater); + serverSocket->write(lines.at(i)); + serverSocket->flush(); + QVERIFY(clientReadyReadSpy.wait()); + QCOMPARE(client.readAll(), lines.at(i)); + QVERIFY(clientErrorSpy.isEmpty()); + } +} + void tst_QLocalSocket::multiConnect() { QLocalServer server; From 8c5acf6573783fc0f9ca6e7301db52db6efc7741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20K=C3=BCmmel?= Date: Thu, 29 Oct 2015 14:59:59 +0100 Subject: [PATCH 094/133] configure: add link-time-optimization option Windows' configure.exe supports -ltcg since several years, this patch adds -ltcg to Unix's configure script. Change-Id: I3f39086c67c3f4cacd252f63de30e3cfc4aa22bb Reviewed-by: Oswald Buddenhagen --- configure | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/configure b/configure index f60802a9b5..8f4aa8206d 100755 --- a/configure +++ b/configure @@ -703,6 +703,7 @@ CFG_OPENSSL=auto CFG_LIBPROXY=auto CFG_SECURETRANSPORT=auto CFG_PRECOMPILE=auto +CFG_LTCG=no CFG_SEPARATE_DEBUG_INFO=no CFG_REDUCE_EXPORTS=auto CFG_SSE2=auto @@ -1573,6 +1574,13 @@ while [ "$#" -gt 0 ]; do UNKNOWN_OPT=yes fi ;; + ltcg) + if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then + CFG_LTCG="$VAL" + else + UNKNOWN_OPT=no + fi + ;; separate-debug-info) if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then CFG_SEPARATE_DEBUG_INFO="$VAL" @@ -2641,6 +2649,9 @@ Additional options: * -no-pch ............ Do not use precompiled header support. -pch ............... Use precompiled header support. + * -no-ltcg Do not use Link Time Code Generation + -ltcg Use Link Time Code Generation. + -no-dbus ........... Do not compile the Qt D-Bus module. + -dbus-linked ....... Compile the Qt D-Bus module and link to libdbus-1. -dbus-runtime ...... Compile the Qt D-Bus module and dynamically load libdbus-1. @@ -6476,6 +6487,10 @@ if [ "$CFG_FORCE_ASSERTS" = "yes" ]; then QT_CONFIG="$QT_CONFIG force_asserts" fi +if [ "$CFG_LTCG" = "yes" ]; then + QMAKE_CONFIG="$QMAKE_CONFIG ltcg" +fi + if [ "$CFG_SANITIZERS" != "none" ]; then QTCONFIG_CONFIG="$QTCONFIG_CONFIG sanitizer" @@ -7232,6 +7247,7 @@ echo " Using C++ standard ..... $CFG_STDCXX" echo " Using gold linker....... $CFG_USE_GOLD_LINKER" echo " Using new DTAGS ........ $CFG_ENABLE_NEW_DTAGS" echo " Using PCH .............. $CFG_PRECOMPILE" +echo " Using LTCG ............. $CFG_LTCG" echo " Target compiler supports:" if [ "$CFG_ARCH" = "i386" -o "$CFG_ARCH" = "x86_64" ]; then echo " SSE2/SSE3/SSSE3 ...... ${CFG_SSE2}/${CFG_SSE3}/${CFG_SSSE3}" From 1c9f53c4e55090be6db48962705a4e01db5b3109 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 2 Nov 2015 15:35:10 +0100 Subject: [PATCH 095/133] examples: remove use of obsolete QStyleOption*V typedefs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These are obsolete since Qt 5.0. Change-Id: I297477eff129558553f52a04bb7828d95db27969 Reviewed-by: Topi Reiniö --- examples/sql/books/bookdelegate.cpp | 2 +- examples/widgets/painting/shared/arthurstyle.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/sql/books/bookdelegate.cpp b/examples/sql/books/bookdelegate.cpp index ff965eda44..afc4edf434 100644 --- a/examples/sql/books/bookdelegate.cpp +++ b/examples/sql/books/bookdelegate.cpp @@ -44,7 +44,7 @@ void BookDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { if (index.column() != 5) { - QStyleOptionViewItemV3 opt = option; + QStyleOptionViewItem opt = option; opt.rect.adjust(0, 0, -1, -1); // since we draw the grid ourselves QSqlRelationalDelegate::paint(painter, opt, index); } else { diff --git a/examples/widgets/painting/shared/arthurstyle.cpp b/examples/widgets/painting/shared/arthurstyle.cpp index d246336c5d..f03c05881d 100644 --- a/examples/widgets/painting/shared/arthurstyle.cpp +++ b/examples/widgets/painting/shared/arthurstyle.cpp @@ -156,8 +156,8 @@ void ArthurStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *op break; case PE_FrameGroupBox: - if (const QStyleOptionFrameV2 *group - = qstyleoption_cast(option)) { + if (const QStyleOptionFrame *group + = qstyleoption_cast(option)) { const QRect &r = group->rect; painter->save(); From 595d6797beab5f4275b4e544c9683a99b48f4801 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 2 Nov 2015 15:39:47 +0100 Subject: [PATCH 096/133] widgets snippets: remove unreferenced snippets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They were using QStyleOption*V, which are all obsolete since Qt 5.0. Change-Id: I6a8a666cf18d52fcac8f305f38c8ef0843ec7bfd Reviewed-by: Topi Reiniö --- .../doc/snippets/qstyleoption/main.cpp | 33 ------------------- 1 file changed, 33 deletions(-) diff --git a/src/widgets/doc/snippets/qstyleoption/main.cpp b/src/widgets/doc/snippets/qstyleoption/main.cpp index aa4220d8ea..05d5ece33d 100644 --- a/src/widgets/doc/snippets/qstyleoption/main.cpp +++ b/src/widgets/doc/snippets/qstyleoption/main.cpp @@ -75,44 +75,11 @@ void MyPushButton::paintEvent(QPaintEvent *) class MyStyle : public QStyle { public: - MyStyle(); void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget); }; -MyStyle::MyStyle() -{ -//! [1] - QStyleOptionFrame *option; - - if (const QStyleOptionFrame *frameOption = - qstyleoption_cast(option)) { - QStyleOptionFrameV2 frameOptionV2(*frameOption); - - // draw the frame using frameOptionV2 - } -//! [1] - -//! [2] - if (const QStyleOptionProgressBar *progressBarOption = - qstyleoption_cast(option)) { - QStyleOptionProgressBarV2 progressBarV2(*progressBarOption); - - // draw the progress bar using progressBarV2 - } -//! [2] - -//! [3] - if (const QStyleOptionTab *tabOption = - qstyleoption_cast(option)) { - QStyleOptionTabV2 tabV2(*tabOption); - - // draw the tab using tabV2 - } -//! [3] -} - //! [4] void MyStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, From d2bb036d5083d95d1ab7bef53eac012f3520a633 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 2 Nov 2015 15:40:58 +0100 Subject: [PATCH 097/133] [docs] widgets: remove remaining references to QStyleOption*V They are all obsolete since Qt 5.0. Change-Id: Ie56b99ad470fddb87f277f3f4f3845764828d10a Reviewed-by: Jens Bache-Wiig --- src/widgets/doc/snippets/javastyle.cpp | 25 ++++++++----------- .../doc/src/widgets-and-layouts/styles.qdoc | 10 +++----- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/src/widgets/doc/snippets/javastyle.cpp b/src/widgets/doc/snippets/javastyle.cpp index b0b548e731..4997e25ada 100644 --- a/src/widgets/doc/snippets/javastyle.cpp +++ b/src/widgets/doc/snippets/javastyle.cpp @@ -236,9 +236,8 @@ void JavaStyle::drawControl(ControlElement control, const QStyleOption *option, break; } case CE_DockWidgetTitle: { - const QStyleOptionDockWidgetV2 *docker = - new QStyleOptionDockWidgetV2( - *qstyleoption_cast(option)); + const QStyleOptionDockWidget *docker = + qstyleoption_cast(option); QRect rect = docker->rect; QRect titleRect = rect; @@ -366,11 +365,9 @@ void JavaStyle::drawControl(ControlElement control, const QStyleOption *option, break; } case CE_ProgressBar: { - const QStyleOptionProgressBar *bar1 = + const QStyleOptionProgressBar *bar = qstyleoption_cast(option); - QStyleOptionProgressBarV2 *bar = new QStyleOptionProgressBarV2(*bar1); - QRect rect = bar->rect; if (bar->orientation == Qt::Vertical) { rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); @@ -416,7 +413,6 @@ void JavaStyle::drawControl(ControlElement control, const QStyleOption *option, if (bar->textVisible) drawControl(CE_ProgressBarLabel, &subBar, painter, widget); - delete bar; break; } case CE_ProgressBarGroove: { @@ -2366,18 +2362,17 @@ void JavaStyle::drawPrimitive(PrimitiveElement element, case PE_FrameLineEdit: { const QStyleOptionFrame *frame = qstyleoption_cast(option); - const QStyleOptionFrameV2 frameV2(*frame); painter->setPen(frame->palette.color(QPalette::Mid)); - painter->drawRect(frameV2.rect.adjusted(0, 0, -2, -2)); + painter->drawRect(frame->rect.adjusted(0, 0, -2, -2)); painter->setPen(Qt::white); - painter->drawRect(frameV2.rect.adjusted(1, 1, -1, -1)); - painter->setPen(frameV2.palette.color(QPalette::Active, + painter->drawRect(frame->rect.adjusted(1, 1, -1, -1)); + painter->setPen(frame->palette.color(QPalette::Active, QPalette::Background)); - painter->drawLine(frameV2.rect.bottomLeft(), - frameV2.rect.bottomLeft() + QPoint(1, -1)); - painter->drawLine(frameV2.rect.topRight(), - frameV2.rect.topRight() + QPoint(-1, 1)); + painter->drawLine(frame->rect.bottomLeft(), + frame->rect.bottomLeft() + QPoint(1, -1)); + painter->drawLine(frame->rect.topRight(), + frame->rect.topRight() + QPoint(-1, 1)); break; } case PE_FrameFocusRect: { diff --git a/src/widgets/doc/src/widgets-and-layouts/styles.qdoc b/src/widgets/doc/src/widgets-and-layouts/styles.qdoc index 0a5a079969..7d1bffd0b4 100644 --- a/src/widgets/doc/src/widgets-and-layouts/styles.qdoc +++ b/src/widgets/doc/src/widgets-and-layouts/styles.qdoc @@ -989,9 +989,7 @@ The style option for tabs (QStyleOptionTab) contains the necessary information for drawing tabs. The option contains the position of the tab in the tab bar, the position of the selected tab, the - shape of the tab, the text, and the icon. After Qt 4.1, the option - should be cast to a QStyleOptionTabV2, which also contains the - icon's size. + shape of the tab, the text, the icon, and the icon's size. As the Java style tabs don't overlap, we also present an image of a tab widget in the common style. Note that if you want the tabs @@ -1024,7 +1022,7 @@ Note that individual tabs may be disabled even if the tab bar is not. The tab will be active if the tab bar is active. - Here follows a table of QStyleOptionTabV2's members: + Here follows a table of QStyleOptionTab's members: \table 90% \header @@ -1450,7 +1448,7 @@ \li Content \row \li features - \li Flags of the QStyleOptionFrameV2::FrameFeatures + \li Flags of the QStyleOptionFrame::FrameFeatures enum describing the frame of the group box. \row \li lineWidth @@ -1501,7 +1499,7 @@ \image javastyle/progressbarimage.png - The style option for QProgressBar is QStyleOptionProgressBarV2. + The style option for QProgressBar is QStyleOptionProgressBar. The bar does not set any state flags, but the other members of the option are: From de50a6da9fb2d001eb64512612686ae77ce0d5dc Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 2 Nov 2015 16:12:44 +0100 Subject: [PATCH 098/133] bb10style: remove use of obsolete QStyleOption*V They are obsolete since Qt 5.0. Change-Id: I0f375b6dbc3def659d084e94081ad0e9dcfd1ca0 Reviewed-by: Rafael Roquetto --- src/plugins/styles/bb10style/qpixmapstyle.cpp | 27 +++++++------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/src/plugins/styles/bb10style/qpixmapstyle.cpp b/src/plugins/styles/bb10style/qpixmapstyle.cpp index 759f57eb1c..3090c42959 100644 --- a/src/plugins/styles/bb10style/qpixmapstyle.cpp +++ b/src/plugins/styles/bb10style/qpixmapstyle.cpp @@ -616,9 +616,9 @@ void QPixmapStyle::drawProgressBarBackground(const QStyleOption *option, QPainter *painter, const QWidget *) const { bool vertical = false; - if (const QStyleOptionProgressBarV2 *pb2 = - qstyleoption_cast(option)) { - vertical = (pb2->orientation == Qt::Vertical); + if (const QStyleOptionProgressBar *pb = + qstyleoption_cast(option)) { + vertical = pb->orientation == Qt::Vertical; } drawCachedPixmap(vertical ? PB_VBackground : PB_HBackground, option->rect, painter); } @@ -628,11 +628,7 @@ void QPixmapStyle::drawProgressBarLabel(const QStyleOption *option, { if (const QStyleOptionProgressBar *pb = qstyleoption_cast(option)) { - bool vertical = false; - if (const QStyleOptionProgressBarV2 *pb2 = - qstyleoption_cast(option)) { - vertical = (pb2->orientation == Qt::Vertical); - } + const bool vertical = pb->orientation == Qt::Vertical; if (!vertical) { QPalette::ColorRole textRole = QPalette::ButtonText; proxy()->drawItemText(painter, pb->rect, @@ -647,13 +643,8 @@ void QPixmapStyle::drawProgressBarFill(const QStyleOption *option, { const QStyleOptionProgressBar *pbar = qstyleoption_cast(option); - bool vertical = false; - bool flip = pbar->direction == Qt::RightToLeft; - if (const QStyleOptionProgressBarV2 *pb2 = - qstyleoption_cast(option)) { - vertical = (pb2->orientation == Qt::Vertical); - flip = flip ^ pb2->invertedAppearance; - } + const bool vertical = pbar->orientation == Qt::Vertical; + const bool flip = (pbar->direction == Qt::RightToLeft) ^ pbar->invertedAppearance; if (pbar->progress == pbar->maximum) { drawCachedPixmap(vertical ? PB_VComplete : PB_HComplete, option->rect, painter); @@ -801,9 +792,9 @@ QSize QPixmapStyle::progressBarSizeFromContents(const QStyleOption *option, const QWidget *widget) const { bool vertical = false; - if (const QStyleOptionProgressBarV2 *pb2 = - qstyleoption_cast(option)) { - vertical = (pb2->orientation == Qt::Vertical); + if (const QStyleOptionProgressBar *pb = + qstyleoption_cast(option)) { + vertical = pb->orientation == Qt::Vertical; } QSize result = QCommonStyle::sizeFromContents(CT_Slider, option, contentsSize, widget); if (vertical) { From 24c50f8dcf7fa61ac3c3d4d6295c259a104a2b8c Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Thu, 29 Oct 2015 11:39:14 +0100 Subject: [PATCH 099/133] Mirclient: Improved support for autotests Outside qmlscene, a window may be created before its size has been set. So check if the size is valid before using it. Also, allow an app to bypass the adjustment to the requested window size that is normally done in order to leave room for the system's status panel. Such adjustment does not make sense in the context of autotests, and would often cause false test failures. Change-Id: I1627a2e4c37c68ac61c4976be5b73045eb2bb989 Reviewed-by: Paul Olav Tvete --- src/plugins/platforms/mirclient/qmirclientwindow.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/mirclient/qmirclientwindow.cpp b/src/plugins/platforms/mirclient/qmirclientwindow.cpp index f3fd1e756d..3d1e5377e5 100644 --- a/src/plugins/platforms/mirclient/qmirclientwindow.cpp +++ b/src/plugins/platforms/mirclient/qmirclientwindow.cpp @@ -158,7 +158,7 @@ QMirClientWindow::QMirClientWindow(QWindow* w, QSharedPointerid = id++; // Use client geometry if set explicitly, use available screen geometry otherwise. - QPlatformWindow::setGeometry(window()->geometry() != screen->geometry() ? + QPlatformWindow::setGeometry(window()->geometry().isValid() && window()->geometry() != screen->geometry() ? window()->geometry() : screen->availableGeometry()); createWindow(); DLOG("QMirClientWindow::QMirClientWindow (this=%p, w=%p, screen=%p, input=%p)", this, w, screen, input); @@ -198,6 +198,8 @@ void QMirClientWindowPrivate::destroyEGLSurface() // we need to guess the panel height (3GU + 2DP) int QMirClientWindowPrivate::panelHeight() { + if (qEnvironmentVariableIsSet("QT_MIRCLIENT_IGNORE_PANEL")) + return 0; const int defaultGridUnit = 8; int gridUnit = defaultGridUnit; QByteArray gridUnitString = qgetenv("GRID_UNIT_PX"); From 0f68f8920573cdce1729a285a92ac8582df32841 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 27 Oct 2015 15:25:42 +0100 Subject: [PATCH 100/133] QtWidgets: Do hide/show via WA_OutsideWSRange for native widgets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a native widget has a width or height of 0 we don't have to invalidate its backing store as that is done by the window system. Certain applications rely on ... interesting ... behavior of certain window systems in this case. Task-number: QTBUG-48321 Change-Id: I78ef29975181ee22429c9bd4b11d96d9e68b7a9c Reviewed-by: Dmitry Shachnev Reviewed-by: Alexander Volkov Reviewed-by: Lisandro Damián Nicanor Pérez Meyer Reviewed-by: Paul Olav Tvete --- src/widgets/kernel/qwidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 773471533e..4286130521 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -7169,7 +7169,7 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) bool needsShow = false; - if (q->isWindow()) { + if (q->isWindow() || q->windowHandle()) { if (!(data.window_state & Qt::WindowFullScreen) && (w == 0 || h == 0)) { q->setAttribute(Qt::WA_OutsideWSRange, true); if (q->isVisible() && q->testAttribute(Qt::WA_Mapped)) From 115f303352df90a0ceeea2af167a8592da33cd82 Mon Sep 17 00:00:00 2001 From: Alejandro Exojo Date: Sat, 31 Oct 2015 13:17:02 +0100 Subject: [PATCH 101/133] Fix the closeEvent of the systray example on OS X MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The implementation of the close event handler requires handling the two close events that are received on OS X when the user quits through the application menu bar or the Command+Q shortcut. The first is an spontaneous event, and the second a non-spontaneous one with the window already closed. Change-Id: I24e3d3f0de4d631bd2d5616c85ce747f085691e0 Reviewed-by: Topi Reiniö --- examples/widgets/desktop/systray/doc/src/systray.qdoc | 6 +++++- examples/widgets/desktop/systray/window.cpp | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/examples/widgets/desktop/systray/doc/src/systray.qdoc b/examples/widgets/desktop/systray/doc/src/systray.qdoc index 074012b6a7..fa2dbb2721 100644 --- a/examples/widgets/desktop/systray/doc/src/systray.qdoc +++ b/examples/widgets/desktop/systray/doc/src/systray.qdoc @@ -173,7 +173,11 @@ We have reimplemented the QWidget::closeEvent() event handler to receive widget close events, showing the above message to the - users when they are closing the editor window. + users when they are closing the editor window. On OS X we need to + avoid showing the message and accepting the close event when the + user really intends to quit the application, that is, when the + user has triggered "Quit" in the menu bar or pressed the Command+Q + shortcut. In addition to the functions and slots discussed above, we have also implemented several convenience functions to simplify the diff --git a/examples/widgets/desktop/systray/window.cpp b/examples/widgets/desktop/systray/window.cpp index 931e443de7..d499f498af 100644 --- a/examples/widgets/desktop/systray/window.cpp +++ b/examples/widgets/desktop/systray/window.cpp @@ -102,6 +102,11 @@ void Window::setVisible(bool visible) //! [2] void Window::closeEvent(QCloseEvent *event) { +#ifdef Q_OS_OSX + if (!event->spontaneous() || !isVisible()) { + return; + } +#endif if (trayIcon->isVisible()) { QMessageBox::information(this, tr("Systray"), tr("The program will keep running in the " From 6a6c14626df1ccf7838f0b8dd82bc88a1c637d04 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 2 Nov 2015 12:28:35 +0100 Subject: [PATCH 102/133] Windows: Default to vertical hinting when high-dpi scaling is enabled Since hinted text layouts are not scalable, we should disable hinting by default when the high-dpi scaling is active. This is the Windows version of 0f7bc885aa7ae8cc3c448cc751aba4eba8c1c8b8, which solved the same issue for the fontconfig database. Change-Id: I48b5da5b045dec195fd257743175017f39cf9620 Reviewed-by: Paul Olav Tvete --- .../platforms/windows/qwindowsfontdatabase.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index 9531d30e06..c8eaccd956 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -40,6 +40,7 @@ #include #include +#include #include #include @@ -1100,8 +1101,11 @@ QFontEngine *QWindowsFontDatabase::fontEngine(const QByteArray &fontData, qreal QFontEngine *fontEngine = 0; #if !defined(QT_NO_DIRECTWRITE) - if (hintingPreference == QFont::PreferDefaultHinting - || hintingPreference == QFont::PreferFullHinting) + bool useDirectWrite = (hintingPreference == QFont::PreferNoHinting) + || (hintingPreference == QFont::PreferVerticalHinting) + || (QHighDpiScaling::isActive() && hintingPreference == QFont::PreferDefaultHinting); + + if (!useDirectWrite) #endif { GUID guid; @@ -1704,7 +1708,8 @@ QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request, #if !defined(QT_NO_DIRECTWRITE) bool useDirectWrite = (request.hintingPreference == QFont::PreferNoHinting) - || (request.hintingPreference == QFont::PreferVerticalHinting); + || (request.hintingPreference == QFont::PreferVerticalHinting) + || (QHighDpiScaling::isActive() && request.hintingPreference == QFont::PreferDefaultHinting); if (useDirectWrite && initDirectWrite(data.data())) { const QString fam = QString::fromWCharArray(lf.lfFaceName); const QString nameSubstitute = QWindowsFontEngineDirectWrite::fontNameSubstitute(fam); From 6ed957fd7fc748143093fa335d8b4506c3ea16fa Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Mon, 2 Nov 2015 15:42:58 +0100 Subject: [PATCH 103/133] fix MinGW ANGLE build glslang_tab.cpp was not created in the right subdirectory. This amends commit 69167189. Change-Id: I031499baa53b72a1923883c58eb5ddfc2a02789a Reviewed-by: Liang Qi Reviewed-by: Oswald Buddenhagen --- src/angle/src/compiler/translator.pro | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/angle/src/compiler/translator.pro b/src/angle/src/compiler/translator.pro index eebe41b09e..b40aa96319 100644 --- a/src/angle/src/compiler/translator.pro +++ b/src/angle/src/compiler/translator.pro @@ -170,8 +170,10 @@ flex.dependency_type = TYPE_C flex.variable_out = GENERATED_SOURCES QMAKE_EXTRA_COMPILERS += flex +defineReplace(myDirName) { return($$dirname(1)) } bison.commands = $$addGnuPath(bison) --no-lines --skeleton=yacc.c --defines=${QMAKE_FILE_OUT} \ - --output=${QMAKE_FILE_OUT_BASE}.cpp ${QMAKE_FILE_NAME} + --output=${QMAKE_FUNC_FILE_OUT_myDirName}$$QMAKE_DIR_SEP${QMAKE_FILE_OUT_BASE}.cpp \ + ${QMAKE_FILE_NAME} bison.output = $${BUILDSUBDIR}${QMAKE_FILE_BASE}_tab.h bison.input = BISON_SOURCES bison.dependency_type = TYPE_C From 358715acc987c84316dd95a9567e37f99a44b302 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 3 Nov 2015 13:12:19 +0100 Subject: [PATCH 104/133] Fix build with Xcode 7.1 toolchain Change-Id: Iab8111e4d3fd7ce68aae35eb6c0b600262ba3f10 Reviewed-by: Simon Hausmann --- tests/auto/other/macgui/guitest.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/auto/other/macgui/guitest.cpp b/tests/auto/other/macgui/guitest.cpp index 1ddd0ca870..dee7ace1b9 100644 --- a/tests/auto/other/macgui/guitest.cpp +++ b/tests/auto/other/macgui/guitest.cpp @@ -145,7 +145,9 @@ namespace NativeEvents { CGEventType mouseDownType = (buttons & Qt::LeftButton) ? kCGEventLeftMouseDown : (buttons & Qt::RightButton) ? kCGEventRightMouseDown : kCGEventOtherMouseDown; - CGMouseButton mouseButton = mouseDownType == kCGEventOtherMouseDown ? kCGMouseButtonCenter : kCGEventLeftMouseDown; + // The mouseButton argument to CGEventCreateMouseEvent() is ignored unless the type + // is kCGEventOtherMouseDown, so defaulting to kCGMouseButtonLeft is fine. + CGMouseButton mouseButton = mouseDownType == kCGEventOtherMouseDown ? kCGMouseButtonCenter : kCGMouseButtonLeft; CGEventRef mouseEvent = CGEventCreateMouseEvent(NULL, mouseDownType, position, mouseButton); CGEventPost(kCGHIDEventTap, mouseEvent); From b825c702ac6111b1bedc8fcebee53b6aab289a67 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Mon, 2 Nov 2015 21:30:07 +0100 Subject: [PATCH 105/133] Blacklist tst_QPrinter::doubleSidedPrinting for msvc 2013 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This test keeps on failing on Windows 8 with 32 bit. Let's add the platform despite this one test failing. Change-Id: Id6a2b3e0b587d3cff29d1f616d5edacfcf68746d Reviewed-by: Jędrzej Nowacki --- tests/auto/printsupport/kernel/qprinter/BLACKLIST | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 tests/auto/printsupport/kernel/qprinter/BLACKLIST diff --git a/tests/auto/printsupport/kernel/qprinter/BLACKLIST b/tests/auto/printsupport/kernel/qprinter/BLACKLIST new file mode 100644 index 0000000000..250a18787c --- /dev/null +++ b/tests/auto/printsupport/kernel/qprinter/BLACKLIST @@ -0,0 +1,3 @@ +[doubleSidedPrinting] +windows 32bit msvc-2013 + From 5bb679590ea72372b80d83267935f45c8864a15e Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Tue, 3 Nov 2015 14:54:04 +0100 Subject: [PATCH 106/133] Rename "wl_display" native resource There is already a "wl_display" resource used by the client-side Wayland plugin. This is confusing, and would cause horrible bugs if ever a Wayland server was run as a client (the nested compositor usecase). Therefore, use "server_wl_display" for the name of the resource to be used on the server side. Change-Id: I30455177a154e89b98ad3620b6a14626b821e54c Reviewed-by: Giulio Camuffo --- src/plugins/platforms/eglfs/qeglfsintegration.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index ac6bb34ff1..2086ce56e2 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -264,7 +264,7 @@ static int resourceType(const QByteArray &key) QByteArrayLiteral("eglconfig"), QByteArrayLiteral("nativedisplay"), QByteArrayLiteral("display"), - QByteArrayLiteral("wl_display") + QByteArrayLiteral("server_wl_display") }; const QByteArray *end = names + sizeof(names) / sizeof(names[0]); const QByteArray *result = std::find(names, end, key); From 60bb802598bf42c188574f6287038d2d3e7580b7 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Fri, 30 Oct 2015 15:52:55 +0100 Subject: [PATCH 107/133] Doc: replaced mentions of deprecated function setDefaultCaCertificates() --> QSslConfiguration::defaultConfiguration().setCaCertificates() Task-number: QTBUG-49119 Change-Id: I0b53165fe658bb7e459ad7a5960210fc6c91b916 Reviewed-by: Venugopal Shivashankar --- src/network/ssl/qsslsocket.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 788e59df24..805adc734f 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -131,19 +131,18 @@ before the handshake phase with setLocalCertificate() and setPrivateKey(). \li The CA certificate database can be extended and customized with - addCaCertificate(), addCaCertificates(), setCaCertificates(), - addDefaultCaCertificate(), addDefaultCaCertificates(), and - setDefaultCaCertificates(). + addCaCertificate(), addCaCertificates(), addDefaultCaCertificate(), + addDefaultCaCertificates(), and QSslConfiguration::defaultConfiguration().setCaCertificates(). \endlist \note If available, root certificates on Unix (excluding OS X) will be - loaded on demand from the standard certificate directories. If - you do not want to load root certificates on demand, you need to call either - the static function setDefaultCaCertificates() before the first SSL handshake - is made in your application, (e.g. via - "QSslSocket::setDefaultCaCertificates(QSslSocket::systemCaCertificates());"), - or call setCaCertificates() on your QSslSocket instance prior to the SSL - handshake. + loaded on demand from the standard certificate directories. If you do not + want to load root certificates on demand, you need to call either + QSslConfiguration::defaultConfiguration().setCaCertificates() before the first + SSL handshake is made in your application (for example, via passing + QSslSocket::systemCaCertificates() to it), or call + QSslConfiguration::defaultConfiguration()::setCaCertificates() on your QSslSocket instance + prior to the SSL handshake. For more information about ciphers and certificates, refer to QSslCipher and QSslCertificate. From 99d1969284dba08c68a5153a64b17aa160afd51f Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 2 Nov 2015 16:42:21 +0100 Subject: [PATCH 108/133] tests: remove use of obsolete QStyleOption*V They are obsolete since Qt 5.0. Change-Id: Iefe47684526832def8fc5be5a170817059dcc530 Reviewed-by: Jake Petroules --- .../itemviews/qlistview/tst_qlistview.cpp | 3 +-- .../itemviews/qtreeview/tst_qtreeview.cpp | 19 +++++++++---------- .../styles/qstyleoption/tst_qstyleoption.cpp | 16 ---------------- .../qstylesheetstyle/tst_qstylesheetstyle.cpp | 4 ++-- .../widgets/qprogressbar/tst_qprogressbar.cpp | 2 +- 5 files changed, 13 insertions(+), 31 deletions(-) diff --git a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp index d94a3c8bca..5b206af357 100644 --- a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp +++ b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp @@ -2020,8 +2020,7 @@ void tst_QListView::styleOptionViewItem() public: void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { - QVERIFY(qstyleoption_cast(&option)); - QStyleOptionViewItemV4 opt(option); + QStyleOptionViewItem opt(option); initStyleOption(&opt, index); QCOMPARE(opt.index, index); diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index 6d5f5a1c60..033464c9db 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -3075,7 +3075,7 @@ void tst_QTreeView::styleOptionViewItem() { class MyDelegate : public QStyledItemDelegate { - static QString posToString(QStyleOptionViewItemV4::ViewItemPosition pos) { + static QString posToString(QStyleOptionViewItem::ViewItemPosition pos) { static const char* s_pos[] = { "Invalid", "Beginning", "Middle", "End", "OnlyOne" }; return s_pos[pos]; } @@ -3088,8 +3088,7 @@ void tst_QTreeView::styleOptionViewItem() void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const { - QVERIFY(qstyleoption_cast(&option)); - QStyleOptionViewItemV4 opt(option); + QStyleOptionViewItem opt(option); initStyleOption(&opt, index); QVERIFY(!opt.text.isEmpty()); @@ -3097,20 +3096,20 @@ void tst_QTreeView::styleOptionViewItem() //qDebug() << index << opt.text; if (allCollapsed) - QCOMPARE(!(opt.features & QStyleOptionViewItemV2::Alternate), !(index.row() % 2)); - QCOMPARE(!(opt.features & QStyleOptionViewItemV2::HasCheckIndicator), !opt.text.contains("Checkable")); + QCOMPARE(!(opt.features & QStyleOptionViewItem::Alternate), !(index.row() % 2)); + QCOMPARE(!(opt.features & QStyleOptionViewItem::HasCheckIndicator), !opt.text.contains("Checkable")); if (opt.text.contains("Beginning")) - QCOMPARE(posToString(opt.viewItemPosition), posToString(QStyleOptionViewItemV4::Beginning)); + QCOMPARE(posToString(opt.viewItemPosition), posToString(QStyleOptionViewItem::Beginning)); if (opt.text.contains("Middle")) - QCOMPARE(posToString(opt.viewItemPosition), posToString(QStyleOptionViewItemV4::Middle)); + QCOMPARE(posToString(opt.viewItemPosition), posToString(QStyleOptionViewItem::Middle)); if (opt.text.contains("End")) - QCOMPARE(posToString(opt.viewItemPosition), posToString(QStyleOptionViewItemV4::End)); + QCOMPARE(posToString(opt.viewItemPosition), posToString(QStyleOptionViewItem::End)); if (opt.text.contains("OnlyOne")) - QCOMPARE(posToString(opt.viewItemPosition), posToString(QStyleOptionViewItemV4::OnlyOne)); + QCOMPARE(posToString(opt.viewItemPosition), posToString(QStyleOptionViewItem::OnlyOne)); if (opt.text.contains("Checked")) QCOMPARE(opt.checkState, Qt::Checked); @@ -4192,7 +4191,7 @@ void tst_QTreeView::taskQTBUG_25333_adjustViewOptionsForIndex() #ifdef QT_BUILD_INTERNAL { - QStyleOptionViewItemV4 option; + QStyleOptionViewItem option; view.aiv_priv()->adjustViewOptionsForIndex(&option, model.indexFromItem(item1)); diff --git a/tests/auto/widgets/styles/qstyleoption/tst_qstyleoption.cpp b/tests/auto/widgets/styles/qstyleoption/tst_qstyleoption.cpp index 3c1d4c589b..2e26ba609b 100644 --- a/tests/auto/widgets/styles/qstyleoption/tst_qstyleoption.cpp +++ b/tests/auto/widgets/styles/qstyleoption/tst_qstyleoption.cpp @@ -43,7 +43,6 @@ class tst_QStyleOption: public QObject private slots: void qstyleoptioncast_data(); void qstyleoptioncast(); - void copyconstructors(); }; // Just a simple container for QStyleOption-pointer @@ -133,21 +132,6 @@ void tst_QStyleOption::qstyleoptioncast() delete testOption; } -void tst_QStyleOption::copyconstructors() -{ - QStyleOptionFrame frame; - QStyleOptionFrameV2 frame2(frame); - QCOMPARE(frame2.version, int(QStyleOptionFrameV2::Version)); - frame2 = frame; - QCOMPARE(frame2.version, int(QStyleOptionFrameV2::Version)); - - QStyleOptionProgressBar bar; - QStyleOptionProgressBarV2 bar2(bar); - QCOMPARE(bar2.version, int(QStyleOptionProgressBarV2::Version)); - bar2 = bar; - QCOMPARE(bar2.version, int(QStyleOptionProgressBarV2::Version)); -} - QTEST_MAIN(tst_QStyleOption) #include "tst_qstyleoption.moc" diff --git a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp index a511e91e2c..a360803c50 100644 --- a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp +++ b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp @@ -1301,9 +1301,9 @@ void tst_QStyleSheetStyle::proxyStyle() QTest::qWait(100); // Test for QTBUG-7198 - style sheet overrides custom element size - QStyleOptionViewItemV4 opt; + QStyleOptionViewItem opt; opt.initFrom(w); - opt.features |= QStyleOptionViewItemV2::HasCheckIndicator; + opt.features |= QStyleOptionViewItem::HasCheckIndicator; QVERIFY(pb5->style()->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &opt, pb5).width() == 3); delete w; diff --git a/tests/auto/widgets/widgets/qprogressbar/tst_qprogressbar.cpp b/tests/auto/widgets/widgets/qprogressbar/tst_qprogressbar.cpp index 4a5f9d535b..5455ebb830 100644 --- a/tests/auto/widgets/widgets/qprogressbar/tst_qprogressbar.cpp +++ b/tests/auto/widgets/widgets/qprogressbar/tst_qprogressbar.cpp @@ -267,7 +267,7 @@ void tst_QProgressBar::sizeHint() //test if the sizeHint is big enough QFontMetrics fm = bar.fontMetrics(); - QStyleOptionProgressBarV2 opt; + QStyleOptionProgressBar opt; bar.initStyleOption(&opt); QSize size = QSize(9 * 7 + fm.width(QLatin1Char('0')) * 4, fm.height() + 8); size= bar.style()->sizeFromContents(QStyle::CT_ProgressBar, &opt, size, &bar); From ad0bc42d00c28593237339081a029ce820da0259 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 2 Nov 2015 16:42:21 +0100 Subject: [PATCH 109/133] QStyleSheetStyle: remove use of obsolete QStyleOption*V They are obsolete since Qt 5.0. Change-Id: I3bf9926fada136dda7406dc5f7b8edb3c71b55a9 Reviewed-by: Jake Petroules Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/widgets/styles/qstylesheetstyle.cpp | 32 ++++++++++++------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 380b2b3939..d3f667748e 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -1958,24 +1958,24 @@ QRenderRule QStyleSheetStyle::renderRule(const QObject *obj, const QStyleOption } #endif // QT_NO_TOOLBAR #ifndef QT_NO_TOOLBOX - else if (const QStyleOptionToolBoxV2 *tab = qstyleoption_cast(opt)) { - if (tab->position == QStyleOptionToolBoxV2::OnlyOneTab) + else if (const QStyleOptionToolBox *tb = qstyleoption_cast(opt)) { + if (tb->position == QStyleOptionToolBox::OnlyOneTab) extraClass |= PseudoClass_OnlyOne; - else if (tab->position == QStyleOptionToolBoxV2::Beginning) + else if (tb->position == QStyleOptionToolBox::Beginning) extraClass |= PseudoClass_First; - else if (tab->position == QStyleOptionToolBoxV2::End) + else if (tb->position == QStyleOptionToolBox::End) extraClass |= PseudoClass_Last; - else if (tab->position == QStyleOptionToolBoxV2::Middle) + else if (tb->position == QStyleOptionToolBox::Middle) extraClass |= PseudoClass_Middle; - if (tab->selectedPosition == QStyleOptionToolBoxV2::NextIsSelected) + if (tb->selectedPosition == QStyleOptionToolBox::NextIsSelected) extraClass |= PseudoClass_NextSelected; - else if (tab->selectedPosition == QStyleOptionToolBoxV2::PreviousIsSelected) + else if (tb->selectedPosition == QStyleOptionToolBox::PreviousIsSelected) extraClass |= PseudoClass_PreviousSelected; } #endif // QT_NO_TOOLBOX #ifndef QT_NO_DOCKWIDGET - else if (const QStyleOptionDockWidgetV2 *dw = qstyleoption_cast(opt)) { + else if (const QStyleOptionDockWidget *dw = qstyleoption_cast(opt)) { if (dw->verticalTitleBar) extraClass |= PseudoClass_Vertical; else @@ -3807,7 +3807,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q case CE_ProgressBarContents: { QRenderRule subRule = renderRule(w, opt, PseudoElement_ProgressBarChunk); if (subRule.hasDrawable()) { - if (const QStyleOptionProgressBarV2 *pb = qstyleoption_cast(opt)) { + if (const QStyleOptionProgressBar *pb = qstyleoption_cast(opt)) { p->save(); p->setClipRect(pb->rect); @@ -3888,12 +3888,12 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q break; case CE_ProgressBarLabel: - if (const QStyleOptionProgressBarV2 *pb = qstyleoption_cast(opt)) { + if (const QStyleOptionProgressBar *pb = qstyleoption_cast(opt)) { if (rule.hasBox() || rule.hasBorder() || hasStyleRule(w, PseudoElement_ProgressBarChunk)) { drawItemText(p, pb->rect, pb->textAlignment | Qt::TextSingleLine, pb->palette, pb->state & State_Enabled, pb->text, QPalette::Text); } else { - QStyleOptionProgressBarV2 pbCopy(*pb); + QStyleOptionProgressBar pbCopy(*pb); rule.configurePalette(&pbCopy.palette, QPalette::HighlightedText, QPalette::Highlight); baseStyle()->drawControl(ce, &pbCopy, p, w); } @@ -4016,13 +4016,13 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q case CE_TabBarTabLabel: case CE_TabBarTabShape: if (const QStyleOptionTab *tab = qstyleoption_cast(opt)) { - QStyleOptionTabV3 tabCopy(*tab); QRenderRule subRule = renderRule(w, opt, PseudoElement_TabBarTab); QRect r = positionRect(w, subRule, PseudoElement_TabBarTab, opt->rect, opt->direction); if (ce == CE_TabBarTabShape && subRule.hasDrawable()) { subRule.drawRule(p, r); return; } + QStyleOptionTab tabCopy(*tab); subRule.configurePalette(&tabCopy.palette, QPalette::WindowText, QPalette::Window); QFont oldFont = p->font(); if (subRule.hasFont) @@ -4050,14 +4050,14 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q break; case CE_DockWidgetTitle: - if (const QStyleOptionDockWidgetV2 *dwOpt = qstyleoption_cast(opt)) { + if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast(opt)) { QRenderRule subRule = renderRule(w, opt, PseudoElement_DockWidgetTitle); if (!subRule.hasDrawable() && !subRule.hasPosition()) break; if (subRule.hasDrawable()) { subRule.drawRule(p, opt->rect); } else { - QStyleOptionDockWidgetV2 dwCopy(*dwOpt); + QStyleOptionDockWidget dwCopy(*dwOpt); dwCopy.title = QString(); baseStyle()->drawControl(ce, &dwCopy, p, w); } @@ -4393,7 +4393,7 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op QRenderRule subRule = renderRule(w, opt, PseudoElement_TabWidgetPane); if (subRule.hasNativeBorder()) { subRule.drawBackground(p, opt->rect); - QStyleOptionTabWidgetFrameV2 frmCopy(*frm); + QStyleOptionTabWidgetFrame frmCopy(*frm); subRule.configurePalette(&frmCopy.palette, QPalette::WindowText, QPalette::Window); baseStyle()->drawPrimitive(pe, &frmCopy, p, w); } else { @@ -5709,7 +5709,7 @@ QRect QStyleSheetStyle::subElementRect(SubElement se, const QStyleOption *opt, c case SE_ProgressBarGroove: case SE_ProgressBarContents: case SE_ProgressBarLabel: - if (const QStyleOptionProgressBarV2 *pb = qstyleoption_cast(opt)) { + if (const QStyleOptionProgressBar *pb = qstyleoption_cast(opt)) { if (rule.hasBox() || !rule.hasNativeBorder() || rule.hasPosition() || hasStyleRule(w, PseudoElement_ProgressBarChunk)) { if (se == SE_ProgressBarGroove) return rule.borderRect(pb->rect); From dbb013d98429f9eed399392da979e42759875db3 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 3 Nov 2015 13:54:19 +0100 Subject: [PATCH 110/133] QDockAreaLayoutInfo::updateTabBar(): Save and restore current index. When rebuilding the tab bar after hiding several dock widgets, the index gets offset. Task-number: QTBUG-49045 Change-Id: I05f6a976ca1d8c6f7cdf6532f1a728483398eabc Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/widgets/widgets/qdockarealayout.cpp | 5 +++ .../widgets/qdockwidget/tst_qdockwidget.cpp | 40 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp index 0a00086138..06c20adb9d 100644 --- a/src/widgets/widgets/qdockarealayout.cpp +++ b/src/widgets/widgets/qdockarealayout.cpp @@ -2105,6 +2105,8 @@ bool QDockAreaLayoutInfo::updateTabBar() const const QSignalBlocker blocker(tabBar); bool gap = false; + const quintptr oldCurrentId = currentTabId(); + int tab_idx = 0; for (int i = 0; i < item_list.count(); ++i) { const QDockAreaLayoutItem &item = item_list.at(i); @@ -2153,6 +2155,9 @@ bool QDockAreaLayoutInfo::updateTabBar() const tabBar->removeTab(tab_idx); } + if (oldCurrentId > 0 && currentTabId() != oldCurrentId) + that->setCurrentTabId(oldCurrentId); + //returns if the tabbar is visible or not return ( (gap ? 1 : 0) + tabBar->count()) > 1; } diff --git a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp index 82832bced1..70df31ed69 100644 --- a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp +++ b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include "private/qdockwidget_p.h" @@ -68,6 +69,7 @@ private slots: void allowedAreas(); void toggleViewAction(); void visibilityChanged(); + void updateTabBarOnVisibilityChanged(); void dockLocationChanged(); void setTitleBarWidget(); void titleBarDoubleClick(); @@ -586,6 +588,44 @@ void tst_QDockWidget::visibilityChanged() QCOMPARE(spy.at(0).at(0).toBool(), true); } +void tst_QDockWidget::updateTabBarOnVisibilityChanged() +{ + // QTBUG49045: Populate tabified dock area with 4 widgets, set the tab + // index to 2 (dw2), hide dw0, dw1 and check that the tab index is 0 (dw3). + QMainWindow mw; + mw.setMinimumSize(400, 400); + mw.setWindowTitle(QTest::currentTestFunction()); + QDockWidget *dw0 = new QDockWidget("d1", &mw); + dw0->setAllowedAreas(Qt::LeftDockWidgetArea); + mw.addDockWidget(Qt::LeftDockWidgetArea, dw0); + QDockWidget *dw1 = new QDockWidget("d2", &mw); + dw1->setAllowedAreas(Qt::LeftDockWidgetArea); + mw.addDockWidget(Qt::LeftDockWidgetArea, dw1); + QDockWidget *dw2 = new QDockWidget("d3", &mw); + dw2->setAllowedAreas(Qt::LeftDockWidgetArea); + mw.addDockWidget(Qt::LeftDockWidgetArea, dw2); + QDockWidget *dw3 = new QDockWidget("d4", &mw); + dw3->setAllowedAreas(Qt::LeftDockWidgetArea); + mw.addDockWidget(Qt::LeftDockWidgetArea, dw3); + mw.tabifyDockWidget(dw0, dw1); + mw.tabifyDockWidget(dw1, dw2); + mw.tabifyDockWidget(dw2, dw3); + + QTabBar *tabBar = mw.findChild(); + QVERIFY(tabBar); + tabBar->setCurrentIndex(2); + + mw.show(); + QVERIFY(QTest::qWaitForWindowExposed(&mw)); + + QCOMPARE(tabBar->currentIndex(), 2); + + dw0->hide(); + dw1->hide(); + QTRY_COMPARE(tabBar->count(), 2); + QCOMPARE(tabBar->currentIndex(), 0); +} + Q_DECLARE_METATYPE(Qt::DockWidgetArea) void tst_QDockWidget::dockLocationChanged() From 4f8c75acbd7598ee5664b558293fb542817e0091 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Mon, 2 Nov 2015 08:26:39 +0400 Subject: [PATCH 111/133] Update bundled HarfBuzz-NG to 1.0.6 - Unicode 8.0 support - Universal Shaping Engine - Various fixes, improvements, optimizations, etc. Change-Id: Ib6f8c92fa275c2a6575b9ae09068c92aecac7b4e Reviewed-by: Lars Knoll Reviewed-by: Eskil Abrahamsen Blomfeldt --- config.tests/unix/harfbuzz/harfbuzz.cpp | 2 +- src/3rdparty/harfbuzz-ng/NEWS | 115 +++ src/3rdparty/harfbuzz-ng/README | 1 + src/3rdparty/harfbuzz-ng/config.h | 47 ++ src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro | 11 +- .../harfbuzz-ng/src/hb-atomic-private.hh | 102 +-- src/3rdparty/harfbuzz-ng/src/hb-blob.cc | 24 +- .../src/hb-buffer-deserialize-text.hh | 4 +- .../harfbuzz-ng/src/hb-buffer-private.hh | 14 +- .../harfbuzz-ng/src/hb-buffer-serialize.cc | 33 +- src/3rdparty/harfbuzz-ng/src/hb-buffer.cc | 219 ++++-- src/3rdparty/harfbuzz-ng/src/hb-buffer.h | 28 +- src/3rdparty/harfbuzz-ng/src/hb-common.cc | 47 +- src/3rdparty/harfbuzz-ng/src/hb-common.h | 10 + src/3rdparty/harfbuzz-ng/src/hb-coretext.cc | 106 ++- src/3rdparty/harfbuzz-ng/src/hb-face.cc | 40 +- .../harfbuzz-ng/src/hb-font-private.hh | 2 +- src/3rdparty/harfbuzz-ng/src/hb-font.cc | 126 ++-- src/3rdparty/harfbuzz-ng/src/hb-font.h | 35 +- .../harfbuzz-ng/src/hb-mutex-private.hh | 10 +- .../harfbuzz-ng/src/hb-object-private.hh | 34 +- .../harfbuzz-ng/src/hb-open-file-private.hh | 20 +- .../harfbuzz-ng/src/hb-open-type-private.hh | 116 +-- .../harfbuzz-ng/src/hb-ot-cmap-table.hh | 56 +- src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc | 108 ++- src/3rdparty/harfbuzz-ng/src/hb-ot-font.h | 4 + .../harfbuzz-ng/src/hb-ot-glyf-table.hh | 104 +++ .../harfbuzz-ng/src/hb-ot-head-table.hh | 5 +- .../harfbuzz-ng/src/hb-ot-hhea-table.hh | 2 +- .../harfbuzz-ng/src/hb-ot-hmtx-table.hh | 2 +- .../src/hb-ot-layout-common-private.hh | 110 +-- .../src/hb-ot-layout-gdef-table.hh | 44 +- .../src/hb-ot-layout-gpos-table.hh | 331 +++++---- .../src/hb-ot-layout-gsub-table.hh | 311 ++++---- .../src/hb-ot-layout-gsubgpos-private.hh | 279 ++++--- .../src/hb-ot-layout-jstf-table.hh | 35 +- .../harfbuzz-ng/src/hb-ot-layout-private.hh | 45 +- src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc | 77 +- .../harfbuzz-ng/src/hb-ot-map-private.hh | 7 +- src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc | 10 + .../harfbuzz-ng/src/hb-ot-maxp-table.hh | 5 +- .../harfbuzz-ng/src/hb-ot-name-table.hh | 14 +- .../hb-ot-shape-complex-arabic-fallback.hh | 6 +- .../src/hb-ot-shape-complex-arabic-private.hh | 50 ++ .../src/hb-ot-shape-complex-arabic-table.hh | 26 +- .../src/hb-ot-shape-complex-arabic.cc | 39 +- .../src/hb-ot-shape-complex-hangul.cc | 13 +- .../src/hb-ot-shape-complex-indic-private.hh | 2 - .../src/hb-ot-shape-complex-indic.cc | 141 ++-- .../src/hb-ot-shape-complex-myanmar.cc | 77 +- .../src/hb-ot-shape-complex-private.hh | 145 ++-- .../src/hb-ot-shape-complex-sea-machine.hh | 224 ------ .../src/hb-ot-shape-complex-sea.cc | 380 ---------- .../src/hb-ot-shape-complex-thai.cc | 4 +- .../src/hb-ot-shape-complex-use-machine.hh | 548 ++++++++++++++ .../src/hb-ot-shape-complex-use-private.hh | 97 +++ .../src/hb-ot-shape-complex-use-table.cc | 696 ++++++++++++++++++ .../src/hb-ot-shape-complex-use.cc | 585 +++++++++++++++ .../harfbuzz-ng/src/hb-ot-shape-fallback.cc | 9 +- .../harfbuzz-ng/src/hb-ot-shape-normalize.cc | 50 +- src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc | 207 ++++-- src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc | 40 +- src/3rdparty/harfbuzz-ng/src/hb-private.hh | 122 ++- .../harfbuzz-ng/src/hb-set-private.hh | 11 +- src/3rdparty/harfbuzz-ng/src/hb-set.cc | 52 +- src/3rdparty/harfbuzz-ng/src/hb-set.h | 3 + src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc | 36 +- src/3rdparty/harfbuzz-ng/src/hb-shape.cc | 85 ++- src/3rdparty/harfbuzz-ng/src/hb-shape.h | 3 - src/3rdparty/harfbuzz-ng/src/hb-shaper.cc | 2 +- .../harfbuzz-ng/src/hb-unicode-private.hh | 2 +- src/3rdparty/harfbuzz-ng/src/hb-unicode.cc | 33 +- src/3rdparty/harfbuzz-ng/src/hb-unicode.h | 41 +- src/3rdparty/harfbuzz-ng/src/hb-version.h | 8 +- src/3rdparty/harfbuzz-ng/src/hb-warning.cc | 24 +- 75 files changed, 4354 insertions(+), 2102 deletions(-) create mode 100644 src/3rdparty/harfbuzz-ng/config.h create mode 100644 src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh create mode 100644 src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-private.hh delete mode 100644 src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea-machine.hh delete mode 100644 src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea.cc create mode 100644 src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-machine.hh create mode 100644 src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-private.hh create mode 100644 src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-table.cc create mode 100644 src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use.cc diff --git a/config.tests/unix/harfbuzz/harfbuzz.cpp b/config.tests/unix/harfbuzz/harfbuzz.cpp index bbaa9fc14d..1e6f7e70d6 100644 --- a/config.tests/unix/harfbuzz/harfbuzz.cpp +++ b/config.tests/unix/harfbuzz/harfbuzz.cpp @@ -33,7 +33,7 @@ #include -#if !HB_VERSION_ATLEAST(0, 9, 31) +#if !HB_VERSION_ATLEAST(0, 9, 42) # error "This version of harfbuzz is too old." #endif diff --git a/src/3rdparty/harfbuzz-ng/NEWS b/src/3rdparty/harfbuzz-ng/NEWS index c4950e2620..f2b0a32401 100644 --- a/src/3rdparty/harfbuzz-ng/NEWS +++ b/src/3rdparty/harfbuzz-ng/NEWS @@ -1,3 +1,118 @@ +Overview of changes leading to 1.0.6 +Thursday, October 15, 2015 +==================================== + +- Reduce max nesting level in OT lookups from 8 to 6. + Should not affect any real font as far as I know. +- Fix memory access issue in ot-font. +- Revert default load-flags of fonts created using hb_ft_font_create() + back to FT_LOAD_DEFAULT|FT_LOAD_NO_HINTING. This was changed in + last release (1.0.5), but caused major issues, so revert. + https://github.com/behdad/harfbuzz/issues/143 + + +Overview of changes leading to 1.0.5 +Tuesday, October 13, 2015 +==================================== + +- Fix multiple memory access bugs discovered using libFuzzer. + https://github.com/behdad/harfbuzz/issues/139 + Everyone should upgrade to this version as soon as possible. + We now have continuous fuzzing set up, to avoid issues like + these creeping in again. +- Misc fixes. + +- New API: + * hb_font_set_parent(). + * hb_ft_font_[sg]et_load_flags() + The default flags for fonts created using hb_ft_font_create() + has changed to default to FT_LOAD_DEFAULT now. Previously it + was defaulting to FT_LOAD_DFEAULT|FT_LOAD_NO_HINTING. + +- API changes: + * Fonts now default to units-per-EM as their scale, instead of 0. + * hb_font_create_sub_font() does NOT make parent font immutable + anymore. hb_font_make_immutable() does. + + +Overview of changes leading to 1.0.4 +Wednesday, September 30, 2015 +==================================== + +- Fix minor out-of-bounds read error. + + +Overview of changes leading to 1.0.3 +Tuesday, September 1, 2015 +==================================== + +- Start of user documentation, from Simon Cozens! +- Implement glyph_extents() for TrueType fonts in hb-ot-font. +- Improve GPOS cursive attachments with conflicting lookups. +- More fixes for cluster-level = 1. +- Uniscribe positioning fix. + + +Overview of changes leading to 1.0.2 +Wednesday, August 19, 2015 +==================================== + +- Fix shaping with cluster-level > 0. +- Fix Uniscribe backend font-size scaling. +- Declare dependencies in harfbuzz.pc. + FreeType is not declared though, to avoid bugs in pkg-config + 0.26 with recursive dependencies. +- Slightly improved debug infrastructure. More to come later. +- Misc build fixes. + + +Overview of changes leading to 1.0.1 +Monday, July 27, 2015 +==================================== + +- Fix out-of-bounds access in USE shaper. + + +Overview of changes leading to 1.0.0 +Sunday, July 26, 2015 +==================================== + +- Implement Universal Shaping Engine: + https://www.microsoft.com/typography/OpenTypeDev/USE/intro.htm + http://blogs.windows.com/bloggingwindows/2015/02/23/windows-shapes-the-worlds-languages/ +- Bump version to 1.0.0. The soname was NOT bumped. + + +Overview of changes leading to 0.9.42 +Thursday, July 26, 2015 +===================================== + +- New API to allow for retrieving finer-grained cluster + mappings if the client desires to handle them. Default + behavior is unchanged. +- Fix cluster merging when removing default-ignorables. +- Update to Unicode 8.0 +- hb-graphite2 fixes. +- Misc fixes. +- Removed HB_NO_MERGE_CLUSTERS hack. +- New API: + hb_buffer_cluster_level_t enum + hb_buffer_get_cluster_level() + hb_buffer_set_cluster_level() + hb-shape / hb-view --cluster-level + + +Overview of changes leading to 0.9.41 +Thursday, June 18, 2015 +===================================== + +- Fix hb-coretext with trailing whitespace in right-to-left. +- New API: hb_buffer_reverse_range(). +- Allow implementing atomic ops in config.h. +- Fix hb_language_t in language bindings. +- Misc fixes. + + Overview of changes leading to 0.9.40 Friday, March 20, 2015 ===================================== diff --git a/src/3rdparty/harfbuzz-ng/README b/src/3rdparty/harfbuzz-ng/README index d34bc74f99..dea10688f3 100644 --- a/src/3rdparty/harfbuzz-ng/README +++ b/src/3rdparty/harfbuzz-ng/README @@ -1,5 +1,6 @@ [![Build Status](https://travis-ci.org/behdad/harfbuzz.svg)](https://travis-ci.org/behdad/harfbuzz) [![Coverage Status](https://img.shields.io/coveralls/behdad/harfbuzz.svg)](https://coveralls.io/r/behdad/harfbuzz) +[![Coverity Scan](https://img.shields.io/coverity/scan/5450.svg)](https://scan.coverity.com/projects/5450) This is HarfBuzz, a text shaping library. diff --git a/src/3rdparty/harfbuzz-ng/config.h b/src/3rdparty/harfbuzz-ng/config.h new file mode 100644 index 0000000000..b8b6b3c0fe --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/config.h @@ -0,0 +1,47 @@ +/* +* Copyright (C) 2015 The Qt Company Ltd. +* Copyright (C) 2015 Konstantin Ritt +* +* Permission is hereby granted, without written agreement and without +* license or royalty fees, to use, copy, modify, and distribute this +* software and its documentation for any purpose, provided that the +* above copyright notice and the following two paragraphs appear in +* all copies of this software. +* +* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR +* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN +* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +* DAMAGE. +* +* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, +* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS +* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO +* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. +* +*/ + +#include + +QT_USE_NAMESPACE + +namespace { + +// We need to cast hb_atomic_int_t to QAtomicInt and pointers to +// QAtomicPointer instead of using QAtomicOps, otherwise we get a failed +// overload resolution of the template arguments for testAndSetOrdered. +template +inline QAtomicPointer *makeAtomicPointer(T * const &ptr) +{ + return reinterpret_cast *>(const_cast(&ptr)); +} + +} // namespace + +typedef int hb_atomic_int_impl_t; +#define HB_ATOMIC_INT_IMPL_INIT(V) (V) +#define hb_atomic_int_impl_add(AI, V) reinterpret_cast(AI).fetchAndAddOrdered(V) + +#define hb_atomic_ptr_impl_get(P) makeAtomicPointer(*(P))->loadAcquire() +#define hb_atomic_ptr_impl_cmpexch(P,O,N) makeAtomicPointer(*(P))->testAndSetOrdered((O), (N)) diff --git a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro index fb6771759b..031f7ecd58 100644 --- a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro +++ b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro @@ -7,7 +7,8 @@ CONFIG += \ load(qt_helper_lib) -DEFINES += HAVE_OT HAVE_QT5_ATOMICS HB_NO_UNICODE_FUNCS HB_DISABLE_DEPRECATED +DEFINES += HAVE_CONFIG_H +DEFINES += HAVE_OT HB_NO_UNICODE_FUNCS HB_DISABLE_DEPRECATED # platform/compiler specific definitions DEFINES += HAVE_ATEXIT @@ -45,6 +46,7 @@ HEADERS += \ $$PWD/src/hb-open-file-private.hh \ $$PWD/src/hb-open-type-private.hh \ $$PWD/src/hb-ot-cmap-table.hh \ + $$PWD/src/hb-ot-glyf-table.hh \ $$PWD/src/hb-ot-head-table.hh \ $$PWD/src/hb-ot-hhea-table.hh \ $$PWD/src/hb-ot-hmtx-table.hh \ @@ -86,9 +88,10 @@ SOURCES += \ $$PWD/src/hb-ot-shape-complex-indic.cc \ $$PWD/src/hb-ot-shape-complex-indic-table.cc \ $$PWD/src/hb-ot-shape-complex-myanmar.cc \ - $$PWD/src/hb-ot-shape-complex-sea.cc \ $$PWD/src/hb-ot-shape-complex-thai.cc \ $$PWD/src/hb-ot-shape-complex-tibetan.cc \ + $$PWD/src/hb-ot-shape-complex-use.cc \ + $$PWD/src/hb-ot-shape-complex-use-table.cc \ $$PWD/src/hb-ot-shape-fallback.cc \ $$PWD/src/hb-ot-shape-normalize.cc @@ -102,12 +105,14 @@ HEADERS += \ $$PWD/src/hb-ot-layout-private.hh \ $$PWD/src/hb-ot-map-private.hh \ $$PWD/src/hb-ot-shape-complex-arabic-fallback.hh \ + $$PWD/src/hb-ot-shape-complex-arabic-private.hh \ $$PWD/src/hb-ot-shape-complex-arabic-table.hh \ $$PWD/src/hb-ot-shape-complex-indic-machine.hh \ $$PWD/src/hb-ot-shape-complex-indic-private.hh \ $$PWD/src/hb-ot-shape-complex-myanmar-machine.hh \ $$PWD/src/hb-ot-shape-complex-private.hh \ - $$PWD/src/hb-ot-shape-complex-sea-machine.hh \ + $$PWD/src/hb-ot-shape-complex-use-machine.hh \ + $$PWD/src/hb-ot-shape-complex-use-private.hh \ $$PWD/src/hb-ot-shape-fallback-private.hh \ $$PWD/src/hb-ot-shape-normalize-private.hh \ $$PWD/src/hb-ot-shape-private.hh diff --git a/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh index 48eb56141f..8179571ad2 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh @@ -39,27 +39,12 @@ /* We need external help for these */ -#if 0 +#if defined(hb_atomic_int_impl_add) \ + && defined(hb_atomic_ptr_impl_get) \ + && defined(hb_atomic_ptr_impl_cmpexch) -#elif !defined(HB_NO_MT) && defined(HAVE_QT5_ATOMICS) -#include +/* Defined externally, i.e. in config.h; must have typedef'ed hb_atomic_int_impl_t as well. */ -QT_USE_NAMESPACE - -namespace { -// We need to cast hb_atomic_int_t to QAtomicInt and pointers to -// QAtomicPointer instead of using QAtomicOps, otherwise we get a failed -// overload resolution of the template arguments for testAndSetOrdered. -template QAtomicPointer *makeAtomicPointer(T * const &ptr) -{ - return reinterpret_cast *>(const_cast(&ptr)); -} -} - -typedef int hb_atomic_int_t; -#define hb_atomic_int_add(AI, V) reinterpret_cast(AI).fetchAndAddOrdered(V) -#define hb_atomic_ptr_get(P) makeAtomicPointer(*P)->loadAcquire() -#define hb_atomic_ptr_cmpexch(P,O,N) makeAtomicPointer(*P)->testAndSetOrdered((O), (N)) #elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__)) @@ -77,11 +62,12 @@ static inline void _HBMemoryBarrier (void) { #endif } -typedef LONG hb_atomic_int_t; -#define hb_atomic_int_add(AI, V) InterlockedExchangeAdd (&(AI), (V)) +typedef LONG hb_atomic_int_impl_t; +#define HB_ATOMIC_INT_IMPL_INIT(V) (V) +#define hb_atomic_int_impl_add(AI, V) InterlockedExchangeAdd (&(AI), (V)) -#define hb_atomic_ptr_get(P) (_HBMemoryBarrier (), (void *) *(P)) -#define hb_atomic_ptr_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O)) +#define hb_atomic_ptr_impl_get(P) (_HBMemoryBarrier (), (void *) *(P)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O)) #elif !defined(HB_NO_MT) && defined(__APPLE__) @@ -93,28 +79,31 @@ typedef LONG hb_atomic_int_t; #include #endif -typedef int32_t hb_atomic_int_t; -#define hb_atomic_int_add(AI, V) (OSAtomicAdd32Barrier ((V), &(AI)) - (V)) -#define hb_atomic_ptr_get(P) (OSMemoryBarrier (), (void *) *(P)) +typedef int32_t hb_atomic_int_impl_t; +#define HB_ATOMIC_INT_IMPL_INIT(V) (V) +#define hb_atomic_int_impl_add(AI, V) (OSAtomicAdd32Barrier ((V), &(AI)) - (V)) + +#define hb_atomic_ptr_impl_get(P) (OSMemoryBarrier (), (void *) *(P)) #if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 || __IPHONE_VERSION_MIN_REQUIRED >= 20100) -#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P)) #else #if __ppc64__ || __x86_64__ || __aarch64__ -#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P)) #else -#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P)) #endif #endif #elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES) -typedef int hb_atomic_int_t; -#define hb_atomic_int_add(AI, V) __sync_fetch_and_add (&(AI), (V)) +typedef int hb_atomic_int_impl_t; +#define HB_ATOMIC_INT_IMPL_INIT(V) (V) +#define hb_atomic_int_impl_add(AI, V) __sync_fetch_and_add (&(AI), (V)) -#define hb_atomic_ptr_get(P) (void *) (__sync_synchronize (), *(P)) -#define hb_atomic_ptr_cmpexch(P,O,N) __sync_bool_compare_and_swap ((P), (O), (N)) +#define hb_atomic_ptr_impl_get(P) (void *) (__sync_synchronize (), *(P)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) __sync_bool_compare_and_swap ((P), (O), (N)) #elif !defined(HB_NO_MT) && defined(HAVE_SOLARIS_ATOMIC_OPS) @@ -122,33 +111,54 @@ typedef int hb_atomic_int_t; #include #include -typedef unsigned int hb_atomic_int_t; -#define hb_atomic_int_add(AI, V) ( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V)) +typedef unsigned int hb_atomic_int_impl_t; +#define HB_ATOMIC_INT_IMPL_INIT(V) (V) +#define hb_atomic_int_impl_add(AI, V) ( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V)) -#define hb_atomic_ptr_get(P) ( ({__machine_rw_barrier ();}), (void *) *(P)) -#define hb_atomic_ptr_cmpexch(P,O,N) ( ({__machine_rw_barrier ();}), atomic_cas_ptr ((void **) (P), (void *) (O), (void *) (N)) == (void *) (O) ? true : false) +#define hb_atomic_ptr_impl_get(P) ( ({__machine_rw_barrier ();}), (void *) *(P)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) ( ({__machine_rw_barrier ();}), atomic_cas_ptr ((void **) (P), (void *) (O), (void *) (N)) == (void *) (O) ? true : false) #elif !defined(HB_NO_MT) #define HB_ATOMIC_INT_NIL 1 /* Warn that fallback implementation is in use. */ -typedef volatile int hb_atomic_int_t; -#define hb_atomic_int_add(AI, V) (((AI) += (V)) - (V)) -#define hb_atomic_ptr_get(P) ((void *) *(P)) -#define hb_atomic_ptr_cmpexch(P,O,N) (* (void * volatile *) (P) == (void *) (O) ? (* (void * volatile *) (P) = (void *) (N), true) : false) +typedef volatile int hb_atomic_int_impl_t; +#define HB_ATOMIC_INT_IMPL_INIT(V) (V) +#define hb_atomic_int_impl_add(AI, V) (((AI) += (V)) - (V)) + +#define hb_atomic_ptr_impl_get(P) ((void *) *(P)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) (* (void * volatile *) (P) == (void *) (O) ? (* (void * volatile *) (P) = (void *) (N), true) : false) #else /* HB_NO_MT */ -typedef int hb_atomic_int_t; -#define hb_atomic_int_add(AI, V) (((AI) += (V)) - (V)) +typedef int hb_atomic_int_impl_t; +#define HB_ATOMIC_INT_IMPL_INIT(V) (V) +#define hb_atomic_int_impl_add(AI, V) (((AI) += (V)) - (V)) + +#define hb_atomic_ptr_impl_get(P) ((void *) *(P)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) (* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false) -#define hb_atomic_ptr_get(P) ((void *) *(P)) -#define hb_atomic_ptr_cmpexch(P,O,N) (* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false) #endif -/* TODO Add tracing. */ + +#define HB_ATOMIC_INT_INIT(V) {HB_ATOMIC_INT_IMPL_INIT(V)} + +struct hb_atomic_int_t +{ + hb_atomic_int_impl_t v; + + inline void set_unsafe (int v_) { v = v_; } + inline int get_unsafe (void) const { return v; } + inline int inc (void) { return hb_atomic_int_impl_add (const_cast (v), 1); } + inline int dec (void) { return hb_atomic_int_impl_add (const_cast (v), -1); } +}; + + +#define hb_atomic_ptr_get(P) hb_atomic_ptr_impl_get(P) +#define hb_atomic_ptr_cmpexch(P,O,N) hb_atomic_ptr_impl_cmpexch((P),(O),(N)) + #endif /* HB_ATOMIC_PRIVATE_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-blob.cc b/src/3rdparty/harfbuzz-ng/src/hb-blob.cc index 8759a252a5..a6870dc06e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-blob.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-blob.cc @@ -91,7 +91,7 @@ _hb_blob_destroy_user_data (hb_blob_t *blob) * Return value: New blob, or the empty blob if something failed or if @length is * zero. Destroy with hb_blob_destroy(). * - * Since: 1.0 + * Since: 0.9.2 **/ hb_blob_t * hb_blob_create (const char *data, @@ -147,7 +147,7 @@ hb_blob_create (const char *data, * @length is zero or @offset is beyond the end of @parent's data. Destroy * with hb_blob_destroy(). * - * Since: 1.0 + * Since: 0.9.2 **/ hb_blob_t * hb_blob_create_sub_blob (hb_blob_t *parent, @@ -179,7 +179,7 @@ hb_blob_create_sub_blob (hb_blob_t *parent, * * Return value: (transfer full): the empty blob. * - * Since: 1.0 + * Since: 0.9.2 **/ hb_blob_t * hb_blob_get_empty (void) @@ -210,7 +210,7 @@ hb_blob_get_empty (void) * * Return value: @blob. * - * Since: 1.0 + * Since: 0.9.2 **/ hb_blob_t * hb_blob_reference (hb_blob_t *blob) @@ -228,7 +228,7 @@ hb_blob_reference (hb_blob_t *blob) * * See TODO:link object types for more information. * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_blob_destroy (hb_blob_t *blob) @@ -250,7 +250,7 @@ hb_blob_destroy (hb_blob_t *blob) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_blob_set_user_data (hb_blob_t *blob, @@ -271,7 +271,7 @@ hb_blob_set_user_data (hb_blob_t *blob, * * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ void * hb_blob_get_user_data (hb_blob_t *blob, @@ -287,7 +287,7 @@ hb_blob_get_user_data (hb_blob_t *blob, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_blob_make_immutable (hb_blob_t *blob) @@ -306,7 +306,7 @@ hb_blob_make_immutable (hb_blob_t *blob) * * Return value: TODO * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_blob_is_immutable (hb_blob_t *blob) @@ -323,7 +323,7 @@ hb_blob_is_immutable (hb_blob_t *blob) * * Return value: the length of blob data in bytes. * - * Since: 1.0 + * Since: 0.9.2 **/ unsigned int hb_blob_get_length (hb_blob_t *blob) @@ -340,7 +340,7 @@ hb_blob_get_length (hb_blob_t *blob) * * Returns: (transfer none) (array length=length): * - * Since: 1.0 + * Since: 0.9.2 **/ const char * hb_blob_get_data (hb_blob_t *blob, unsigned int *length) @@ -365,7 +365,7 @@ hb_blob_get_data (hb_blob_t *blob, unsigned int *length) * Returns: (transfer none) (array length=length): Writable blob data, * or %NULL if failed. * - * Since: 1.0 + * Since: 0.9.2 **/ char * hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text.hh b/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text.hh index 7a46ab278b..d2d8daae7e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text.hh @@ -336,8 +336,8 @@ _hb_buffer_deserialize_glyphs_text (hb_buffer_t *buffer, const char *eof = pe, *tok = NULL; int cs; - hb_glyph_info_t info; - hb_glyph_position_t pos; + hb_glyph_info_t info = {0}; + hb_glyph_position_t pos = {0}; #line 343 "hb-buffer-deserialize-text.hh" { diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh index 069f925581..7fed7386b0 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh @@ -50,6 +50,7 @@ struct hb_buffer_t { /* Information about how the text in the buffer should be treated */ hb_unicode_funcs_t *unicode; /* Unicode functions */ hb_buffer_flags_t flags; /* BOT / EOT / etc. */ + hb_buffer_cluster_level_t cluster_level; hb_codepoint_t replacement; /* U+FFFD or something else. */ /* Buffer contents */ @@ -171,9 +172,18 @@ struct hb_buffer_t { unsigned int cluster_end); HB_INTERNAL void merge_clusters (unsigned int start, - unsigned int end); + unsigned int end) + { + if (end - start < 2) + return; + merge_clusters_impl (start, end); + } + HB_INTERNAL void merge_clusters_impl (unsigned int start, + unsigned int end); HB_INTERNAL void merge_out_clusters (unsigned int start, unsigned int end); + /* Merge clusters for deleting current glyph, and skip it. */ + HB_INTERNAL void delete_glyph (void); /* Internal methods */ HB_INTERNAL bool enlarge (unsigned int size); @@ -191,6 +201,8 @@ struct hb_buffer_t { HB_INTERNAL scratch_buffer_t *get_scratch_buffer (unsigned int *size); inline void clear_context (unsigned int side) { context_len[side] = 0; } + + HB_INTERNAL void sort (unsigned int start, unsigned int end, int(*compar)(const hb_glyph_info_t *, const hb_glyph_info_t *)); }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc b/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc index 406d69db75..7839cbc3f0 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc @@ -40,7 +40,7 @@ static const char *serialize_formats[] = { * * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ const char ** hb_buffer_serialize_list_formats (void) @@ -57,7 +57,7 @@ hb_buffer_serialize_list_formats (void) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_buffer_serialize_format_t hb_buffer_serialize_format_from_string (const char *str, int len) @@ -74,7 +74,7 @@ hb_buffer_serialize_format_from_string (const char *str, int len) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ const char * hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format) @@ -99,7 +99,8 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer, hb_buffer_serialize_flags_t flags) { hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL); - hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, NULL); + hb_glyph_position_t *pos = (flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS) ? + NULL : hb_buffer_get_glyph_positions (buffer, NULL); *buf_consumed = 0; for (unsigned int i = start; i < end; i++) @@ -144,6 +145,16 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer, pos[i].x_advance, pos[i].y_advance); } + if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS) + { + hb_glyph_extents_t extents; + hb_font_get_glyph_extents(font, info[i].codepoint, &extents); + p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d", + extents.x_bearing, extents.y_bearing)); + p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d", + extents.width, extents.height)); + } + *p++ = '}'; unsigned int l = p - b; @@ -172,7 +183,8 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, hb_buffer_serialize_flags_t flags) { hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL); - hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, NULL); + hb_glyph_position_t *pos = (flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS) ? + NULL : hb_buffer_get_glyph_positions (buffer, NULL); *buf_consumed = 0; for (unsigned int i = start; i < end; i++) @@ -208,6 +220,13 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance)); } + if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS) + { + hb_glyph_extents_t extents; + hb_font_get_glyph_extents(font, info[i].codepoint, &extents); + p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "<%d,%d,%d,%d>", extents.x_bearing, extents.y_bearing, extents.width, extents.height)); + } + unsigned int l = p - b; if (buf_size > l) { @@ -240,7 +259,7 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ unsigned int hb_buffer_serialize_glyphs (hb_buffer_t *buffer, @@ -347,7 +366,7 @@ parse_int (const char *pp, const char *end, int32_t *pv) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc index b9fe263ce5..50710dd23e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc @@ -36,6 +36,9 @@ #endif +/** + * Since: 0.9.7 + **/ hb_bool_t hb_segment_properties_equal (const hb_segment_properties_t *a, const hb_segment_properties_t *b) @@ -48,6 +51,9 @@ hb_segment_properties_equal (const hb_segment_properties_t *a, } +/** + * Since: 0.9.7 + **/ unsigned int hb_segment_properties_hash (const hb_segment_properties_t *p) { @@ -498,14 +504,10 @@ hb_buffer_t::reverse_clusters (void) } void -hb_buffer_t::merge_clusters (unsigned int start, - unsigned int end) +hb_buffer_t::merge_clusters_impl (unsigned int start, + unsigned int end) { -#ifdef HB_NO_MERGE_CLUSTERS - return; -#endif - - if (unlikely (end - start < 2)) + if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS) return; unsigned int cluster = info[start].cluster; @@ -523,7 +525,7 @@ hb_buffer_t::merge_clusters (unsigned int start, /* If we hit the start of buffer, continue in out-buffer. */ if (idx == start) - for (unsigned i = out_len; i && out_info[i - 1].cluster == info[start].cluster; i--) + for (unsigned int i = out_len; i && out_info[i - 1].cluster == info[start].cluster; i--) out_info[i - 1].cluster = cluster; for (unsigned int i = start; i < end; i++) @@ -533,9 +535,8 @@ void hb_buffer_t::merge_out_clusters (unsigned int start, unsigned int end) { -#ifdef HB_NO_MERGE_CLUSTERS - return; -#endif + if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS) + return; if (unlikely (end - start < 2)) return; @@ -555,12 +556,44 @@ hb_buffer_t::merge_out_clusters (unsigned int start, /* If we hit the end of out-buffer, continue in buffer. */ if (end == out_len) - for (unsigned i = idx; i < len && info[i].cluster == out_info[end - 1].cluster; i++) + for (unsigned int i = idx; i < len && info[i].cluster == out_info[end - 1].cluster; i++) info[i].cluster = cluster; for (unsigned int i = start; i < end; i++) out_info[i].cluster = cluster; } +void +hb_buffer_t::delete_glyph () +{ + unsigned int cluster = info[idx].cluster; + if (idx + 1 < len && cluster == info[idx + 1].cluster) + { + /* Cluster survives; do nothing. */ + goto done; + } + + if (out_len) + { + /* Merge cluster backward. */ + if (cluster < out_info[out_len - 1].cluster) + { + unsigned int old_cluster = out_info[out_len - 1].cluster; + for (unsigned i = out_len; i && out_info[i - 1].cluster == old_cluster; i--) + out_info[i - 1].cluster = cluster; + } + goto done; + } + + if (idx + 1 < len) + { + /* Merge cluster forward. */ + merge_clusters (idx, idx + 2); + goto done; + } + +done: + skip_glyph (); +} void hb_buffer_t::guess_segment_properties (void) @@ -671,7 +704,7 @@ void hb_buffer_t::deallocate_var_all (void) * * Return value: (transfer full) * - * Since: 1.0 + * Since: 0.9.2 **/ hb_buffer_t * hb_buffer_create (void) @@ -693,7 +726,7 @@ hb_buffer_create (void) * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_buffer_t * hb_buffer_get_empty (void) @@ -703,6 +736,7 @@ hb_buffer_get_empty (void) const_cast (&_hb_unicode_funcs_nil), HB_BUFFER_FLAG_DEFAULT, + HB_BUFFER_CLUSTER_LEVEL_DEFAULT, HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT, HB_BUFFER_CONTENT_TYPE_INVALID, @@ -725,7 +759,7 @@ hb_buffer_get_empty (void) * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_buffer_t * hb_buffer_reference (hb_buffer_t *buffer) @@ -739,7 +773,7 @@ hb_buffer_reference (hb_buffer_t *buffer) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_buffer_destroy (hb_buffer_t *buffer) @@ -766,7 +800,7 @@ hb_buffer_destroy (hb_buffer_t *buffer) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_buffer_set_user_data (hb_buffer_t *buffer, @@ -787,7 +821,7 @@ hb_buffer_set_user_data (hb_buffer_t *buffer, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ void * hb_buffer_get_user_data (hb_buffer_t *buffer, @@ -804,7 +838,7 @@ hb_buffer_get_user_data (hb_buffer_t *buffer, * * * - * Since: 1.0 + * Since: 0.9.5 **/ void hb_buffer_set_content_type (hb_buffer_t *buffer, @@ -821,7 +855,7 @@ hb_buffer_set_content_type (hb_buffer_t *buffer, * * Return value: * - * Since: 1.0 + * Since: 0.9.5 **/ hb_buffer_content_type_t hb_buffer_get_content_type (hb_buffer_t *buffer) @@ -837,7 +871,7 @@ hb_buffer_get_content_type (hb_buffer_t *buffer) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_buffer_set_unicode_funcs (hb_buffer_t *buffer, @@ -863,7 +897,7 @@ hb_buffer_set_unicode_funcs (hb_buffer_t *buffer, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_unicode_funcs_t * hb_buffer_get_unicode_funcs (hb_buffer_t *buffer) @@ -878,7 +912,7 @@ hb_buffer_get_unicode_funcs (hb_buffer_t *buffer) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_buffer_set_direction (hb_buffer_t *buffer, @@ -899,7 +933,7 @@ hb_buffer_set_direction (hb_buffer_t *buffer, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_direction_t hb_buffer_get_direction (hb_buffer_t *buffer) @@ -914,7 +948,7 @@ hb_buffer_get_direction (hb_buffer_t *buffer) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_buffer_set_script (hb_buffer_t *buffer, @@ -934,7 +968,7 @@ hb_buffer_set_script (hb_buffer_t *buffer, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_script_t hb_buffer_get_script (hb_buffer_t *buffer) @@ -949,7 +983,7 @@ hb_buffer_get_script (hb_buffer_t *buffer) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_buffer_set_language (hb_buffer_t *buffer, @@ -967,9 +1001,9 @@ hb_buffer_set_language (hb_buffer_t *buffer, * * * - * Return value: + * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_language_t hb_buffer_get_language (hb_buffer_t *buffer) @@ -984,7 +1018,7 @@ hb_buffer_get_language (hb_buffer_t *buffer) * * * - * Since: 1.0 + * Since: 0.9.7 **/ void hb_buffer_set_segment_properties (hb_buffer_t *buffer, @@ -999,11 +1033,11 @@ hb_buffer_set_segment_properties (hb_buffer_t *buffer, /** * hb_buffer_get_segment_properties: * @buffer: a buffer. - * @props: + * @props: (out): * * * - * Since: 1.0 + * Since: 0.9.7 **/ void hb_buffer_get_segment_properties (hb_buffer_t *buffer, @@ -1020,7 +1054,7 @@ hb_buffer_get_segment_properties (hb_buffer_t *buffer, * * * - * Since: 1.0 + * Since: 0.9.7 **/ void hb_buffer_set_flags (hb_buffer_t *buffer, @@ -1040,7 +1074,7 @@ hb_buffer_set_flags (hb_buffer_t *buffer, * * Return value: * - * Since: 1.0 + * Since: 0.9.7 **/ hb_buffer_flags_t hb_buffer_get_flags (hb_buffer_t *buffer) @@ -1048,6 +1082,41 @@ hb_buffer_get_flags (hb_buffer_t *buffer) return buffer->flags; } +/** + * hb_buffer_set_cluster_level: + * @buffer: a buffer. + * @cluster_level: + * + * + * + * Since: 0.9.42 + **/ +void +hb_buffer_set_cluster_level (hb_buffer_t *buffer, + hb_buffer_cluster_level_t cluster_level) +{ + if (unlikely (hb_object_is_inert (buffer))) + return; + + buffer->cluster_level = cluster_level; +} + +/** + * hb_buffer_get_cluster_level: + * @buffer: a buffer. + * + * + * + * Return value: + * + * Since: 0.9.42 + **/ +hb_buffer_cluster_level_t +hb_buffer_get_cluster_level (hb_buffer_t *buffer) +{ + return buffer->cluster_level; +} + /** * hb_buffer_set_replacement_codepoint: @@ -1056,7 +1125,7 @@ hb_buffer_get_flags (hb_buffer_t *buffer) * * * - * Since: 1.0 + * Since: 0.9.31 **/ void hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer, @@ -1076,7 +1145,7 @@ hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer, * * Return value: * - * Since: 1.0 + * Since: 0.9.31 **/ hb_codepoint_t hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer) @@ -1091,7 +1160,7 @@ hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_buffer_reset (hb_buffer_t *buffer) @@ -1105,7 +1174,7 @@ hb_buffer_reset (hb_buffer_t *buffer) * * * - * Since: 1.0 + * Since: 0.9.11 **/ void hb_buffer_clear_contents (hb_buffer_t *buffer) @@ -1122,7 +1191,7 @@ hb_buffer_clear_contents (hb_buffer_t *buffer) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size) @@ -1138,7 +1207,7 @@ hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_buffer_allocation_successful (hb_buffer_t *buffer) @@ -1154,7 +1223,7 @@ hb_buffer_allocation_successful (hb_buffer_t *buffer) * * * - * Since: 1.0 + * Since: 0.9.7 **/ void hb_buffer_add (hb_buffer_t *buffer, @@ -1174,7 +1243,7 @@ hb_buffer_add (hb_buffer_t *buffer, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_buffer_set_length (hb_buffer_t *buffer, @@ -1213,7 +1282,7 @@ hb_buffer_set_length (hb_buffer_t *buffer, * * Return value: buffer length. * - * Since: 1.0 + * Since: 0.9.2 **/ unsigned int hb_buffer_get_length (hb_buffer_t *buffer) @@ -1231,7 +1300,7 @@ hb_buffer_get_length (hb_buffer_t *buffer) * * Return value: (transfer none) (array length=length): buffer glyph information array. * - * Since: 1.0 + * Since: 0.9.2 **/ hb_glyph_info_t * hb_buffer_get_glyph_infos (hb_buffer_t *buffer, @@ -1253,7 +1322,7 @@ hb_buffer_get_glyph_infos (hb_buffer_t *buffer, * * Return value: (transfer none) (array length=length): buffer glyph position array. * - * Since: 1.0 + * Since: 0.9.2 **/ hb_glyph_position_t * hb_buffer_get_glyph_positions (hb_buffer_t *buffer, @@ -1274,7 +1343,7 @@ hb_buffer_get_glyph_positions (hb_buffer_t *buffer, * * Reverses buffer contents. * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_buffer_reverse (hb_buffer_t *buffer) @@ -1282,6 +1351,23 @@ hb_buffer_reverse (hb_buffer_t *buffer) buffer->reverse (); } +/** + * hb_buffer_reverse_range: + * @buffer: a buffer. + * @start: start index. + * @end: end index. + * + * Reverses buffer contents between start to end. + * + * Since: 0.9.41 + **/ +void +hb_buffer_reverse_range (hb_buffer_t *buffer, + unsigned int start, unsigned int end) +{ + buffer->reverse_range (start, end); +} + /** * hb_buffer_reverse_clusters: * @buffer: a buffer. @@ -1290,7 +1376,7 @@ hb_buffer_reverse (hb_buffer_t *buffer) * reversed, then each cluster (consecutive items having the * same cluster number) are reversed again. * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_buffer_reverse_clusters (hb_buffer_t *buffer) @@ -1320,7 +1406,7 @@ hb_buffer_reverse_clusters (hb_buffer_t *buffer) * hb_language_get_default(). This may change in the future by * taking buffer script into consideration when choosing a language. * - * Since: 1.0 + * Since: 0.9.7 **/ void hb_buffer_guess_segment_properties (hb_buffer_t *buffer) @@ -1407,7 +1493,7 @@ hb_buffer_add_utf (hb_buffer_t *buffer, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_buffer_add_utf8 (hb_buffer_t *buffer, @@ -1429,7 +1515,7 @@ hb_buffer_add_utf8 (hb_buffer_t *buffer, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_buffer_add_utf16 (hb_buffer_t *buffer, @@ -1451,7 +1537,7 @@ hb_buffer_add_utf16 (hb_buffer_t *buffer, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_buffer_add_utf32 (hb_buffer_t *buffer, @@ -1473,7 +1559,7 @@ hb_buffer_add_utf32 (hb_buffer_t *buffer, * * * - * Since: 1.0 + * Since: 0.9.39 **/ void hb_buffer_add_latin1 (hb_buffer_t *buffer, @@ -1495,7 +1581,7 @@ hb_buffer_add_latin1 (hb_buffer_t *buffer, * * * - * Since: 1.0 + * Since: 0.9.31 **/ void hb_buffer_add_codepoints (hb_buffer_t *buffer, @@ -1550,7 +1636,7 @@ normalize_glyphs_cluster (hb_buffer_t *buffer, pos[end - 1].x_advance = total_x_advance; pos[end - 1].y_advance = total_y_advance; - hb_bubble_sort (buffer->info + start, end - start - 1, compare_info_codepoint, buffer->pos + start); + hb_stable_sort (buffer->info + start, end - start - 1, compare_info_codepoint, buffer->pos + start); } else { /* Transfer all cluster advance to the first glyph. */ pos[start].x_advance += total_x_advance; @@ -1559,7 +1645,7 @@ normalize_glyphs_cluster (hb_buffer_t *buffer, pos[i].x_offset -= total_x_advance; pos[i].y_offset -= total_y_advance; } - hb_bubble_sort (buffer->info + start + 1, end - start - 1, compare_info_codepoint, buffer->pos + start + 1); + hb_stable_sort (buffer->info + start + 1, end - start - 1, compare_info_codepoint, buffer->pos + start + 1); } } @@ -1569,7 +1655,7 @@ normalize_glyphs_cluster (hb_buffer_t *buffer, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_buffer_normalize_glyphs (hb_buffer_t *buffer) @@ -1592,3 +1678,24 @@ hb_buffer_normalize_glyphs (hb_buffer_t *buffer) } normalize_glyphs_cluster (buffer, start, end, backward); } + +void +hb_buffer_t::sort (unsigned int start, unsigned int end, int(*compar)(const hb_glyph_info_t *, const hb_glyph_info_t *)) +{ + assert (!have_positions); + for (unsigned int i = start + 1; i < end; i++) + { + unsigned int j = i; + while (j > start && compar (&info[j - 1], &info[i]) > 0) + j--; + if (i == j) + continue; + /* Move item i to occupy place for item j, shift what's in between. */ + merge_clusters (j, i + 1); + { + hb_glyph_info_t t = info[i]; + memmove (&info[j + 1], &info[j], (i - j) * sizeof (hb_glyph_info_t)); + info[j] = t; + } + } +} diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.h b/src/3rdparty/harfbuzz-ng/src/hb-buffer.h index e5b46d867a..bb89dc3de7 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.h @@ -171,6 +171,9 @@ void hb_buffer_guess_segment_properties (hb_buffer_t *buffer); +/* + * Since: 0.9.20 + */ typedef enum { /*< flags >*/ HB_BUFFER_FLAG_DEFAULT = 0x00000000u, HB_BUFFER_FLAG_BOT = 0x00000001u, /* Beginning-of-text */ @@ -185,7 +188,22 @@ hb_buffer_set_flags (hb_buffer_t *buffer, hb_buffer_flags_t hb_buffer_get_flags (hb_buffer_t *buffer); +/* + * Since: 0.9.42 + */ +typedef enum { + HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES = 0, + HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS = 1, + HB_BUFFER_CLUSTER_LEVEL_CHARACTERS = 2, + HB_BUFFER_CLUSTER_LEVEL_DEFAULT = HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES +} hb_buffer_cluster_level_t; +void +hb_buffer_set_cluster_level (hb_buffer_t *buffer, + hb_buffer_cluster_level_t cluster_level); + +hb_buffer_cluster_level_t +hb_buffer_get_cluster_level (hb_buffer_t *buffer); #define HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT 0xFFFDu @@ -221,6 +239,10 @@ hb_buffer_allocation_successful (hb_buffer_t *buffer); void hb_buffer_reverse (hb_buffer_t *buffer); +void +hb_buffer_reverse_range (hb_buffer_t *buffer, + unsigned int start, unsigned int end); + void hb_buffer_reverse_clusters (hb_buffer_t *buffer); @@ -303,11 +325,15 @@ hb_buffer_normalize_glyphs (hb_buffer_t *buffer); * Serialize */ +/* + * Since: 0.9.20 + */ typedef enum { /*< flags >*/ HB_BUFFER_SERIALIZE_FLAG_DEFAULT = 0x00000000u, HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS = 0x00000001u, HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS = 0x00000002u, - HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES = 0x00000004u + HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES = 0x00000004u, + HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS = 0x00000008u } hb_buffer_serialize_flags_t; typedef enum { diff --git a/src/3rdparty/harfbuzz-ng/src/hb-common.cc b/src/3rdparty/harfbuzz-ng/src/hb-common.cc index 1516211e96..e67059d10b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-common.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-common.cc @@ -64,7 +64,7 @@ _hb_options_init (void) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_tag_t hb_tag_from_string (const char *str, int len) @@ -92,7 +92,7 @@ hb_tag_from_string (const char *str, int len) * * * - * Since: 1.0 + * Since: 0.9.5 **/ void hb_tag_to_string (hb_tag_t tag, char *buf) @@ -122,7 +122,7 @@ const char direction_strings[][4] = { * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_direction_t hb_direction_from_string (const char *str, int len) @@ -149,7 +149,7 @@ hb_direction_from_string (const char *str, int len) * * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ const char * hb_direction_to_string (hb_direction_t direction) @@ -179,7 +179,7 @@ static const char canon_map[256] = { 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, 0 }; -static hb_bool_t +static bool lang_equal (hb_language_t v1, const void *v2) { @@ -286,28 +286,28 @@ retry: * * * - * Return value: + * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_language_t hb_language_from_string (const char *str, int len) { - char strbuf[64]; - if (!str || !len || !*str) return HB_LANGUAGE_INVALID; + hb_language_item_t *item = NULL; if (len >= 0) { /* NUL-terminate it. */ + char strbuf[64]; len = MIN (len, (int) sizeof (strbuf) - 1); memcpy (strbuf, str, len); strbuf[len] = '\0'; - str = strbuf; + item = lang_find_or_insert (strbuf); } - - hb_language_item_t *item = lang_find_or_insert (str); + else + item = lang_find_or_insert (str); return likely (item) ? item->lang : HB_LANGUAGE_INVALID; } @@ -320,7 +320,7 @@ hb_language_from_string (const char *str, int len) * * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ const char * hb_language_to_string (hb_language_t language) @@ -334,9 +334,9 @@ hb_language_to_string (hb_language_t language) * * * - * Return value: + * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_language_t hb_language_get_default (void) @@ -363,7 +363,7 @@ hb_language_get_default (void) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_script_t hb_script_from_iso15924_tag (hb_tag_t tag) @@ -408,7 +408,7 @@ hb_script_from_iso15924_tag (hb_tag_t tag) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_script_t hb_script_from_string (const char *s, int len) @@ -424,7 +424,7 @@ hb_script_from_string (const char *s, int len) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_tag_t hb_script_to_iso15924_tag (hb_script_t script) @@ -440,7 +440,7 @@ hb_script_to_iso15924_tag (hb_script_t script) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_direction_t hb_script_get_horizontal_direction (hb_script_t script) @@ -493,6 +493,9 @@ hb_script_get_horizontal_direction (hb_script_t script) case HB_SCRIPT_PALMYRENE: case HB_SCRIPT_PSALTER_PAHLAVI: + /* Unicode-8.0 additions */ + case HB_SCRIPT_OLD_HUNGARIAN: + return HB_DIRECTION_RTL; } @@ -542,7 +545,7 @@ hb_user_data_array_t::get (hb_user_data_key_t *key) * * Returns library version as three integer components. * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_version (unsigned int *major, @@ -561,7 +564,7 @@ hb_version (unsigned int *major, * * Return value: library version string. * - * Since: 1.0 + * Since: 0.9.2 **/ const char * hb_version_string (void) @@ -579,7 +582,7 @@ hb_version_string (void) * * Return value: * - * Since: 1.0 + * Since: 0.9.30 **/ hb_bool_t hb_version_atleast (unsigned int major, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-common.h b/src/3rdparty/harfbuzz-ng/src/hb-common.h index b6ce3f724d..c291dbbe94 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-common.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-common.h @@ -272,6 +272,9 @@ typedef enum /*6.1*/ HB_SCRIPT_SORA_SOMPENG = HB_TAG ('S','o','r','a'), /*6.1*/ HB_SCRIPT_TAKRI = HB_TAG ('T','a','k','r'), + /* + * Since: 0.9.30 + */ /*7.0*/ HB_SCRIPT_BASSA_VAH = HB_TAG ('B','a','s','s'), /*7.0*/ HB_SCRIPT_CAUCASIAN_ALBANIAN = HB_TAG ('A','g','h','b'), /*7.0*/ HB_SCRIPT_DUPLOYAN = HB_TAG ('D','u','p','l'), @@ -296,6 +299,13 @@ typedef enum /*7.0*/ HB_SCRIPT_TIRHUTA = HB_TAG ('T','i','r','h'), /*7.0*/ HB_SCRIPT_WARANG_CITI = HB_TAG ('W','a','r','a'), + /*8.0*/ HB_SCRIPT_AHOM = HB_TAG ('A','h','o','m'), + /*8.0*/ HB_SCRIPT_ANATOLIAN_HIEROGLYPHS = HB_TAG ('H','l','u','w'), + /*8.0*/ HB_SCRIPT_HATRAN = HB_TAG ('H','a','t','r'), + /*8.0*/ HB_SCRIPT_MULTANI = HB_TAG ('M','u','l','t'), + /*8.0*/ HB_SCRIPT_OLD_HUNGARIAN = HB_TAG ('H','u','n','g'), + /*8.0*/ HB_SCRIPT_SIGNWRITING = HB_TAG ('S','g','n','w'), + /* No script set. */ HB_SCRIPT_INVALID = HB_TAG_NONE, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc index ab9e1d4a93..13ba5d94ef 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc @@ -38,19 +38,6 @@ #endif -typedef bool (*qt_get_font_table_func_t) (void *user_data, unsigned int tag, unsigned char *buffer, unsigned int *length); - -struct FontEngineFaceData { - void *user_data; - qt_get_font_table_func_t get_font_table; -}; - -struct CoreTextFontEngineData { - CTFontRef ctFont; - CGFontRef cgFont; -}; - - static void release_table_data (void *user_data) { @@ -104,7 +91,7 @@ hb_coretext_shaper_face_data_t * _hb_coretext_shaper_face_data_create (hb_face_t *face) { hb_coretext_shaper_face_data_t *data = NULL; -#if 0 + if (face->destroy == (hb_destroy_func_t) CGFontRelease) { data = CGFontRetain ((CGFontRef) face->user_data); @@ -124,11 +111,7 @@ _hb_coretext_shaper_face_data_create (hb_face_t *face) CGDataProviderRelease (provider); } } -#else - FontEngineFaceData *fontEngineFaceData = (FontEngineFaceData *) face->user_data; - CoreTextFontEngineData *coreTextFontEngineData = (CoreTextFontEngineData *) fontEngineFaceData->user_data; - data = CGFontRetain (coreTextFontEngineData->cgFont); -#endif + if (unlikely (!data)) { DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed"); } @@ -142,6 +125,9 @@ _hb_coretext_shaper_face_data_destroy (hb_coretext_shaper_face_data_t *data) CFRelease (data); } +/* + * Since: 0.9.10 + */ CGFontRef hb_coretext_face_get_cg_font (hb_face_t *face) { @@ -170,10 +156,10 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font) return NULL; hb_face_t *face = font->face; -#if 0 hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); /* Choose a CoreText font size and calculate multipliers to convert to HarfBuzz space. */ + /* TODO: use upem instead of 36? */ CGFloat font_size = 36.; /* Default... */ /* No idea if the following is even a good idea. */ if (font->y_ppem) @@ -184,12 +170,6 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font) data->x_mult = (CGFloat) font->x_scale / font_size; data->y_mult = (CGFloat) font->y_scale / font_size; data->ct_font = CTFontCreateWithGraphicsFont (face_data, font_size, NULL, NULL); -#else - data->x_mult = data->y_mult = (CGFloat) 64.0f; - FontEngineFaceData *fontEngineFaceData = (FontEngineFaceData *) face->user_data; - CoreTextFontEngineData *coreTextFontEngineData = (CoreTextFontEngineData *) fontEngineFaceData->user_data; - data->ct_font = (CTFontRef) CFRetain (coreTextFontEngineData->ctFont); -#endif if (unlikely (!data->ct_font)) { DEBUG_MSG (CORETEXT, font, "Font CTFontCreateWithGraphicsFont() failed"); free (data); @@ -812,6 +792,17 @@ retry: buffer->len = 0; uint32_t status_and = ~0, status_or = 0; double advances_so_far = 0; + /* For right-to-left runs, CoreText returns the glyphs positioned such that + * any trailing whitespace is to the left of (0,0). Adjust coordinate system + * to fix for that. Test with any RTL string with trailing spaces. + * https://code.google.com/p/chromium/issues/detail?id=469028 + */ + if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) + { + advances_so_far -= CTLineGetTrailingWhitespaceWidth (line); + if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction)) + advances_so_far = -advances_so_far; + } const CFRange range_all = CFRangeMake (0, 0); @@ -827,8 +818,6 @@ retry: run_advance = -run_advance; DEBUG_MSG (CORETEXT, run, "Run advance: %g", run_advance); - CFRange range = CTRunGetStringRange (run); - /* CoreText does automatic font fallback (AKA "cascading") for characters * not supported by the requested font, and provides no way to turn it off, * so we must detect if the returned run uses a font other than the requested @@ -895,6 +884,7 @@ retry: } if (!matched) { + CFRange range = CTRunGetStringRange (run); DEBUG_MSG (CORETEXT, run, "Run used fallback font: %ld..%ld", range.location, range.location + range.length); if (!buffer->ensure_inplace (buffer->len + range.length)) @@ -929,8 +919,8 @@ retry: info->cluster = log_clusters[j]; info->mask = advance; - info->var1.u32 = x_offset; - info->var2.u32 = y_offset; + info->var1.i32 = x_offset; + info->var2.i32 = y_offset; info++; buffer->len++; @@ -946,13 +936,7 @@ retry: if (num_glyphs == 0) continue; - /* ### temporary fix for QTBUG-38113 */ - /* CoreText throws away the PDF token, while the OpenType backend will add a zero-advance - * glyph for this. We need to make sure the two produce the same output. */ - UniChar endGlyph = CFStringGetCharacterAtIndex (string_ref, range.location + range.length - 1); - bool endsWithPDF = endGlyph == 0x202c; - - if (!buffer->ensure_inplace (buffer->len + num_glyphs + (endsWithPDF ? 1 : 0))) + if (!buffer->ensure_inplace (buffer->len + num_glyphs)) goto resize_and_retry; hb_glyph_info_t *run_info = buffer->info + buffer->len; @@ -1022,8 +1006,8 @@ retry: else /* last glyph */ advance = run_advance - (positions[j].x - positions[0].x); info->mask = advance * x_mult; - info->var1.u32 = x_offset; - info->var2.u32 = positions[j].y * y_mult; + info->var1.i32 = x_offset; + info->var2.i32 = positions[j].y * y_mult; info++; } } @@ -1038,25 +1022,11 @@ retry: else /* last glyph */ advance = run_advance - (positions[j].y - positions[0].y); info->mask = advance * y_mult; - info->var1.u32 = positions[j].x * x_mult; - info->var2.u32 = y_offset; + info->var1.i32 = positions[j].x * x_mult; + info->var2.i32 = y_offset; info++; } } - if (endsWithPDF) { - /* Ensure a zero-advance glyph the PDF token */ - if (unlikely (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))) { - memmove (run_info + 1, run_info, num_glyphs * sizeof (hb_glyph_info_t)); - info = run_info; - } - info->codepoint = 0xffff; - info->cluster = log_clusters[range.location + range.length - 1]; - info->mask = 0; - info->var1.u32 = 0; - info->var2.u32 = 0; - - buffer->len++; - } SCRATCH_RESTORE(); advances_so_far += run_advance; } @@ -1068,10 +1038,20 @@ retry: buffer->len += num_glyphs; } - /* Make sure all runs had the expected direction. */ - bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); - assert (bool (status_and & kCTRunStatusRightToLeft) == backward); - assert (bool (status_or & kCTRunStatusRightToLeft) == backward); + /* Mac OS 10.6 doesn't have kCTTypesetterOptionForcedEmbeddingLevel, + * or if it does, it doesn't resepct it. So we get runs with wrong + * directions. As such, disable the assert... It wouldn't crash, but + * cursoring will be off... + * + * http://crbug.com/419769 + */ + if (0) + { + /* Make sure all runs had the expected direction. */ + bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); + assert (bool (status_and & kCTRunStatusRightToLeft) == backward); + assert (bool (status_or & kCTRunStatusRightToLeft) == backward); + } buffer->clear_positions (); @@ -1082,16 +1062,16 @@ retry: for (unsigned int i = 0; i < count; i++) { pos->x_advance = info->mask; - pos->x_offset = info->var1.u32; - pos->y_offset = info->var2.u32; + pos->x_offset = info->var1.i32; + pos->y_offset = info->var2.i32; info++, pos++; } else for (unsigned int i = 0; i < count; i++) { pos->y_advance = info->mask; - pos->x_offset = info->var1.u32; - pos->y_offset = info->var2.u32; + pos->x_offset = info->var1.i32; + pos->y_offset = info->var2.i32; info++, pos++; } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-face.cc b/src/3rdparty/harfbuzz-ng/src/hb-face.cc index 9348af7bf8..9effc41c88 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-face.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-face.cc @@ -77,7 +77,7 @@ const hb_face_t _hb_face_nil = { * * Return value: (transfer full) * - * Since: 1.0 + * Since: 0.9.2 **/ hb_face_t * hb_face_create_for_tables (hb_reference_table_func_t reference_table_func, @@ -113,7 +113,7 @@ _hb_face_for_data_closure_create (hb_blob_t *blob, unsigned int index) { hb_face_for_data_closure_t *closure; - closure = (hb_face_for_data_closure_t *) malloc (sizeof (hb_face_for_data_closure_t)); + closure = (hb_face_for_data_closure_t *) calloc (1, sizeof (hb_face_for_data_closure_t)); if (unlikely (!closure)) return NULL; @@ -157,7 +157,7 @@ _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_face_t * hb_face_create (hb_blob_t *blob, @@ -165,8 +165,8 @@ hb_face_create (hb_blob_t *blob, { hb_face_t *face; - if (unlikely (!blob || !hb_blob_get_length (blob))) - return hb_face_get_empty (); + if (unlikely (!blob)) + blob = hb_blob_get_empty (); hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::Sanitizer::sanitize (hb_blob_reference (blob)), index); @@ -189,7 +189,7 @@ hb_face_create (hb_blob_t *blob, * * Return value: (transfer full) * - * Since: 1.0 + * Since: 0.9.2 **/ hb_face_t * hb_face_get_empty (void) @@ -206,7 +206,7 @@ hb_face_get_empty (void) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_face_t * hb_face_reference (hb_face_t *face) @@ -220,7 +220,7 @@ hb_face_reference (hb_face_t *face) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_face_destroy (hb_face_t *face) @@ -257,7 +257,7 @@ hb_face_destroy (hb_face_t *face) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_face_set_user_data (hb_face_t *face, @@ -278,7 +278,7 @@ hb_face_set_user_data (hb_face_t *face, * * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ void * hb_face_get_user_data (hb_face_t *face, @@ -293,7 +293,7 @@ hb_face_get_user_data (hb_face_t *face, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_face_make_immutable (hb_face_t *face) @@ -312,7 +312,7 @@ hb_face_make_immutable (hb_face_t *face) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_face_is_immutable (hb_face_t *face) @@ -330,7 +330,7 @@ hb_face_is_immutable (hb_face_t *face) * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_blob_t * hb_face_reference_table (hb_face_t *face, @@ -347,7 +347,7 @@ hb_face_reference_table (hb_face_t *face, * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_blob_t * hb_face_reference_blob (hb_face_t *face) @@ -362,7 +362,7 @@ hb_face_reference_blob (hb_face_t *face) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_face_set_index (hb_face_t *face, @@ -382,7 +382,7 @@ hb_face_set_index (hb_face_t *face, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ unsigned int hb_face_get_index (hb_face_t *face) @@ -397,7 +397,7 @@ hb_face_get_index (hb_face_t *face) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_face_set_upem (hb_face_t *face, @@ -417,7 +417,7 @@ hb_face_set_upem (hb_face_t *face, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ unsigned int hb_face_get_upem (hb_face_t *face) @@ -441,7 +441,7 @@ hb_face_t::load_upem (void) const * * * - * Since: 1.0 + * Since: 0.9.7 **/ void hb_face_set_glyph_count (hb_face_t *face, @@ -461,7 +461,7 @@ hb_face_set_glyph_count (hb_face_t *face, * * Return value: * - * Since: 1.0 + * Since: 0.9.7 **/ unsigned int hb_face_get_glyph_count (hb_face_t *face) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh index 33bbf7143a..c05499d4c2 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh @@ -268,7 +268,7 @@ struct hb_font_t { { *x = get_glyph_h_advance (glyph) / 2; - /* TODO use font_metics.ascent */ + /* TODO use font_metrics.ascent */ *y = y_scale; } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.cc b/src/3rdparty/harfbuzz-ng/src/hb-font.cc index d42db59855..6a69cae313 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-font.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-font.cc @@ -236,7 +236,7 @@ static const hb_font_funcs_t _hb_font_funcs_nil = { * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_font_funcs_t * hb_font_funcs_create (void) @@ -258,7 +258,7 @@ hb_font_funcs_create (void) * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_font_funcs_t * hb_font_funcs_get_empty (void) @@ -274,7 +274,7 @@ hb_font_funcs_get_empty (void) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_font_funcs_t * hb_font_funcs_reference (hb_font_funcs_t *ffuncs) @@ -288,7 +288,7 @@ hb_font_funcs_reference (hb_font_funcs_t *ffuncs) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_destroy (hb_font_funcs_t *ffuncs) @@ -315,7 +315,7 @@ hb_font_funcs_destroy (hb_font_funcs_t *ffuncs) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs, @@ -336,7 +336,7 @@ hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs, * * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ void * hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs, @@ -352,7 +352,7 @@ hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs) @@ -371,7 +371,7 @@ hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs) @@ -425,7 +425,7 @@ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_get_glyph (hb_font_t *font, @@ -444,7 +444,7 @@ hb_font_get_glyph (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_position_t hb_font_get_glyph_h_advance (hb_font_t *font, @@ -462,7 +462,7 @@ hb_font_get_glyph_h_advance (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_position_t hb_font_get_glyph_v_advance (hb_font_t *font, @@ -482,7 +482,7 @@ hb_font_get_glyph_v_advance (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_get_glyph_h_origin (hb_font_t *font, @@ -503,7 +503,7 @@ hb_font_get_glyph_h_origin (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_get_glyph_v_origin (hb_font_t *font, @@ -523,7 +523,7 @@ hb_font_get_glyph_v_origin (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_position_t hb_font_get_glyph_h_kerning (hb_font_t *font, @@ -542,7 +542,7 @@ hb_font_get_glyph_h_kerning (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_position_t hb_font_get_glyph_v_kerning (hb_font_t *font, @@ -561,7 +561,7 @@ hb_font_get_glyph_v_kerning (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_get_glyph_extents (hb_font_t *font, @@ -583,7 +583,7 @@ hb_font_get_glyph_extents (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_get_glyph_contour_point (hb_font_t *font, @@ -604,7 +604,7 @@ hb_font_get_glyph_contour_point (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_get_glyph_name (hb_font_t *font, @@ -625,7 +625,7 @@ hb_font_get_glyph_name (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_get_glyph_from_name (hb_font_t *font, @@ -648,7 +648,7 @@ hb_font_get_glyph_from_name (hb_font_t *font, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_get_glyph_advance_for_direction (hb_font_t *font, @@ -669,7 +669,7 @@ hb_font_get_glyph_advance_for_direction (hb_font_t *font, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_get_glyph_origin_for_direction (hb_font_t *font, @@ -690,7 +690,7 @@ hb_font_get_glyph_origin_for_direction (hb_font_t *font, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_add_glyph_origin_for_direction (hb_font_t *font, @@ -711,7 +711,7 @@ hb_font_add_glyph_origin_for_direction (hb_font_t *font, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_subtract_glyph_origin_for_direction (hb_font_t *font, @@ -733,7 +733,7 @@ hb_font_subtract_glyph_origin_for_direction (hb_font_t *font, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_get_glyph_kerning_for_direction (hb_font_t *font, @@ -755,7 +755,7 @@ hb_font_get_glyph_kerning_for_direction (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_get_glyph_extents_for_origin (hb_font_t *font, @@ -779,7 +779,7 @@ hb_font_get_glyph_extents_for_origin (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_get_glyph_contour_point_for_origin (hb_font_t *font, @@ -800,7 +800,7 @@ hb_font_get_glyph_contour_point_for_origin (hb_font_t *font, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_glyph_to_string (hb_font_t *font, @@ -822,7 +822,7 @@ hb_font_glyph_to_string (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_glyph_from_string (hb_font_t *font, @@ -845,7 +845,7 @@ hb_font_glyph_from_string (hb_font_t *font, * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_font_t * hb_font_create (hb_face_t *face) @@ -854,8 +854,6 @@ hb_font_create (hb_face_t *face) if (unlikely (!face)) face = hb_face_get_empty (); - if (unlikely (hb_object_is_inert (face))) - return hb_font_get_empty (); if (!(font = hb_object_create ())) return hb_font_get_empty (); @@ -863,6 +861,8 @@ hb_font_create (hb_face_t *face) font->face = hb_face_reference (face); font->klass = hb_font_funcs_get_empty (); + font->x_scale = font->y_scale = hb_face_get_upem (face); + return font; } @@ -874,20 +874,19 @@ hb_font_create (hb_face_t *face) * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_font_t * hb_font_create_sub_font (hb_font_t *parent) { if (unlikely (!parent)) - return hb_font_get_empty (); + parent = hb_font_get_empty (); hb_font_t *font = hb_font_create (parent->face); if (unlikely (hb_object_is_inert (font))) return font; - hb_font_make_immutable (parent); font->parent = hb_font_reference (parent); font->x_scale = parent->x_scale; @@ -905,7 +904,7 @@ hb_font_create_sub_font (hb_font_t *parent) * * Return value: (transfer full) * - * Since: 1.0 + * Since: 0.9.2 **/ hb_font_t * hb_font_get_empty (void) @@ -946,7 +945,7 @@ hb_font_get_empty (void) * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_font_t * hb_font_reference (hb_font_t *font) @@ -960,7 +959,7 @@ hb_font_reference (hb_font_t *font) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_destroy (hb_font_t *font) @@ -993,7 +992,7 @@ hb_font_destroy (hb_font_t *font) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_set_user_data (hb_font_t *font, @@ -1014,7 +1013,7 @@ hb_font_set_user_data (hb_font_t *font, * * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ void * hb_font_get_user_data (hb_font_t *font, @@ -1029,7 +1028,7 @@ hb_font_get_user_data (hb_font_t *font, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_make_immutable (hb_font_t *font) @@ -1037,6 +1036,9 @@ hb_font_make_immutable (hb_font_t *font) if (unlikely (hb_object_is_inert (font))) return; + if (font->parent) + hb_font_make_immutable (font->parent); + font->immutable = true; } @@ -1048,7 +1050,7 @@ hb_font_make_immutable (hb_font_t *font) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_is_immutable (hb_font_t *font) @@ -1056,6 +1058,32 @@ hb_font_is_immutable (hb_font_t *font) return font->immutable; } +/** + * hb_font_set_parent: + * @font: a font. + * @parent: new parent. + * + * Sets parent font of @font. + * + * Since: 1.0.5 + **/ +void +hb_font_set_parent (hb_font_t *font, + hb_font_t *parent) +{ + if (font->immutable) + return; + + if (!parent) + parent = hb_font_get_empty (); + + hb_font_t *old = font->parent; + + font->parent = hb_font_reference (parent); + + hb_font_destroy (old); +} + /** * hb_font_get_parent: * @font: a font. @@ -1064,7 +1092,7 @@ hb_font_is_immutable (hb_font_t *font) * * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_font_t * hb_font_get_parent (hb_font_t *font) @@ -1080,7 +1108,7 @@ hb_font_get_parent (hb_font_t *font) * * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_face_t * hb_font_get_face (hb_font_t *font) @@ -1098,7 +1126,7 @@ hb_font_get_face (hb_font_t *font) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_set_funcs (hb_font_t *font, @@ -1133,7 +1161,7 @@ hb_font_set_funcs (hb_font_t *font, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_set_funcs_data (hb_font_t *font, @@ -1163,7 +1191,7 @@ hb_font_set_funcs_data (hb_font_t *font, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_set_scale (hb_font_t *font, @@ -1185,7 +1213,7 @@ hb_font_set_scale (hb_font_t *font, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_get_scale (hb_font_t *font, @@ -1204,7 +1232,7 @@ hb_font_get_scale (hb_font_t *font, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_set_ppem (hb_font_t *font, @@ -1226,7 +1254,7 @@ hb_font_set_ppem (hb_font_t *font, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_get_ppem (hb_font_t *font, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.h b/src/3rdparty/harfbuzz-ng/src/hb-font.h index 7273db43ed..fb4a0eab5a 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-font.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-font.h @@ -80,12 +80,13 @@ hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs); /* glyph extents */ +/* Note that height is negative in coordinate systems that grow up. */ typedef struct hb_glyph_extents_t { - hb_position_t x_bearing; - hb_position_t y_bearing; - hb_position_t width; - hb_position_t height; + hb_position_t x_bearing; /* left side of glyph from origin. */ + hb_position_t y_bearing; /* top side of glyph from origin. */ + hb_position_t width; /* distance from left to right side. */ + hb_position_t height; /* distance from top to bottom side. */ } hb_glyph_extents_t; @@ -148,7 +149,7 @@ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void * * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, @@ -164,7 +165,7 @@ hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_set_glyph_h_advance_func (hb_font_funcs_t *ffuncs, @@ -180,7 +181,7 @@ hb_font_funcs_set_glyph_h_advance_func (hb_font_funcs_t *ffuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_set_glyph_v_advance_func (hb_font_funcs_t *ffuncs, @@ -196,7 +197,7 @@ hb_font_funcs_set_glyph_v_advance_func (hb_font_funcs_t *ffuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_set_glyph_h_origin_func (hb_font_funcs_t *ffuncs, @@ -212,7 +213,7 @@ hb_font_funcs_set_glyph_h_origin_func (hb_font_funcs_t *ffuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs, @@ -228,7 +229,7 @@ hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs, @@ -244,7 +245,7 @@ hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs, @@ -260,7 +261,7 @@ hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs, @@ -276,7 +277,7 @@ hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_set_glyph_contour_point_func (hb_font_funcs_t *ffuncs, @@ -292,7 +293,7 @@ hb_font_funcs_set_glyph_contour_point_func (hb_font_funcs_t *ffuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs, @@ -308,7 +309,7 @@ hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs, @@ -458,6 +459,10 @@ hb_font_make_immutable (hb_font_t *font); hb_bool_t hb_font_is_immutable (hb_font_t *font); +void +hb_font_set_parent (hb_font_t *font, + hb_font_t *parent); + hb_font_t * hb_font_get_parent (hb_font_t *font); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-mutex-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-mutex-private.hh index a8ea39ccfd..ed2703571c 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-mutex-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-mutex-private.hh @@ -39,7 +39,13 @@ /* We need external help for these */ -#if 0 +#if defined(HB_MUTEX_IMPL_INIT) \ + && defined(hb_mutex_impl_init) \ + && defined(hb_mutex_impl_lock) \ + && defined(hb_mutex_impl_unlock) \ + && defined(hb_mutex_impl_finish) + +/* Defined externally, i.e. in config.h; must have typedef'ed hb_mutex_impl_t as well. */ #elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__)) @@ -113,10 +119,12 @@ typedef int hb_mutex_impl_t; #define hb_mutex_impl_unlock(M) HB_STMT_START {} HB_STMT_END #define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END + #endif #define HB_MUTEX_INIT {HB_MUTEX_IMPL_INIT} + struct hb_mutex_t { /* TODO Add tracing. */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-object-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-object-private.hh index 7bd0f1624b..6b73ff92d0 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-object-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-object-private.hh @@ -47,19 +47,22 @@ /* reference_count */ -#define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1) -#define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE} +#define HB_REFERENCE_COUNT_INERT_VALUE -1 +#define HB_REFERENCE_COUNT_POISON_VALUE -0x0000DEAD +#define HB_REFERENCE_COUNT_INIT {HB_ATOMIC_INT_INIT(HB_REFERENCE_COUNT_INERT_VALUE)} + struct hb_reference_count_t { hb_atomic_int_t ref_count; - inline void init (int v) { ref_count = v; } - inline int inc (void) { return hb_atomic_int_add (const_cast (ref_count), 1); } - inline int dec (void) { return hb_atomic_int_add (const_cast (ref_count), -1); } - inline void finish (void) { ref_count = HB_REFERENCE_COUNT_INVALID_VALUE; } - - inline bool is_invalid (void) const { return ref_count == HB_REFERENCE_COUNT_INVALID_VALUE; } + inline void init (int v) { ref_count.set_unsafe (v); } + inline int get_unsafe (void) const { return ref_count.get_unsafe (); } + inline int inc (void) { return ref_count.inc (); } + inline int dec (void) { return ref_count.dec (); } + inline void finish (void) { ref_count.set_unsafe (HB_REFERENCE_COUNT_POISON_VALUE); } + inline bool is_inert (void) const { return ref_count.get_unsafe () == HB_REFERENCE_COUNT_INERT_VALUE; } + inline bool is_valid (void) const { return ref_count.get_unsafe () > 0; } }; @@ -102,7 +105,7 @@ struct hb_object_header_t hb_reference_count_t ref_count; hb_user_data_array_t user_data; -#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INVALID, HB_USER_DATA_ARRAY_INIT} +#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INIT, HB_USER_DATA_ARRAY_INIT} private: ASSERT_POD (); @@ -117,7 +120,7 @@ static inline void hb_object_trace (const Type *obj, const char *function) DEBUG_MSG (OBJECT, (void *) obj, "%s refcount=%d", function, - obj ? obj->header.ref_count.ref_count : 0); + obj ? obj->header.ref_count.get_unsafe () : 0); } template @@ -141,7 +144,12 @@ static inline void hb_object_init (Type *obj) template static inline bool hb_object_is_inert (const Type *obj) { - return unlikely (obj->header.ref_count.is_invalid ()); + return unlikely (obj->header.ref_count.is_inert ()); +} +template +static inline bool hb_object_is_valid (const Type *obj) +{ + return likely (obj->header.ref_count.is_valid ()); } template static inline Type *hb_object_reference (Type *obj) @@ -149,6 +157,7 @@ static inline Type *hb_object_reference (Type *obj) hb_object_trace (obj, HB_FUNC); if (unlikely (!obj || hb_object_is_inert (obj))) return obj; + assert (hb_object_is_valid (obj)); obj->header.ref_count.inc (); return obj; } @@ -158,6 +167,7 @@ static inline bool hb_object_destroy (Type *obj) hb_object_trace (obj, HB_FUNC); if (unlikely (!obj || hb_object_is_inert (obj))) return false; + assert (hb_object_is_valid (obj)); if (obj->header.ref_count.dec () != 1) return false; @@ -174,6 +184,7 @@ static inline bool hb_object_set_user_data (Type *obj, { if (unlikely (!obj || hb_object_is_inert (obj))) return false; + assert (hb_object_is_valid (obj)); return obj->header.user_data.set (key, data, destroy, replace); } @@ -183,6 +194,7 @@ static inline void *hb_object_get_user_data (Type *obj, { if (unlikely (!obj || hb_object_is_inert (obj))) return NULL; + assert (hb_object_is_valid (obj)); return obj->header.user_data.get (key); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh index 178bc7ccb8..152230a0e5 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh @@ -56,7 +56,7 @@ typedef struct TableRecord inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this)); + return_trace (c->check_struct (this)); } Tag tag; /* 4-byte identifier. */ @@ -106,7 +106,7 @@ typedef struct OffsetTable inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && c->check_array (tables, TableRecord::static_size, numTables)); + return_trace (c->check_struct (this) && c->check_array (tables, TableRecord::static_size, numTables)); } protected: @@ -135,7 +135,7 @@ struct TTCHeaderVersion1 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (table.sanitize (c, this)); + return_trace (table.sanitize (c, this)); } protected: @@ -175,11 +175,11 @@ struct TTCHeader inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!u.header.version.sanitize (c))) return TRACE_RETURN (false); + if (unlikely (!u.header.version.sanitize (c))) return_trace (false); switch (u.header.version.major) { case 2: /* version 2 is compatible with version 1 */ - case 1: return TRACE_RETURN (u.version1.sanitize (c)); - default:return TRACE_RETURN (true); + case 1: return_trace (u.version1.sanitize (c)); + default:return_trace (true); } } @@ -240,14 +240,14 @@ struct OpenTypeFontFile inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!u.tag.sanitize (c))) return TRACE_RETURN (false); + if (unlikely (!u.tag.sanitize (c))) return_trace (false); switch (u.tag) { case CFFTag: /* All the non-collection tags */ case TrueTag: case Typ1Tag: - case TrueTypeTag: return TRACE_RETURN (u.fontFace.sanitize (c)); - case TTCTag: return TRACE_RETURN (u.ttcHeader.sanitize (c)); - default: return TRACE_RETURN (true); + case TrueTypeTag: return_trace (u.fontFace.sanitize (c)); + case TTCTag: return_trace (u.ttcHeader.sanitize (c)); + default: return_trace (true); } } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh index 75a0f568d1..f053502ded 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh @@ -154,6 +154,20 @@ ASSERT_STATIC (Type::min_size + 1 <= sizeof (_Null##Type)) #define Null(Type) Null() +/* + * Dispatch + */ + +template +struct hb_dispatch_context_t +{ + static const unsigned int max_debug_depth = MaxDebugDepth; + typedef Return return_t; + template + inline bool may_dispatch (const T *obj, const F *format) { return true; } + static return_t no_dispatch_return_value (void) { return Context::default_return_value (); } +}; + /* * Sanitize @@ -174,17 +188,23 @@ ASSERT_STATIC (Type::min_size + 1 <= sizeof (_Null##Type)) #define HB_SANITIZE_MAX_EDITS 100 #endif -struct hb_sanitize_context_t +struct hb_sanitize_context_t : + hb_dispatch_context_t { + inline hb_sanitize_context_t (void) : + debug_depth (0), + start (NULL), end (NULL), + writable (false), edit_count (0), + blob (NULL) {} + inline const char *get_name (void) { return "SANITIZE"; } - static const unsigned int max_debug_depth = HB_DEBUG_SANITIZE; - typedef bool return_t; template inline bool may_dispatch (const T *obj, const F *format) { return format->sanitize (this); } template inline return_t dispatch (const T &obj) { return obj.sanitize (this); } static return_t default_return_value (void) { return true; } + static return_t no_dispatch_return_value (void) { return false; } bool stop_sublookup_iteration (const return_t r) const { return !r; } inline void init (hb_blob_t *b) @@ -295,7 +315,7 @@ template struct Sanitizer { static hb_blob_t *sanitize (hb_blob_t *blob) { - hb_sanitize_context_t c[1] = {{0, NULL, NULL, false, 0, NULL}}; + hb_sanitize_context_t c[1]; bool sane; /* TODO is_sane() stuff */ @@ -379,9 +399,9 @@ struct Sanitizer struct hb_serialize_context_t { - inline hb_serialize_context_t (void *start, unsigned int size) + inline hb_serialize_context_t (void *start_, unsigned int size) { - this->start = (char *) start; + this->start = (char *) start_; this->end = this->start + size; this->ran_out_of_room = false; @@ -475,10 +495,10 @@ struct hb_serialize_context_t return reinterpret_cast (&obj); } - inline void truncate (void *head) + inline void truncate (void *new_head) { - assert (this->start < head && head <= this->head); - this->head = (char *) head; + assert (this->start < new_head && new_head <= this->head); + this->head = (char *) new_head; } unsigned int debug_depth; @@ -535,6 +555,20 @@ struct Supplier template struct BEInt; +template +struct BEInt +{ + public: + inline void set (Type V) + { + v = V; + } + inline operator Type (void) const + { + return v; + } + private: uint8_t v; +}; template struct BEInt { @@ -610,7 +644,7 @@ struct IntType inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (likely (c->check_struct (this))); + return_trace (likely (c->check_struct (this))); } protected: BEInt v; @@ -618,7 +652,7 @@ struct IntType DEFINE_SIZE_STATIC (Size); }; -typedef uint8_t BYTE; /* 8-bit unsigned integer. */ +typedef IntType BYTE; /* 8-bit unsigned integer. */ typedef IntType USHORT; /* 16-bit unsigned integer. */ typedef IntType SHORT; /* 16-bit signed integer. */ typedef IntType ULONG; /* 32-bit unsigned integer. */ @@ -638,7 +672,7 @@ struct LONGDATETIME inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (likely (c->check_struct (this))); + return_trace (likely (c->check_struct (this))); } protected: LONG major; @@ -715,7 +749,7 @@ struct FixedVersion inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this)); + return_trace (c->check_struct (this)); } USHORT major; @@ -751,21 +785,21 @@ struct OffsetTo : Offset inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); + if (unlikely (!c->check_struct (this))) return_trace (false); unsigned int offset = *this; - if (unlikely (!offset)) return TRACE_RETURN (true); + if (unlikely (!offset)) return_trace (true); const Type &obj = StructAtOffset (base, offset); - return TRACE_RETURN (likely (obj.sanitize (c)) || neuter (c)); + return_trace (likely (obj.sanitize (c)) || neuter (c)); } template inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const { TRACE_SANITIZE (this); - if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); + if (unlikely (!c->check_struct (this))) return_trace (false); unsigned int offset = *this; - if (unlikely (!offset)) return TRACE_RETURN (true); + if (unlikely (!offset)) return_trace (true); const Type &obj = StructAtOffset (base, offset); - return TRACE_RETURN (likely (obj.sanitize (c, user_data)) || neuter (c)); + return_trace (likely (obj.sanitize (c, user_data)) || neuter (c)); } /* Set the offset to Null */ @@ -816,10 +850,10 @@ struct ArrayOf unsigned int items_len) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); + if (unlikely (!c->extend_min (*this))) return_trace (false); len.set (items_len); /* TODO(serialize) Overflow? */ - if (unlikely (!c->extend (*this))) return TRACE_RETURN (false); - return TRACE_RETURN (true); + if (unlikely (!c->extend (*this))) return_trace (false); + return_trace (true); } inline bool serialize (hb_serialize_context_t *c, @@ -827,17 +861,17 @@ struct ArrayOf unsigned int items_len) { TRACE_SERIALIZE (this); - if (unlikely (!serialize (c, items_len))) return TRACE_RETURN (false); + if (unlikely (!serialize (c, items_len))) return_trace (false); for (unsigned int i = 0; i < items_len; i++) array[i] = items[i]; items.advance (items_len); - return TRACE_RETURN (true); + return_trace (true); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); + if (unlikely (!sanitize_shallow (c))) return_trace (false); /* Note: for structs that do not reference other structs, * we do not need to call their sanitize() as we already did @@ -848,28 +882,28 @@ struct ArrayOf */ (void) (false && array[0].sanitize (c)); - return TRACE_RETURN (true); + return_trace (true); } inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); + if (unlikely (!sanitize_shallow (c))) return_trace (false); unsigned int count = len; for (unsigned int i = 0; i < count; i++) if (unlikely (!array[i].sanitize (c, base))) - return TRACE_RETURN (false); - return TRACE_RETURN (true); + return_trace (false); + return_trace (true); } template inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const { TRACE_SANITIZE (this); - if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); + if (unlikely (!sanitize_shallow (c))) return_trace (false); unsigned int count = len; for (unsigned int i = 0; i < count; i++) if (unlikely (!array[i].sanitize (c, base, user_data))) - return TRACE_RETURN (false); - return TRACE_RETURN (true); + return_trace (false); + return_trace (true); } template @@ -886,7 +920,7 @@ struct ArrayOf inline bool sanitize_shallow (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && c->check_array (this, Type::static_size, len)); + return_trace (c->check_struct (this) && c->check_array (array, Type::static_size, len)); } public: @@ -913,13 +947,13 @@ struct OffsetListOf : OffsetArrayOf inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (OffsetArrayOf::sanitize (c, this)); + return_trace (OffsetArrayOf::sanitize (c, this)); } template inline bool sanitize (hb_sanitize_context_t *c, T user_data) const { TRACE_SANITIZE (this); - return TRACE_RETURN (OffsetArrayOf::sanitize (c, this, user_data)); + return_trace (OffsetArrayOf::sanitize (c, this, user_data)); } }; @@ -941,14 +975,14 @@ struct HeadlessArrayOf unsigned int items_len) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); + if (unlikely (!c->extend_min (*this))) return_trace (false); len.set (items_len); /* TODO(serialize) Overflow? */ - if (unlikely (!items_len)) return TRACE_RETURN (true); - if (unlikely (!c->extend (*this))) return TRACE_RETURN (false); + if (unlikely (!items_len)) return_trace (true); + if (unlikely (!c->extend (*this))) return_trace (false); for (unsigned int i = 0; i < items_len - 1; i++) array[i] = items[i]; items.advance (items_len - 1); - return TRACE_RETURN (true); + return_trace (true); } inline bool sanitize_shallow (hb_sanitize_context_t *c) const @@ -960,7 +994,7 @@ struct HeadlessArrayOf inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); + if (unlikely (!sanitize_shallow (c))) return_trace (false); /* Note: for structs that do not reference other structs, * we do not need to call their sanitize() as we already did @@ -971,7 +1005,7 @@ struct HeadlessArrayOf */ (void) (false && array[0].sanitize (c)); - return TRACE_RETURN (true); + return_trace (true); } LenType len; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh index 0482312553..c9161f0ef4 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh @@ -54,7 +54,7 @@ struct CmapSubtableFormat0 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this)); + return_trace (c->check_struct (this)); } protected: @@ -130,7 +130,7 @@ struct CmapSubtableFormat4 { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) - return TRACE_RETURN (false); + return_trace (false); if (unlikely (!c->check_range (this, length))) { @@ -141,10 +141,10 @@ struct CmapSubtableFormat4 (uintptr_t) (c->end - (char *) this)); if (!c->try_set (&length, new_length)) - return TRACE_RETURN (false); + return_trace (false); } - return TRACE_RETURN (16 + 4 * (unsigned int) segCountX2 <= length); + return_trace (16 + 4 * (unsigned int) segCountX2 <= length); } protected: @@ -187,7 +187,7 @@ struct CmapSubtableLongGroup inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this)); + return_trace (c->check_struct (this)); } private: @@ -215,7 +215,7 @@ struct CmapSubtableTrimmed inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && glyphIdArray.sanitize (c)); + return_trace (c->check_struct (this) && glyphIdArray.sanitize (c)); } protected: @@ -248,7 +248,7 @@ struct CmapSubtableLongSegmented inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && groups.sanitize (c)); + return_trace (c->check_struct (this) && groups.sanitize (c)); } protected: @@ -295,7 +295,7 @@ struct UnicodeValueRange inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this)); + return_trace (c->check_struct (this)); } UINT24 startUnicodeValue; /* First value in this range. */ @@ -317,7 +317,7 @@ struct UVSMapping inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this)); + return_trace (c->check_struct (this)); } UINT24 unicodeValue; /* Base Unicode value of the UVS */ @@ -357,9 +357,9 @@ struct VariationSelectorRecord inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && - defaultUVS.sanitize (c, base) && - nonDefaultUVS.sanitize (c, base)); + return_trace (c->check_struct (this) && + defaultUVS.sanitize (c, base) && + nonDefaultUVS.sanitize (c, base)); } UINT24 varSelector; /* Variation selector. */ @@ -383,8 +383,8 @@ struct CmapSubtableFormat14 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && - record.sanitize (c, this)); + return_trace (c->check_struct (this) && + record.sanitize (c, this)); } protected: @@ -429,16 +429,16 @@ struct CmapSubtable inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); + if (!u.format.sanitize (c)) return_trace (false); switch (u.format) { - case 0: return TRACE_RETURN (u.format0 .sanitize (c)); - case 4: return TRACE_RETURN (u.format4 .sanitize (c)); - case 6: return TRACE_RETURN (u.format6 .sanitize (c)); - case 10: return TRACE_RETURN (u.format10.sanitize (c)); - case 12: return TRACE_RETURN (u.format12.sanitize (c)); - case 13: return TRACE_RETURN (u.format13.sanitize (c)); - case 14: return TRACE_RETURN (u.format14.sanitize (c)); - default:return TRACE_RETURN (true); + case 0: return_trace (u.format0 .sanitize (c)); + case 4: return_trace (u.format4 .sanitize (c)); + case 6: return_trace (u.format6 .sanitize (c)); + case 10: return_trace (u.format10.sanitize (c)); + case 12: return_trace (u.format12.sanitize (c)); + case 13: return_trace (u.format13.sanitize (c)); + case 14: return_trace (u.format14.sanitize (c)); + default:return_trace (true); } } @@ -473,8 +473,8 @@ struct EncodingRecord inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && - subtable.sanitize (c, base)); + return_trace (c->check_struct (this) && + subtable.sanitize (c, base)); } USHORT platformID; /* Platform ID. */ @@ -509,9 +509,9 @@ struct cmap inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && - likely (version == 0) && - encodingRecord.sanitize (c, this)); + return_trace (c->check_struct (this) && + likely (version == 0) && + encodingRecord.sanitize (c, this)); } USHORT version; /* Table version number (0). */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc index 2af2f54a75..69d2503abb 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc @@ -31,6 +31,8 @@ #include "hb-font-private.hh" #include "hb-ot-cmap-table.hh" +#include "hb-ot-glyf-table.hh" +#include "hb-ot-head-table.hh" #include "hb-ot-hhea-table.hh" #include "hb-ot-hmtx-table.hh" @@ -45,9 +47,9 @@ struct hb_ot_face_metrics_accelerator_t inline void init (hb_face_t *face, hb_tag_t _hea_tag, hb_tag_t _mtx_tag, - unsigned int default_advance) + unsigned int default_advance_) { - this->default_advance = default_advance; + this->default_advance = default_advance_; this->num_metrics = face->get_num_glyphs (); hb_blob_t *_hea_blob = OT::Sanitizer::sanitize (face->reference_table (_hea_tag)); @@ -57,7 +59,7 @@ struct hb_ot_face_metrics_accelerator_t this->blob = OT::Sanitizer::sanitize (face->reference_table (_mtx_tag)); if (unlikely (!this->num_advances || - 2 * (this->num_advances + this->num_metrics) < hb_blob_get_length (this->blob))) + 2 * (this->num_advances + this->num_metrics) > hb_blob_get_length (this->blob))) { this->num_metrics = this->num_advances = 0; hb_blob_destroy (this->blob); @@ -76,8 +78,8 @@ struct hb_ot_face_metrics_accelerator_t if (unlikely (glyph >= this->num_metrics)) { /* If this->num_metrics is zero, it means we don't have the metrics table - * for this direction: return one EM. Otherwise, it means that the glyph - * index is out of bound: return zero. */ + * for this direction: return default advance. Otherwise, it means that the + * glyph index is out of bound: return zero. */ if (this->num_metrics) return 0; else @@ -91,6 +93,79 @@ struct hb_ot_face_metrics_accelerator_t } }; +struct hb_ot_face_glyf_accelerator_t +{ + bool short_offset; + unsigned int num_glyphs; + const OT::loca *loca; + const OT::glyf *glyf; + hb_blob_t *loca_blob; + hb_blob_t *glyf_blob; + unsigned int glyf_len; + + inline void init (hb_face_t *face) + { + hb_blob_t *head_blob = OT::Sanitizer::sanitize (face->reference_table (HB_OT_TAG_head)); + const OT::head *head = OT::Sanitizer::lock_instance (head_blob); + if ((unsigned int) head->indexToLocFormat > 1 || head->glyphDataFormat != 0) + { + /* Unknown format. Leave num_glyphs=0, that takes care of disabling us. */ + hb_blob_destroy (head_blob); + return; + } + this->short_offset = 0 == head->indexToLocFormat; + hb_blob_destroy (head_blob); + + this->loca_blob = OT::Sanitizer::sanitize (face->reference_table (HB_OT_TAG_loca)); + this->loca = OT::Sanitizer::lock_instance (this->loca_blob); + this->glyf_blob = OT::Sanitizer::sanitize (face->reference_table (HB_OT_TAG_glyf)); + this->glyf = OT::Sanitizer::lock_instance (this->glyf_blob); + + this->num_glyphs = MAX (1u, hb_blob_get_length (this->loca_blob) / (this->short_offset ? 2 : 4)) - 1; + this->glyf_len = hb_blob_get_length (this->glyf_blob); + } + + inline void fini (void) + { + hb_blob_destroy (this->loca_blob); + hb_blob_destroy (this->glyf_blob); + } + + inline bool get_extents (hb_codepoint_t glyph, + hb_glyph_extents_t *extents) const + { + if (unlikely (glyph >= this->num_glyphs)) + return false; + + unsigned int start_offset, end_offset; + if (this->short_offset) + { + start_offset = 2 * this->loca->u.shortsZ[glyph]; + end_offset = 2 * this->loca->u.shortsZ[glyph + 1]; + } + else + { + start_offset = this->loca->u.longsZ[glyph]; + end_offset = this->loca->u.longsZ[glyph + 1]; + } + + if (start_offset > end_offset || end_offset > this->glyf_len) + return false; + + if (end_offset - start_offset < OT::glyfGlyphHeader::static_size) + return true; /* Empty glyph; zero extents. */ + + const OT::glyfGlyphHeader &glyph_header = OT::StructAtOffset (this->glyf, start_offset); + + extents->x_bearing = MIN (glyph_header.xMin, glyph_header.xMax); + extents->y_bearing = MAX (glyph_header.yMin, glyph_header.yMax); + extents->width = MAX (glyph_header.xMin, glyph_header.xMax) - extents->x_bearing; + extents->height = MIN (glyph_header.yMin, glyph_header.yMax) - extents->y_bearing; + + return true; + } +}; + struct hb_ot_face_cmap_accelerator_t { const OT::CmapSubtable *table; @@ -114,6 +189,7 @@ struct hb_ot_face_cmap_accelerator_t if (!subtable) subtable = cmap->find_subtable (0, 2); if (!subtable) subtable = cmap->find_subtable (0, 1); if (!subtable) subtable = cmap->find_subtable (0, 0); + if (!subtable) subtable = cmap->find_subtable (3, 0); /* Meh. */ if (!subtable) subtable = &OT::Null(OT::CmapSubtable); @@ -157,14 +233,14 @@ struct hb_ot_font_t hb_ot_face_cmap_accelerator_t cmap; hb_ot_face_metrics_accelerator_t h_metrics; hb_ot_face_metrics_accelerator_t v_metrics; + hb_ot_face_glyf_accelerator_t glyf; }; static hb_ot_font_t * -_hb_ot_font_create (hb_font_t *font) +_hb_ot_font_create (hb_face_t *face) { hb_ot_font_t *ot_font = (hb_ot_font_t *) calloc (1, sizeof (hb_ot_font_t)); - hb_face_t *face = font->face; if (unlikely (!ot_font)) return NULL; @@ -174,6 +250,7 @@ _hb_ot_font_create (hb_font_t *font) ot_font->cmap.init (face); ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, upem>>1); ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, upem); /* TODO Can we do this lazily? */ + ot_font->glyf.init (face); return ot_font; } @@ -184,6 +261,7 @@ _hb_ot_font_destroy (hb_ot_font_t *ot_font) ot_font->cmap.fini (); ot_font->h_metrics.fini (); ot_font->v_metrics.fini (); + ot_font->glyf.fini (); free (ot_font); } @@ -219,7 +297,7 @@ hb_ot_get_glyph_v_advance (hb_font_t *font HB_UNUSED, void *user_data HB_UNUSED) { const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; - return font->em_scale_y (-ot_font->v_metrics.get_advance (glyph)); + return font->em_scale_y (-(int) ot_font->v_metrics.get_advance (glyph)); } static hb_bool_t @@ -275,8 +353,13 @@ hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED, hb_glyph_extents_t *extents, void *user_data HB_UNUSED) { - /* TODO */ - return false; + const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; + bool ret = ot_font->glyf.get_extents (glyph, extents); + extents->x_bearing = font->em_scale_x (extents->x_bearing); + extents->y_bearing = font->em_scale_y (extents->y_bearing); + extents->width = font->em_scale_x (extents->width); + extents->height = font->em_scale_y (extents->height); + return ret; } static hb_bool_t @@ -334,10 +417,13 @@ _hb_ot_get_font_funcs (void) } +/** + * Since: 0.9.28 + **/ void hb_ot_font_set_funcs (hb_font_t *font) { - hb_ot_font_t *ot_font = _hb_ot_font_create (font); + hb_ot_font_t *ot_font = _hb_ot_font_create (font->face); if (unlikely (!ot_font)) return; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.h index 7a8c04ac33..b9947a16bc 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.h @@ -24,6 +24,10 @@ * Google Author(s): Behdad Esfahbod, Roozbeh Pournader */ +#ifndef HB_OT_H_IN +#error "Include instead." +#endif + #ifndef HB_OT_FONT_H #define HB_OT_FONT_H diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh new file mode 100644 index 0000000000..9e5af6d10d --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh @@ -0,0 +1,104 @@ +/* + * Copyright © 2015 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_GLYF_TABLE_HH +#define HB_OT_GLYF_TABLE_HH + +#include "hb-open-type-private.hh" + + +namespace OT { + + +/* + * loca -- Index to Location + */ + +#define HB_OT_TAG_loca HB_TAG('l','o','c','a') + + +struct loca +{ + static const hb_tag_t tableTag = HB_OT_TAG_loca; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (true); + } + + public: + union { + USHORT shortsZ[VAR]; /* Location offset divided by 2. */ + ULONG longsZ[VAR]; /* Location offset. */ + } u; + DEFINE_SIZE_ARRAY (0, u.longsZ); +}; + + +/* + * glyf -- TrueType Glyph Data + */ + +#define HB_OT_TAG_glyf HB_TAG('g','l','y','f') + + +struct glyf +{ + static const hb_tag_t tableTag = HB_OT_TAG_glyf; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + /* We don't check for anything specific here. The users of the + * struct do all the hard work... */ + return_trace (true); + } + + public: + BYTE dataX[VAR]; /* Glyphs data. */ + + DEFINE_SIZE_ARRAY (0, dataX); +}; + +struct glyfGlyphHeader +{ + SHORT numberOfContours; /* If the number of contours is + * greater than or equal to zero, + * this is a simple glyph; if negative, + * this is a composite glyph. */ + SHORT xMin; /* Minimum x for coordinate data. */ + SHORT yMin; /* Minimum y for coordinate data. */ + SHORT xMax; /* Maximum x for coordinate data. */ + SHORT yMax; /* Maximum y for coordinate data. */ + + DEFINE_SIZE_STATIC (10); +}; + +} /* namespace OT */ + + +#endif /* HB_OT_GLYF_TABLE_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh index 268f133408..fc351cfb48 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh @@ -55,7 +55,7 @@ struct head inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1)); + return_trace (c->check_struct (this) && likely (version.major == 1)); } protected: @@ -138,9 +138,10 @@ struct head * 2: Like 1 but also contains neutrals; * -1: Only strongly right to left; * -2: Like -1 but also contains neutrals. */ + public: SHORT indexToLocFormat; /* 0 for short offsets, 1 for long. */ SHORT glyphDataFormat; /* 0 for current format. */ - public: + DEFINE_SIZE_STATIC (54); }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh index 992fe55202..24114534a7 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh @@ -52,7 +52,7 @@ struct _hea inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1)); + return_trace (c->check_struct (this) && likely (version.major == 1)); } public: diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh index a0e3855a84..49056e6769 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh @@ -62,7 +62,7 @@ struct _mtx TRACE_SANITIZE (this); /* We don't check for anything specific here. The users of the * struct do all the hard work... */ - return TRACE_RETURN (true); + return_trace (true); } public: diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh index 3db7f57ab4..ea61f5c1bd 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh @@ -44,7 +44,7 @@ namespace OT { #define NOT_COVERED ((unsigned int) -1) -#define MAX_NESTING_LEVEL 8 +#define MAX_NESTING_LEVEL 6 #define MAX_CONTEXT_LENGTH 64 @@ -75,7 +75,7 @@ struct Record { TRACE_SANITIZE (this); const sanitize_closure_t closure = {tag, base}; - return TRACE_RETURN (c->check_struct (this) && offset.sanitize (c, base, &closure)); + return_trace (c->check_struct (this) && offset.sanitize (c, base, &closure)); } Tag tag; /* 4-byte Tag identifier */ @@ -131,7 +131,7 @@ struct RecordListOf : RecordArrayOf inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (RecordArrayOf::sanitize (c, this)); + return_trace (RecordArrayOf::sanitize (c, this)); } }; @@ -145,7 +145,7 @@ struct RangeRecord inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this)); + return_trace (c->check_struct (this)); } inline bool intersects (const hb_set_t *glyphs) const { @@ -211,7 +211,7 @@ struct LangSys const Record::sanitize_closure_t * = NULL) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && featureIndex.sanitize (c)); + return_trace (c->check_struct (this) && featureIndex.sanitize (c)); } Offset<> lookupOrderZ; /* = Null (reserved for an offset to a @@ -251,7 +251,7 @@ struct Script const Record