From eb4bcdd8cec77c558cc75d31730cff89852dd684 Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Thu, 4 Aug 2016 18:43:42 +0300 Subject: QNativeSocketEngine::option(): return a correct value on invalid call Instead of 'true', it should be '-1'. Change-Id: I5e8f99153da68d34b37477ef4cedbc447fba347f Reviewed-by: Thiago Macieira Reviewed-by: Edward Welbourne --- src/network/socket/qnativesocketengine_unix.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index 5dfc6480da..1ce12edef1 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -307,7 +307,7 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co // handle non-getsockopt cases first if (opt == QNativeSocketEngine::BindExclusively || opt == QNativeSocketEngine::NonBlockingSocketOption || opt == QNativeSocketEngine::BroadcastSocketOption) - return true; + return -1; int n, level; int v = -1; -- cgit v1.2.3 From 434c52269564c84e3ea57242b7aaa2fd7cad3f54 Mon Sep 17 00:00:00 2001 From: David Faure Date: Thu, 4 Aug 2016 10:01:21 +0200 Subject: Improve performance of QColor::name, now more than 4 times faster Before: HexRgb: 0.00230 ms per iteration, HexArgb: 0.00290 ms per iteration After: HexRgb: 0.00051 ms per iteration, HexArgb: 0.00061 ms per iteration This showed up as a relevant optimization when profiling KIconLoader which uses QColor::name() as part of the key -- thanks to Mark Gaiser for the investigation and first suggestion of a solution. I have also seen customer code writing a replacement for QColor::name() because it was too slow to be used as a hash key. Change-Id: I009ccdd712ea0d869d466e2c9894e0cea58f0e68 Reviewed-by: Marc Mutz --- src/gui/painting/qcolor.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index 3f30c061dc..d0a60f3704 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -521,9 +521,10 @@ QString QColor::name(NameFormat format) const { switch (format) { case HexRgb: - return QString::asprintf("#%02x%02x%02x", red(), green(), blue()); + return QLatin1Char('#') + QString::number(rgba() | 0x1000000, 16).rightRef(6); case HexArgb: - return QString::asprintf("#%02x%02x%02x%02x", alpha(), red(), green(), blue()); + // it's called rgba() but it does return AARRGGBB + return QLatin1Char('#') + QString::number(rgba() | 0x100000000, 16).rightRef(8); } return QString(); } -- cgit v1.2.3 From 4cb44c744c7d15658df79b801296b98fdc956336 Mon Sep 17 00:00:00 2001 From: Jesus Fernandez Date: Thu, 4 Aug 2016 17:01:37 +0200 Subject: Added pointer check in QFontDatabase::load CID 11131 (#1 of 1): Dereference after null check (FORWARD_NULL)46. var_deref_op: Dereferencing null pointer fe. Change-Id: Ifc0cd0b208db511516db93c3d0e0367299df6d80 Reviewed-by: Timur Pocheptsov Reviewed-by: Konstantin Ritt --- src/gui/text/qfontdatabase.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 7b88a73c61..074d9707f1 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -2799,6 +2799,7 @@ void QFontDatabase::load(const QFontPrivate *d, int script) req.fallBackFamilies.clear(); } + Q_ASSERT(fe); if (fe->symbol || (d->request.styleStrategy & QFont::NoFontMerging)) { for (int i = 0; i < QChar::ScriptCount; ++i) { if (!d->engineData->engines[i]) { -- cgit v1.2.3 From 4e6440acf8e09abbb2b2aa208f0241416154e090 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 4 May 2016 15:21:17 +0200 Subject: Improve reliability of callgrind benchmark results When running under callgrind, do not bother with the use of the watchdog. The constructor waits for the thread to start, which adds an overall run-time cost that depends on the OS scheduling. Change-Id: I162e2e311c43a6892ebc67dea39899e40babb61d Reviewed-by: Robin Burchell --- src/testlib/qtestcase.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index d674b0af7a..fe680e19aa 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -2548,8 +2548,13 @@ static void qInvokeTestMethods(QObject *testObject) invokeMethod(testObject, "initTestCase_data()"); QScopedPointer watchDog; - if (!debuggerPresent()) + if (!debuggerPresent() +#ifdef QTESTLIB_USE_VALGRIND + && QBenchmarkGlobalData::current->mode() != QBenchmarkGlobalData::CallgrindChildProcess +#endif + ) { watchDog.reset(new WatchDog); + } if (!QTestResult::skipCurrentTest() && !QTest::currentTestFailed()) { invokeMethod(testObject, "initTestCase()"); -- cgit v1.2.3 From 131b7c8f6467abe07143099aa8b85e594bb9111b Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 28 Jul 2016 08:41:05 +0200 Subject: Fix permissions on lock files on Unix We should create the files with 0666 and let the umask take care of adjusting to the final permissions in the file system. [ChangeLog][QtCore][QLockFile] Fixed permissions on lock files on Unix to allow for adjustments via umask. Change-Id: Iee6a6ac3920d0ffd4465f54ac6e955f7fe087173 Reviewed-by: Denis Shienkov Reviewed-by: Edward Welbourne Reviewed-by: Thiago Macieira Reviewed-by: David Faure --- src/corelib/io/qlockfile_unix.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp index 57c689ac81..7bef253e59 100644 --- a/src/corelib/io/qlockfile_unix.cpp +++ b/src/corelib/io/qlockfile_unix.cpp @@ -176,7 +176,7 @@ QLockFile::LockError QLockFilePrivate::tryLock_sys() % localHostName() % '\n'; const QByteArray lockFileName = QFile::encodeName(fileName); - const int fd = qt_safe_open(lockFileName.constData(), O_WRONLY | O_CREAT | O_EXCL, 0644); + const int fd = qt_safe_open(lockFileName.constData(), O_WRONLY | O_CREAT | O_EXCL, 0666); if (fd < 0) { switch (errno) { case EEXIST: @@ -217,7 +217,7 @@ QLockFile::LockError QLockFilePrivate::tryLock_sys() bool QLockFilePrivate::removeStaleLock() { const QByteArray lockFileName = QFile::encodeName(fileName); - const int fd = qt_safe_open(lockFileName.constData(), O_WRONLY, 0644); + const int fd = qt_safe_open(lockFileName.constData(), O_WRONLY, 0666); if (fd < 0) // gone already? return false; bool success = setNativeLocks(fileName, fd) && (::unlink(lockFileName) == 0); -- cgit v1.2.3 From 874852d62504f70c148ddf77c9a6f17c37aeee9c Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Sat, 6 Aug 2016 19:24:48 +0200 Subject: QMap: remove statement about STL support during Qt's own configuration Since STL support is mandatory in Qt 5, the sentence is a tautology and can be removed. Change-Id: I8676368cc917aa00a85b1113ed2a47694427b2ce Reviewed-by: Marc Mutz --- src/corelib/tools/qmap.cpp | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src') diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp index 27ae07441e..ec54b138f2 100644 --- a/src/corelib/tools/qmap.cpp +++ b/src/corelib/tools/qmap.cpp @@ -533,9 +533,6 @@ void QMapDataBase::freeData(QMapDataBase *d) Constructs a copy of \a other. - This function is only available if Qt is configured with STL - compatibility enabled. - \sa toStdMap() */ @@ -552,9 +549,6 @@ void QMapDataBase::freeData(QMapDataBase *d) /*! \fn std::map QMap::toStdMap() const Returns an STL map equivalent to this QMap. - - This function is only available if Qt is configured with STL - compatibility enabled. */ /*! \fn QMap::~QMap() -- cgit v1.2.3 From 385ab06fb1d99322872dc84f0e077886a917b9a7 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 29 Jul 2016 12:28:07 +0200 Subject: Always generate size hint for spacer items Task-number: QTBUG-55008 Change-Id: I53c86b64aa3c0a3e5f80551baefe775c2d4b1e90 Reviewed-by: Friedemann Kleint --- src/tools/uic/cpp/cppwriteinitialization.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/tools/uic/cpp/cppwriteinitialization.cpp b/src/tools/uic/cpp/cppwriteinitialization.cpp index e0d4bea5b9..518944d9d7 100644 --- a/src/tools/uic/cpp/cppwriteinitialization.cpp +++ b/src/tools/uic/cpp/cppwriteinitialization.cpp @@ -89,10 +89,14 @@ namespace { const QHash properties = propertyMap(node->elementProperty()); output << "new QSpacerItem("; + int w = 0; + int h = 0; if (properties.contains(QLatin1String("sizeHint"))) { const DomSize *sizeHint = properties.value(QLatin1String("sizeHint"))->elementSize(); - output << sizeHint->elementWidth() << ", " << sizeHint->elementHeight() << ", "; + w = sizeHint->elementWidth(); + h = sizeHint->elementHeight(); } + output << w << ", " << h << ", "; // size type QString sizeType = properties.contains(QLatin1String("sizeType")) ? -- cgit v1.2.3 From db79b89899e6537d540e290beaed263c46e3a885 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 5 Jul 2016 09:34:13 +0200 Subject: winrt: support fullscreen mode Enable switching application to fullscreen mode. This is mostly required for desktop targets of WinRT. Task-number: QTBUG-54517 Change-Id: I67e4020bc2ec8da86d94815e5765959f4ae2b63f Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtwindow.cpp | 51 +++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp index 75b43205b7..3bd0cd3ad7 100644 --- a/src/plugins/platforms/winrt/qwinrtwindow.cpp +++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp @@ -320,10 +320,59 @@ void QWinRTWindow::setWindowState(Qt::WindowState state) if (d->state == state) return; +#if _MSC_VER >= 1900 + if (state == Qt::WindowFullScreen) { + HRESULT hr; + boolean success; + hr = QEventDispatcherWinRT::runOnXamlThread([&hr, &success]() { + ComPtr applicationViewStatics; + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_ApplicationView).Get(), + IID_PPV_ARGS(&applicationViewStatics)); + RETURN_HR_IF_FAILED("Could not access application view statics."); + ComPtr view; + hr = applicationViewStatics->GetForCurrentView(&view); + RETURN_HR_IF_FAILED("Could not access application view."); + ComPtr view3; + hr = view.As(&view3); + Q_ASSERT_SUCCEEDED(hr); + hr = view3->TryEnterFullScreenMode(&success); + return hr; + }); + if (FAILED(hr) || !success) { + qCDebug(lcQpaWindows) << "Failed to enter full screen mode."; + return; + } + d->state = state; + return; + } + + if (d->state == Qt::WindowFullScreen) { + HRESULT hr; + hr = QEventDispatcherWinRT::runOnXamlThread([&hr]() { + ComPtr applicationViewStatics; + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_ApplicationView).Get(), + IID_PPV_ARGS(&applicationViewStatics)); + RETURN_HR_IF_FAILED("Could not access application view statics."); + ComPtr view; + hr = applicationViewStatics->GetForCurrentView(&view); + RETURN_HR_IF_FAILED("Could not access application view."); + ComPtr view3; + hr = view.As(&view3); + Q_ASSERT_SUCCEEDED(hr); + hr = view3->ExitFullScreenMode(); + return hr; + }); + if (FAILED(hr)) { + qCDebug(lcQpaWindows) << "Failed to exit full screen mode."; + return; + } + } +#endif // _MSC_VER >= 1900 + if (state == Qt::WindowMinimized) setUIElementVisibility(d->uiElement.Get(), false); - if (d->state == Qt::WindowMinimized) + if (d->state == Qt::WindowMinimized || state == Qt::WindowNoState || state == Qt::WindowActive) setUIElementVisibility(d->uiElement.Get(), true); d->state = state; -- cgit v1.2.3 From 8ebe8ae35ee7556de0749bc27737ced7c61f5153 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 5 Aug 2016 16:12:00 -0700 Subject: HiDPI Drag and Drop: Properly render the default image on Mac MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is only when the attached MIME data contains text, and we fall back to rendering that text into a pixmap. It requires getting the device pixel ratio from the source which, for now, may be a QWidget or a QWindow. Other cases may exist, but that would bring more dependencies than desired. Similarly, it fixes the draggabletext example. Other examples would require either to get updated pixmaps or change substantially in order to support HiDPI (e.g., the fridgemagnets example). Change-Id: I66198214233e3e06c87505744e2aaa9691fe1bb6 Reviewed-by: Filipe Azevedo Reviewed-by: Timur Pocheptsov Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoadrag.mm | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/cocoa/qcocoadrag.mm b/src/plugins/platforms/cocoa/qcocoadrag.mm index 80006ae9b8..1e9c355788 100644 --- a/src/plugins/platforms/cocoa/qcocoadrag.mm +++ b/src/plugins/platforms/cocoa/qcocoadrag.mm @@ -34,6 +34,9 @@ #include "qcocoadrag.h" #include "qmacclipboard.h" #include "qcocoahelpers.h" +#ifndef QT_NO_WIDGETS +#include +#endif QT_BEGIN_NAMESPACE @@ -181,7 +184,18 @@ QPixmap QCocoaDrag::dragPixmap(QDrag *drag, QPoint &hotSpot) const const int width = fm.width(s); const int height = fm.height(); if (width > 0 && height > 0) { - pm = QPixmap(width, height); + qreal dpr = 1.0; + if (const QWindow *sourceWindow = qobject_cast(drag->source())) { + dpr = sourceWindow->devicePixelRatio(); + } +#ifndef QT_NO_WIDGETS + else if (const QWidget *sourceWidget = qobject_cast(drag->source())) { + if (const QWindow *sourceWindow = sourceWidget->window()->windowHandle()) + dpr = sourceWindow->devicePixelRatio(); + } +#endif + pm = QPixmap(width * dpr, height * dpr); + pm.setDevicePixelRatio(dpr); QPainter p(&pm); p.fillRect(0, 0, pm.width(), pm.height(), Qt::color0); p.setPen(Qt::color1); -- cgit v1.2.3 From 89d7c904e5f7c0cd230e59a4cd8b2ee2a1cbcac1 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 20 May 2016 10:47:37 -0700 Subject: QTabBar: Cache title text sizes The first part adds QTabBarPrivate::initBasicStyleOption() which is basically QTabBar::initStyleOption() but without the expensive QFontMetrics::elidedText() call. That is because QTabBar::tabSizeHint() would call initStyleOption() and then immediately discard the result of that computation. Then, QTabBar::tabSizeHint() is modified to cache the calls to QFontMetrics::size(), which is also expensive. The cache is invalidated when the style or the font changes, or when the elide mode is set. Change-Id: I591b2e401af3576a2ebabc5b94f19ae157e28cf2 Reviewed-by: Friedemann Kleint Reviewed-by: Wayne Arnold Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/widgets/widgets/qtabbar.cpp | 87 ++++++++++++++++++++++++++--------------- src/widgets/widgets/qtabbar_p.h | 3 ++ 2 files changed, 58 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp index 87fb3357d6..fc27654add 100644 --- a/src/widgets/widgets/qtabbar.cpp +++ b/src/widgets/widgets/qtabbar.cpp @@ -134,60 +134,59 @@ void QTabBarPrivate::updateMacBorderMetrics() } /*! - Initialize \a option with the values from the tab at \a tabIndex. This method - is useful for subclasses when they need a QStyleOptionTab, - but don't want to fill in all the information themselves. - - \sa QStyleOption::initFrom(), QTabWidget::initStyleOption() + \internal + This is basically QTabBar::initStyleOption() but + without the expensive QFontMetrics::elidedText() call. */ -void QTabBar::initStyleOption(QStyleOptionTab *option, int tabIndex) const + +void QTabBarPrivate::initBasicStyleOption(QStyleOptionTab *option, int tabIndex) const { - Q_D(const QTabBar); - int totalTabs = d->tabList.size(); + Q_Q(const QTabBar); + const int totalTabs = tabList.size(); if (!option || (tabIndex < 0 || tabIndex >= totalTabs)) return; - const QTabBarPrivate::Tab &tab = d->tabList.at(tabIndex); - option->initFrom(this); + const QTabBarPrivate::Tab &tab = tabList.at(tabIndex); + option->initFrom(q); option->state &= ~(QStyle::State_HasFocus | QStyle::State_MouseOver); - option->rect = tabRect(tabIndex); - bool isCurrent = tabIndex == d->currentIndex; + option->rect = q->tabRect(tabIndex); + const bool isCurrent = tabIndex == currentIndex; option->row = 0; - if (tabIndex == d->pressedIndex) + if (tabIndex == pressedIndex) option->state |= QStyle::State_Sunken; if (isCurrent) option->state |= QStyle::State_Selected; - if (isCurrent && hasFocus()) + if (isCurrent && q->hasFocus()) option->state |= QStyle::State_HasFocus; if (!tab.enabled) option->state &= ~QStyle::State_Enabled; - if (isActiveWindow()) + if (q->isActiveWindow()) option->state |= QStyle::State_Active; - if (!d->dragInProgress && option->rect == d->hoverRect) + if (!dragInProgress && option->rect == hoverRect) option->state |= QStyle::State_MouseOver; - option->shape = d->shape; + option->shape = shape; option->text = tab.text; if (tab.textColor.isValid()) - option->palette.setColor(foregroundRole(), tab.textColor); + option->palette.setColor(q->foregroundRole(), tab.textColor); option->icon = tab.icon; - option->iconSize = iconSize(); // Will get the default value then. + option->iconSize = q->iconSize(); // Will get the default value then. option->leftButtonSize = tab.leftWidget ? tab.leftWidget->size() : QSize(); option->rightButtonSize = tab.rightWidget ? tab.rightWidget->size() : QSize(); - option->documentMode = d->documentMode; + option->documentMode = documentMode; - if (tabIndex > 0 && tabIndex - 1 == d->currentIndex) + if (tabIndex > 0 && tabIndex - 1 == currentIndex) option->selectedPosition = QStyleOptionTab::PreviousIsSelected; - else if (tabIndex + 1 < totalTabs && tabIndex + 1 == d->currentIndex) + else if (tabIndex + 1 < totalTabs && tabIndex + 1 == currentIndex) option->selectedPosition = QStyleOptionTab::NextIsSelected; else option->selectedPosition = QStyleOptionTab::NotAdjacent; - bool paintBeginning = (tabIndex == 0) || (d->dragInProgress && tabIndex == d->pressedIndex + 1); - bool paintEnd = (tabIndex == totalTabs - 1) || (d->dragInProgress && tabIndex == d->pressedIndex - 1); + const bool paintBeginning = (tabIndex == 0) || (dragInProgress && tabIndex == pressedIndex + 1); + const bool paintEnd = (tabIndex == totalTabs - 1) || (dragInProgress && tabIndex == pressedIndex - 1); if (paintBeginning) { if (paintEnd) option->position = QStyleOptionTab::OnlyOneTab; @@ -200,7 +199,7 @@ void QTabBar::initStyleOption(QStyleOptionTab *option, int tabIndex) const } #ifndef QT_NO_TABWIDGET - if (const QTabWidget *tw = qobject_cast(parentWidget())) { + if (const QTabWidget *tw = qobject_cast(q->parentWidget())) { option->features |= QStyleOptionTab::HasFrame; if (tw->cornerWidget(Qt::TopLeftCorner) || tw->cornerWidget(Qt::BottomLeftCorner)) option->cornerWidgets |= QStyleOptionTab::LeftCornerWidget; @@ -208,6 +207,19 @@ void QTabBar::initStyleOption(QStyleOptionTab *option, int tabIndex) const option->cornerWidgets |= QStyleOptionTab::RightCornerWidget; } #endif +} + +/*! + Initialize \a option with the values from the tab at \a tabIndex. This method + is useful for subclasses when they need a QStyleOptionTab, + but don't want to fill in all the information themselves. + + \sa QStyleOption::initFrom(), QTabWidget::initStyleOption() +*/ +void QTabBar::initStyleOption(QStyleOptionTab *option, int tabIndex) const +{ + Q_D(const QTabBar); + d->initBasicStyleOption(option, tabIndex); QRect textRect = style()->subElementRect(QStyle::SE_TabBarTabText, option, this); option->text = fontMetrics().elidedText(option->text, d->elideMode, textRect.width(), @@ -1020,6 +1032,7 @@ void QTabBar::setTabText(int index, const QString &text) { Q_D(QTabBar); if (QTabBarPrivate::Tab *tab = d->at(index)) { + d->textSizes.remove(tab->text); tab->text = text; #ifndef QT_NO_SHORTCUT releaseShortcut(tab->shortcutId); @@ -1379,7 +1392,7 @@ QSize QTabBar::tabSizeHint(int index) const Q_D(const QTabBar); if (const QTabBarPrivate::Tab *tab = d->at(index)) { QStyleOptionTab opt; - initStyleOption(&opt, index); + d->initBasicStyleOption(&opt, index); opt.text = d->tabList.at(index).text; QSize iconSize = tab->icon.isNull() ? QSize(0, 0) : opt.iconSize; int hframe = style()->pixelMetric(QStyle::PM_TabBarTabHSpace, &opt, this); @@ -1405,13 +1418,16 @@ QSize QTabBar::tabSizeHint(int index) const if (!opt.icon.isNull()) padding += 4; + QHash::iterator it = d->textSizes.find(tab->text); + if (it == d->textSizes.end()) + it = d->textSizes.insert(tab->text, fm.size(Qt::TextShowMnemonic, tab->text)); + const int textWidth = it.value().width(); QSize csz; if (verticalTabs(d->shape)) { csz = QSize( qMax(maxWidgetWidth, qMax(fm.height(), iconSize.height())) + vframe, - fm.size(Qt::TextShowMnemonic, tab->text).width() + iconSize.width() + hframe + widgetHeight + padding); + textWidth + iconSize.width() + hframe + widgetHeight + padding); } else { - csz = QSize(fm.size(Qt::TextShowMnemonic, tab->text).width() + iconSize.width() + hframe - + widgetWidth + padding, + csz = QSize(textWidth + iconSize.width() + hframe + widgetWidth + padding, qMax(maxWidgetHeight, qMax(fm.height(), iconSize.height())) + vframe); } @@ -2071,15 +2087,21 @@ void QTabBarPrivate::setCurrentNextEnabledIndex(int offset) void QTabBar::changeEvent(QEvent *event) { Q_D(QTabBar); - if (event->type() == QEvent::StyleChange) { + switch (event->type()) { + case QEvent::StyleChange: if (!d->elideModeSetByUser) d->elideMode = Qt::TextElideMode(style()->styleHint(QStyle::SH_TabBar_ElideMode, 0, this)); if (!d->useScrollButtonsSetByUser) d->useScrollButtons = !style()->styleHint(QStyle::SH_TabBar_PreferNoArrows, 0, this); + // fallthrough + case QEvent::FontChange: + d->textSizes.clear(); d->refresh(); - } else if (event->type() == QEvent::FontChange) { - d->refresh(); + break; + default: + break; } + QWidget::changeEvent(event); } @@ -2122,6 +2144,7 @@ void QTabBar::setElideMode(Qt::TextElideMode mode) Q_D(QTabBar); d->elideMode = mode; d->elideModeSetByUser = true; + d->textSizes.clear(); d->refresh(); } diff --git a/src/widgets/widgets/qtabbar_p.h b/src/widgets/widgets/qtabbar_p.h index e58fde160c..d34f45071d 100644 --- a/src/widgets/widgets/qtabbar_p.h +++ b/src/widgets/widgets/qtabbar_p.h @@ -159,6 +159,7 @@ public: #endif //QT_NO_ANIMATION }; QList tabList; + mutable QHash textSizes; int calculateNewPosition(int from, int to, int index) const; void slide(int from, int to); @@ -192,6 +193,8 @@ public: void setupMovableTab(); void autoHideTabs(); + void initBasicStyleOption(QStyleOptionTab *option, int tabIndex) const; + void makeVisible(int index); QSize iconSize; Qt::TextElideMode elideMode; -- cgit v1.2.3 From c6cfa2270b6d25921373f959b318d89f7098f710 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 9 Aug 2016 13:33:14 +0200 Subject: evdevtouch: Avoid crashing on exit 26238aca8c442736f380eb523ef48468f892bdb7 causes double deletion of the QTouchDevice in case the post routine already cleaned up the list by the time the touch handler gets to do it. Just check the list of devices to see if the one we hold is still there. If not, the pointer is likely to be a dangling one so do nothing. This will avoid dying with bus error or similar on application exit. Task-number: QTBUG-51562 Change-Id: I50c1edee7405aad308274538219698388c2cc9f9 Reviewed-by: Shawn Rutledge --- src/gui/kernel/qwindowsysteminterface.cpp | 5 +++++ src/gui/kernel/qwindowsysteminterface.h | 1 + src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp | 8 ++++++-- 3 files changed, 12 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index cae976098c..f1c43110e3 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -442,6 +442,11 @@ void QWindowSystemInterface::unregisterTouchDevice(const QTouchDevice *device) QTouchDevicePrivate::unregisterDevice(device); } +bool QWindowSystemInterface::isTouchDeviceRegistered(const QTouchDevice *device) +{ + return QTouchDevicePrivate::isRegistered(device); +} + void QWindowSystemInterface::handleTouchEvent(QWindow *w, QTouchDevice *device, const QList &points, Qt::KeyboardModifiers mods) { diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h index 69c850ad3e..b4f6020fe2 100644 --- a/src/gui/kernel/qwindowsysteminterface.h +++ b/src/gui/kernel/qwindowsysteminterface.h @@ -123,6 +123,7 @@ public: static void registerTouchDevice(const QTouchDevice *device); static void unregisterTouchDevice(const QTouchDevice *device); + static bool isTouchDeviceRegistered(const QTouchDevice *device); static void handleTouchEvent(QWindow *w, QTouchDevice *device, const QList &points, Qt::KeyboardModifiers mods = Qt::NoModifier); static void handleTouchEvent(QWindow *w, ulong timestamp, QTouchDevice *device, diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp index 7cb4813c7b..f863629ff9 100644 --- a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp +++ b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp @@ -393,9 +393,13 @@ void QEvdevTouchScreenHandler::unregisterTouchDevice() if (!m_device) return; - QWindowSystemInterface::unregisterTouchDevice(m_device); + // At app exit the cleanup may have already been done, avoid + // double delete by checking the list first. + if (QWindowSystemInterface::isTouchDeviceRegistered(m_device)) { + QWindowSystemInterface::unregisterTouchDevice(m_device); + delete m_device; + } - delete m_device; m_device = Q_NULLPTR; } -- cgit v1.2.3