From 5a48d1d164ba507469ee1a8a682a3c194d733890 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 12 Nov 2015 17:26:21 +0100 Subject: Do not leak textures from the backing stores Neither the default nor the eglfs-specific backingstore release the OpenGL textures that are in use when render-to-texture widgets are involved. The result can be fatal on embedded devices that run out of GPU memory at after showing and closing dialogs and popups a certain number of times. Task-number: QTBUG-49363 Task-number: QTBUG-49399 Change-Id: Ia7471b037f147bcca0a4f1db5808ca348e230547 Reviewed-by: Lars Knoll Reviewed-by: Andy Nichols --- src/widgets/kernel/qwidget.cpp | 46 ++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 11 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 2d7c03116b..7c3c4fe8da 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -72,6 +72,7 @@ #include #include #include +#include #include #include @@ -1817,24 +1818,47 @@ void QWidgetPrivate::deleteSysExtra() { } +static void deleteBackingStore(QWidgetPrivate *d) +{ + QTLWExtra *topData = d->topData(); + + // The context must be current when destroying the backing store as it may attempt to + // release resources like textures and shader programs. The window may not be suitable + // anymore as there will often not be a platform window underneath at this stage. Fall + // back to a QOffscreenSurface in this case. + QScopedPointer tempSurface; +#ifndef QT_NO_OPENGL + if (d->textureChildSeen && topData->shareContext) { + if (topData->window->handle()) { + topData->shareContext->makeCurrent(topData->window); + } else { + tempSurface.reset(new QOffscreenSurface); + tempSurface->setFormat(topData->shareContext->format()); + tempSurface->create(); + topData->shareContext->makeCurrent(tempSurface.data()); + } + } +#endif + + delete topData->backingStore; + topData->backingStore = 0; + +#ifndef QT_NO_OPENGL + if (d->textureChildSeen && topData->shareContext) + topData->shareContext->doneCurrent(); +#endif +} + void QWidgetPrivate::deleteTLSysExtra() { if (extra && extra->topextra) { //the qplatformbackingstore may hold a reference to the window, so the backingstore //needs to be deleted first. If the backingstore holds GL resources, we need to - // make the context current here, since the platform bs does not have a reference - // to the widget. + // make the context current here. This is taken care of by deleteBackingStore(). -#ifndef QT_NO_OPENGL - if (textureChildSeen && extra->topextra->shareContext) - extra->topextra->shareContext->makeCurrent(extra->topextra->window); -#endif extra->topextra->backingStoreTracker.destroy(); - delete extra->topextra->backingStore; - extra->topextra->backingStore = 0; + deleteBackingStore(this); #ifndef QT_NO_OPENGL - if (textureChildSeen && extra->topextra->shareContext) - extra->topextra->shareContext->doneCurrent(); delete extra->topextra->shareContext; extra->topextra->shareContext = 0; #endif @@ -11980,7 +12004,7 @@ void QWidget::setBackingStore(QBackingStore *store) return; QBackingStore *oldStore = topData->backingStore; - delete topData->backingStore; + deleteBackingStore(d); topData->backingStore = store; QWidgetBackingStore *bs = d->maybeBackingStore(); -- cgit v1.2.3 From b21c219811f2363002e3cc96c8cfef849aaa95a4 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 6 Nov 2015 11:03:15 +0100 Subject: Call setFocus() if it is a QAxHostWidget which is in a new active window The change 8c0f47cfae17a39137dec47aa0b9f3f9bedad introduced a problem where if the widget was being reparented had a valid HWND then it would cause the focus to change inside the already active window. Therefore we need to limit the times it does this to the case where we know it needs to be done which is the ActiveQt case. Change-Id: Ia85f5136661142b25952e0ebf66f8a43d9500d58 Reviewed-by: Friedemann Kleint Reviewed-by: Andy Shaw --- src/widgets/kernel/qapplication.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 647484ece1..078feb4b03 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -2248,8 +2248,10 @@ void QApplicationPrivate::notifyActiveWindowChange(QWindow *previous) QApplication::setActiveWindow(tlw); // QTBUG-37126, Active X controls may set the focus on native child widgets. if (wnd && tlw && wnd != tlw->windowHandle()) { - if (QWidgetWindow *widgetWindow = qobject_cast(wnd)) - widgetWindow->widget()->setFocus(Qt::ActiveWindowFocusReason); + if (QWidgetWindow *widgetWindow = qobject_cast(wnd)) { + if (widgetWindow->widget()->inherits("QAxHostWidget")) + widgetWindow->widget()->setFocus(Qt::ActiveWindowFocusReason); + } } } -- cgit v1.2.3 From e4d1bf9829c56dc446a07689758f22c58863d70d Mon Sep 17 00:00:00 2001 From: Joni Poikelin Date: Tue, 24 Nov 2015 09:51:12 +0200 Subject: Fix crash in QFileDialog::iconProvider() with native dialogs Task-number: QTBUG-49600 Change-Id: Ied28c0e7efa6b4dce25705dab98377848db5a6d3 Reviewed-by: Richard Moe Gustavsen Reviewed-by: Friedemann Kleint --- src/widgets/dialogs/qfiledialog.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/widgets') diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 2d4ba1aeb9..4e0d70fb9a 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -1938,6 +1938,8 @@ void QFileDialog::setIconProvider(QFileIconProvider *provider) QFileIconProvider *QFileDialog::iconProvider() const { Q_D(const QFileDialog); + if (!d->model) + return Q_NULLPTR; return d->model->iconProvider(); } -- cgit v1.2.3 From fb69a09a2490102ad0c3f6015e04942bb5df7505 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 24 Nov 2015 13:49:44 +0100 Subject: QWidget::mapTo/FromGlobal(): Avoid calling QWindow helpers until shown. The platform window geometry can be misleading until it has been properly positioned and QWindowPrivate::resizeEventPending has been cleared. Task-number: QTBUG-49588 Task-number: QTBUG-48396 Change-Id: Ie065f62478fc8522a9ad51391bb897510afa5aad Reviewed-by: Marc Mutz --- src/widgets/kernel/qwidget.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index b8b8640cea..229cfc0f85 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -12327,6 +12327,12 @@ QPaintEngine *QWidget::paintEngine() const return 0; //##### @@@ } +// Do not call QWindow::mapToGlobal() until QPlatformWindow is properly showing. +static inline bool canMapPosition(QWindow *window) +{ + return window->handle() && !qt_window_private(window)->resizeEventPending; +} + /*! \fn QPoint QWidget::mapToGlobal(const QPoint &pos) const @@ -12354,7 +12360,7 @@ QPoint QWidget::mapToGlobal(const QPoint &pos) const #endif // !QT_NO_GRAPHICSVIEW QWindow *window = w->windowHandle(); - if (window && window->handle()) + if (window && canMapPosition(window)) return window->mapToGlobal(QPoint(x, y)); x += w->data->crect.x(); @@ -12390,7 +12396,7 @@ QPoint QWidget::mapFromGlobal(const QPoint &pos) const #endif // !QT_NO_GRAPHICSVIEW QWindow *window = w->windowHandle(); - if (window && window->handle()) + if (window && canMapPosition(window)) return window->mapFromGlobal(QPoint(x, y)); x -= w->data->crect.x(); -- cgit v1.2.3 From 4eea99788b11ab8b5e3e68764671757d010425c6 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 25 Nov 2015 11:39:02 +0100 Subject: Fix closing a QMenu by pressing Alt. In QMenuPrivate::hideMenu(), delay clearing of 'causedPopup.widget' to after the QMenu::close() call, so that it is still accessible in QMenu::hideEvent() which calls QMenuBarPrivate::setCurrentAction(0) if the caused widget is a QMenuBar. Task-number: QTBUG-47377 Task-number: QTBUG-49592 Change-Id: Idbda48e918dae799afea84068a60d7383d7b4971 Reviewed-by: Marc Mutz --- src/widgets/widgets/qmenu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/widgets') diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 27e977f027..4239e7f3d4 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -502,8 +502,8 @@ void QMenuPrivate::hideMenu(QMenu *menu) if (activeMenu == menu) activeMenu = 0; menu->d_func()->causedPopup.action = 0; - menu->d_func()->causedPopup.widget = 0; menu->close(); + menu->d_func()->causedPopup.widget = 0; if (previousMouseMenu.data() == menu) handleEnterLeaveEvents(&previousMouseMenu, Q_NULLPTR); } -- cgit v1.2.3 From 40a8302115d6bcc171b314c7d3b4e574b08b66b0 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 24 Oct 2015 12:41:08 +0200 Subject: QtBase: remove explicit function info from qWarning() etc This information is already registered by the QMessageLogger ctor. Where, by dropping the << Q_FUNC_INFO in ostream-style qDebug(), only a string literal remained, converted to printf-style qDebug() on the go. Change-Id: I3f261c98fd7bcfa1fead381a75a82713bb75e6f3 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/widgets/itemviews/qtableview.cpp | 4 ---- src/widgets/kernel/qwidgetwindow.cpp | 2 +- src/widgets/styles/qwindowsvistastyle.cpp | 4 ++-- src/widgets/styles/qwindowsxpstyle.cpp | 6 +++--- src/widgets/util/qsystemtrayicon_win.cpp | 2 +- src/widgets/widgets/qtoolbararealayout.cpp | 2 +- 6 files changed, 8 insertions(+), 12 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp index 89bd9dbcb1..1e2e81a4e3 100644 --- a/src/widgets/itemviews/qtableview.cpp +++ b/src/widgets/itemviews/qtableview.cpp @@ -201,7 +201,6 @@ QDebug operator<<(QDebug str, const QSpanCollection::Span &span) void QSpanCollection::updateInsertedRows(int start, int end) { #ifdef DEBUG_SPAN_UPDATE - qDebug() << Q_FUNC_INFO; qDebug() << start << end; qDebug() << index; #endif @@ -251,7 +250,6 @@ void QSpanCollection::updateInsertedRows(int start, int end) void QSpanCollection::updateInsertedColumns(int start, int end) { #ifdef DEBUG_SPAN_UPDATE - qDebug() << Q_FUNC_INFO; qDebug() << start << end; qDebug() << index; #endif @@ -334,7 +332,6 @@ bool QSpanCollection::cleanSpanSubIndex(QSpanCollection::SubIndex &subindex, int void QSpanCollection::updateRemovedRows(int start, int end) { #ifdef DEBUG_SPAN_UPDATE - qDebug() << Q_FUNC_INFO; qDebug() << start << end; qDebug() << index; #endif @@ -463,7 +460,6 @@ void QSpanCollection::updateRemovedRows(int start, int end) void QSpanCollection::updateRemovedColumns(int start, int end) { #ifdef DEBUG_SPAN_UPDATE - qDebug() << Q_FUNC_INFO; qDebug() << start << end; qDebug() << index; #endif diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index a194993328..3637b76aa9 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -795,7 +795,7 @@ void QWidgetWindow::handleDragLeaveEvent(QDragLeaveEvent *event) void QWidgetWindow::handleDropEvent(QDropEvent *event) { if (m_dragTarget.isNull()) { - qWarning() << Q_FUNC_INFO << m_widget << ": No drag target set."; + qWarning() << m_widget << ": No drag target set."; event->ignore(); return; } diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp index a7a0830fb9..083b1d1707 100644 --- a/src/widgets/styles/qwindowsvistastyle.cpp +++ b/src/widgets/styles/qwindowsvistastyle.cpp @@ -2472,12 +2472,12 @@ bool QWindowsVistaStylePrivate::initTreeViewTheming() m_treeViewHelper = createTreeViewHelperWindow(); if (!m_treeViewHelper) { - qWarning("%s: Unable to create the treeview helper window.", Q_FUNC_INFO); + qWarning("Unable to create the treeview helper window."); return false; } const HRESULT hr = QWindowsXPStylePrivate::pSetWindowTheme(m_treeViewHelper, L"explorer", NULL); if (hr != S_OK) { - qErrnoWarning("%s: SetWindowTheme() failed.", Q_FUNC_INFO); + qErrnoWarning("SetWindowTheme() failed."); return false; } return QWindowsXPStylePrivate::createTheme(QWindowsXPStylePrivate::TreeViewTheme, m_treeViewHelper); diff --git a/src/widgets/styles/qwindowsxpstyle.cpp b/src/widgets/styles/qwindowsxpstyle.cpp index 0b33213378..c350e82c69 100644 --- a/src/widgets/styles/qwindowsxpstyle.cpp +++ b/src/widgets/styles/qwindowsxpstyle.cpp @@ -338,15 +338,15 @@ void QWindowsXPStylePrivate::cleanupHandleMap() HTHEME QWindowsXPStylePrivate::createTheme(int theme, HWND hwnd) { if (theme < 0 || theme >= NThemes || !hwnd) { - qWarning("%s: Invalid parameters #%d, %p", Q_FUNC_INFO, theme, hwnd); + qWarning("Invalid parameters #%d, %p", theme, hwnd); return 0; } if (!m_themes[theme]) { const wchar_t *name = themeNames[theme]; m_themes[theme] = pOpenThemeData(hwnd, name); if (!m_themes[theme]) - qErrnoWarning("%s: OpenThemeData() failed for theme %d (%s).", - Q_FUNC_INFO, theme, qPrintable(themeName(theme))); + qErrnoWarning("OpenThemeData() failed for theme %d (%s).", + theme, qPrintable(themeName(theme))); } return m_themes[theme]; } diff --git a/src/widgets/util/qsystemtrayicon_win.cpp b/src/widgets/util/qsystemtrayicon_win.cpp index 1809c36483..f1b86ba2df 100644 --- a/src/widgets/util/qsystemtrayicon_win.cpp +++ b/src/widgets/util/qsystemtrayicon_win.cpp @@ -395,7 +395,7 @@ void QSystemTrayIconPrivate::install_sys() sys->createIcon(); sys->trayMessage(NIM_ADD); } else { - qWarning("%s: The platform plugin failed to create a message window.", Q_FUNC_INFO); + qWarning("The platform plugin failed to create a message window."); } } } diff --git a/src/widgets/widgets/qtoolbararealayout.cpp b/src/widgets/widgets/qtoolbararealayout.cpp index 89e3da1383..16b1115dd6 100644 --- a/src/widgets/widgets/qtoolbararealayout.cpp +++ b/src/widgets/widgets/qtoolbararealayout.cpp @@ -1129,7 +1129,7 @@ QLayoutItem *QToolBarAreaLayout::plug(const QList &path) { QToolBarAreaLayoutItem *item = this->item(path); if (!item) { - qWarning() << Q_FUNC_INFO << "No item at" << path; + qWarning() << "No item at" << path; return 0; } Q_ASSERT(item->gap); -- cgit v1.2.3 From 678a4273a30e9e073dabe684ba21f18faf426e15 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 24 Oct 2015 22:32:45 +0200 Subject: QtBase: combine adjacent qDebug()/qCritical() lines For qDebug() and qWarning(), this is just an optimization. For qCritical(), which can be fatal, the old code was just wrong. Change-Id: I6d8ab1d7531d766cd41b49569dc0fd4420ecab8b Reviewed-by: Friedemann Kleint Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/widgets/itemviews/qtableview.cpp | 12 ++++-------- src/widgets/util/qscroller.cpp | 4 ++-- 2 files changed, 6 insertions(+), 10 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp index 1e2e81a4e3..ee0d41ce15 100644 --- a/src/widgets/itemviews/qtableview.cpp +++ b/src/widgets/itemviews/qtableview.cpp @@ -201,8 +201,7 @@ QDebug operator<<(QDebug str, const QSpanCollection::Span &span) void QSpanCollection::updateInsertedRows(int start, int end) { #ifdef DEBUG_SPAN_UPDATE - qDebug() << start << end; - qDebug() << index; + qDebug() << start << end << endl << index; #endif if (spans.isEmpty()) return; @@ -250,8 +249,7 @@ void QSpanCollection::updateInsertedRows(int start, int end) void QSpanCollection::updateInsertedColumns(int start, int end) { #ifdef DEBUG_SPAN_UPDATE - qDebug() << start << end; - qDebug() << index; + qDebug() << start << end << endl << index; #endif if (spans.isEmpty()) return; @@ -332,8 +330,7 @@ bool QSpanCollection::cleanSpanSubIndex(QSpanCollection::SubIndex &subindex, int void QSpanCollection::updateRemovedRows(int start, int end) { #ifdef DEBUG_SPAN_UPDATE - qDebug() << start << end; - qDebug() << index; + qDebug() << start << end << endl << index; #endif if (spans.isEmpty()) return; @@ -460,8 +457,7 @@ void QSpanCollection::updateRemovedRows(int start, int end) void QSpanCollection::updateRemovedColumns(int start, int end) { #ifdef DEBUG_SPAN_UPDATE - qDebug() << start << end; - qDebug() << index; + qDebug() << start << end << endl << index; #endif if (spans.isEmpty()) return; diff --git a/src/widgets/util/qscroller.cpp b/src/widgets/util/qscroller.cpp index 0065ccf6b3..38b104f9e9 100644 --- a/src/widgets/util/qscroller.cpp +++ b/src/widgets/util/qscroller.cpp @@ -1870,8 +1870,8 @@ void QScrollerPrivate::setContentPositionHelperScrolling() newPos.setY(nextSegmentPosition(ySegments, now, newPos.y())); // -- set the position and handle overshoot - qScrollerDebug() << "QScroller::setContentPositionHelperScrolling()"; - qScrollerDebug() << " --> overshoot:" << overshootPosition << "- new pos:" << newPos; + qScrollerDebug() << "QScroller::setContentPositionHelperScrolling()\n" + " --> overshoot:" << overshootPosition << "- new pos:" << newPos; QPointF newClampedPos = clampToRect(newPos, contentPosRange); -- cgit v1.2.3 From 61cefb2f7a7cb16dfa2732e26d2319017039ef62 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 23 Nov 2015 14:47:05 +0100 Subject: De-inline QFileSystemModel::fileInfo() and implement it efficiently De-inline the method, and return the file info that's already being cached by the model. This is ok to do in a minor release, as apps compiled against an older version of Qt will simply continue to use the less efficient implementation. Change-Id: I164c7961a8cf97447638af316512326442767dd8 Task-number: QTBUG-30902 Reviewed-by: Marc Mutz Reviewed-by: Edward Welbourne Reviewed-by: Konstantin Ritt --- src/widgets/dialogs/qfilesystemmodel.cpp | 5 +++++ src/widgets/dialogs/qfilesystemmodel.h | 4 +--- src/widgets/dialogs/qfilesystemmodel_p.h | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp index b1e77540e7..6bce7e99f5 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -154,6 +154,11 @@ QT_BEGIN_NAMESPACE Returns the QFileInfo for the item stored in the model under the given \a index. */ +QFileInfo QFileSystemModel::fileInfo(const QModelIndex &index) const +{ + Q_D(const QFileSystemModel); + return d->node(index)->fileInfo(); +} /*! \fn void QFileSystemModel::rootPathChanged(const QString &newPath); diff --git a/src/widgets/dialogs/qfilesystemmodel.h b/src/widgets/dialogs/qfilesystemmodel.h index f749c97bcb..add1a7241a 100644 --- a/src/widgets/dialogs/qfilesystemmodel.h +++ b/src/widgets/dialogs/qfilesystemmodel.h @@ -132,7 +132,7 @@ public: inline QString fileName(const QModelIndex &index) const; inline QIcon fileIcon(const QModelIndex &index) const; QFile::Permissions permissions(const QModelIndex &index) const; - inline QFileInfo fileInfo(const QModelIndex &index) const; + QFileInfo fileInfo(const QModelIndex &index) const; bool remove(const QModelIndex &index); protected: @@ -156,8 +156,6 @@ inline QString QFileSystemModel::fileName(const QModelIndex &aindex) const { return aindex.data(Qt::DisplayRole).toString(); } inline QIcon QFileSystemModel::fileIcon(const QModelIndex &aindex) const { return qvariant_cast(aindex.data(Qt::DecorationRole)); } -inline QFileInfo QFileSystemModel::fileInfo(const QModelIndex &aindex) const -{ return QFileInfo(filePath(aindex)); } #endif // QT_NO_FILESYSTEMMODEL diff --git a/src/widgets/dialogs/qfilesystemmodel_p.h b/src/widgets/dialogs/qfilesystemmodel_p.h index 57fb457071..a35c50bfc7 100644 --- a/src/widgets/dialogs/qfilesystemmodel_p.h +++ b/src/widgets/dialogs/qfilesystemmodel_p.h @@ -107,6 +107,7 @@ public: return true; return false; } + inline QFileInfo fileInfo() const { if (info) return info->fileInfo(); return QFileInfo(); } inline bool isFile() const { if (info) return info->isFile(); return true; } inline bool isSystem() const { if (info) return info->isSystem(); return true; } inline bool isHidden() const { if (info) return info->isHidden(); return false; } -- cgit v1.2.3 From 197da3d220fb267d127288e109e691d832ce290b Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 23 Nov 2015 14:35:45 +0100 Subject: Use QCollator for sorting in the filesystem model The old code was extremely inefficient, and QCollator can provide the same functionality in a much better and faster way. Task-number: QTBUG-30902 Change-Id: Iaf5dbe587d9a6ebca26885259fdee74a29d3c84f Reviewed-by: Edward Welbourne Reviewed-by: Konstantin Ritt Reviewed-by: Marc Mutz Reviewed-by: Lars Knoll --- src/widgets/dialogs/qfilesystemmodel.cpp | 95 ++++---------------------------- 1 file changed, 11 insertions(+), 84 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp index 6bce7e99f5..1b9a1129b2 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include @@ -979,84 +980,6 @@ void QFileSystemModelPrivate::_q_performDelayedSort() q->sort(sortColumn, sortOrder); } -static inline QChar getNextChar(const QString &s, int location) -{ - return (location < s.length()) ? s.at(location) : QChar(); -} - -/*! - Natural number sort, skips spaces. - - Examples: - 1, 2, 10, 55, 100 - 01.jpg, 2.jpg, 10.jpg - - Note on the algorithm: - Only as many characters as necessary are looked at and at most they all - are looked at once. - - Slower then QString::compare() (of course) - */ -int QFileSystemModelPrivate::naturalCompare(const QString &s1, const QString &s2, Qt::CaseSensitivity cs) -{ - for (int l1 = 0, l2 = 0; l1 <= s1.count() && l2 <= s2.count(); ++l1, ++l2) { - // skip spaces, tabs and 0's - QChar c1 = getNextChar(s1, l1); - while (c1.isSpace()) - c1 = getNextChar(s1, ++l1); - QChar c2 = getNextChar(s2, l2); - while (c2.isSpace()) - c2 = getNextChar(s2, ++l2); - - if (c1.isDigit() && c2.isDigit()) { - while (c1.digitValue() == 0) - c1 = getNextChar(s1, ++l1); - while (c2.digitValue() == 0) - c2 = getNextChar(s2, ++l2); - - int lookAheadLocation1 = l1; - int lookAheadLocation2 = l2; - int currentReturnValue = 0; - // find the last digit, setting currentReturnValue as we go if it isn't equal - for ( - QChar lookAhead1 = c1, lookAhead2 = c2; - (lookAheadLocation1 <= s1.length() && lookAheadLocation2 <= s2.length()); - lookAhead1 = getNextChar(s1, ++lookAheadLocation1), - lookAhead2 = getNextChar(s2, ++lookAheadLocation2) - ) { - bool is1ADigit = !lookAhead1.isNull() && lookAhead1.isDigit(); - bool is2ADigit = !lookAhead2.isNull() && lookAhead2.isDigit(); - if (!is1ADigit && !is2ADigit) - break; - if (!is1ADigit) - return -1; - if (!is2ADigit) - return 1; - if (currentReturnValue == 0) { - if (lookAhead1 < lookAhead2) { - currentReturnValue = -1; - } else if (lookAhead1 > lookAhead2) { - currentReturnValue = 1; - } - } - } - if (currentReturnValue != 0) - return currentReturnValue; - } - - if (cs == Qt::CaseInsensitive) { - if (!c1.isLower()) c1 = c1.toLower(); - if (!c2.isLower()) c2 = c2.toLower(); - } - int r = QString::localeAwareCompare(c1, c2); - if (r < 0) - return -1; - if (r > 0) - return 1; - } - // The two strings are the same (02 == 2) so fall back to the normal sort - return QString::compare(s1, s2, cs); -} /* \internal @@ -1065,7 +988,11 @@ int QFileSystemModelPrivate::naturalCompare(const QString &s1, const QString &s2 class QFileSystemModelSorter { public: - inline QFileSystemModelSorter(int column) : sortColumn(column) {} + inline QFileSystemModelSorter(int column) : sortColumn(column) + { + naturalCompare.setNumericMode(true); + naturalCompare.setCaseSensitivity(Qt::CaseInsensitive); + } bool compareNodes(const QFileSystemModelPrivate::QFileSystemNode *l, const QFileSystemModelPrivate::QFileSystemNode *r) const @@ -1079,8 +1006,7 @@ public: if (left ^ right) return left; #endif - return QFileSystemModelPrivate::naturalCompare(l->fileName, - r->fileName, Qt::CaseInsensitive) < 0; + return naturalCompare.compare(l->fileName, r->fileName) < 0; } case 1: { @@ -1092,7 +1018,7 @@ public: qint64 sizeDifference = l->size() - r->size(); if (sizeDifference == 0) - return QFileSystemModelPrivate::naturalCompare(l->fileName, r->fileName, Qt::CaseInsensitive) < 0; + return naturalCompare.compare(l->fileName, r->fileName) < 0; return sizeDifference < 0; } @@ -1100,14 +1026,14 @@ public: { int compare = QString::localeAwareCompare(l->type(), r->type()); if (compare == 0) - return QFileSystemModelPrivate::naturalCompare(l->fileName, r->fileName, Qt::CaseInsensitive) < 0; + return naturalCompare.compare(l->fileName, r->fileName) < 0; return compare < 0; } case 3: { if (l->lastModified() == r->lastModified()) - return QFileSystemModelPrivate::naturalCompare(l->fileName, r->fileName, Qt::CaseInsensitive) < 0; + return naturalCompare.compare(l->fileName, r->fileName) < 0; return l->lastModified() < r->lastModified(); } @@ -1124,6 +1050,7 @@ public: private: + QCollator naturalCompare; int sortColumn; }; -- cgit v1.2.3 From ca14600965479dd3d255b734a0fe54bb2ba7892d Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 24 Nov 2015 15:01:53 +0100 Subject: Use natural comparison also for the file types If we want to sort according to file types, we're also sorting user visible strings. For that we can also use the natural comparison collator, as file types should be case insensitive, and won't contain numbers. And even if they do a natual sorting will make it easier for the end user to find what they are looking for. Change-Id: Ie1d7d0af041a08be0f0d1a4eeb2eae9be885ffc7 Reviewed-by: Marc Mutz --- src/widgets/dialogs/qfilesystemmodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/widgets') diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp index 1b9a1129b2..cfc6b9c4cc 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -1024,7 +1024,7 @@ public: } case 2: { - int compare = QString::localeAwareCompare(l->type(), r->type()); + int compare = naturalCompare.compare(l->type(), r->type()); if (compare == 0) return naturalCompare.compare(l->fileName, r->fileName) < 0; -- cgit v1.2.3 From e808c5fa6096eb4bc84b6d90c9befa9e805fa680 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 24 Nov 2015 09:21:53 +0100 Subject: Don't use QList Change it to use a QVector instead. Change-Id: Ie1749f326ba1165db48c0eb8763eb738672c7afd Reviewed-by: Marc Mutz --- src/widgets/dialogs/qfileinfogatherer.cpp | 6 +++--- src/widgets/dialogs/qfileinfogatherer_p.h | 4 ++-- src/widgets/dialogs/qfilesystemmodel.cpp | 10 +++++----- src/widgets/dialogs/qfilesystemmodel.h | 2 +- src/widgets/dialogs/qfilesystemmodel_p.h | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/dialogs/qfileinfogatherer.cpp b/src/widgets/dialogs/qfileinfogatherer.cpp index 7329019a87..92d6b8f3be 100644 --- a/src/widgets/dialogs/qfileinfogatherer.cpp +++ b/src/widgets/dialogs/qfileinfogatherer.cpp @@ -287,7 +287,7 @@ void QFileInfoGatherer::getFileInfos(const QString &path, const QStringList &fil } for (int i = infoList.count() - 1; i >= 0; --i) { QString driveName = translateDriveName(infoList.at(i)); - QList > updatedFiles; + QVector > updatedFiles; updatedFiles.append(QPair(driveName, infoList.at(i))); emit updates(path, updatedFiles); } @@ -298,7 +298,7 @@ void QFileInfoGatherer::getFileInfos(const QString &path, const QStringList &fil base.start(); QFileInfo fileInfo; bool firstTime = true; - QList > updatedFiles; + QVector > updatedFiles; QStringList filesToCheck = files; QString itPath = QDir::fromNativeSeparators(files.isEmpty() ? path : QLatin1String("")); @@ -324,7 +324,7 @@ void QFileInfoGatherer::getFileInfos(const QString &path, const QStringList &fil emit directoryLoaded(path); } -void QFileInfoGatherer::fetch(const QFileInfo &fileInfo, QElapsedTimer &base, bool &firstTime, QList > &updatedFiles, const QString &path) { +void QFileInfoGatherer::fetch(const QFileInfo &fileInfo, QElapsedTimer &base, bool &firstTime, QVector > &updatedFiles, const QString &path) { updatedFiles.append(QPair(fileInfo.fileName(), fileInfo)); QElapsedTimer current; current.start(); diff --git a/src/widgets/dialogs/qfileinfogatherer_p.h b/src/widgets/dialogs/qfileinfogatherer_p.h index 6bd15b5388..03f87fdba5 100644 --- a/src/widgets/dialogs/qfileinfogatherer_p.h +++ b/src/widgets/dialogs/qfileinfogatherer_p.h @@ -149,7 +149,7 @@ class Q_AUTOTEST_EXPORT QFileInfoGatherer : public QThread Q_OBJECT Q_SIGNALS: - void updates(const QString &directory, const QList > &updates); + void updates(const QString &directory, const QVector > &updates); void newListOfFiles(const QString &directory, const QStringList &listOfFiles) const; void nameResolved(const QString &fileName, const QString &resolvedName) const; void directoryLoaded(const QString &path); @@ -176,7 +176,7 @@ private: void run() Q_DECL_OVERRIDE; // called by run(): void getFileInfos(const QString &path, const QStringList &files); - void fetch(const QFileInfo &info, QElapsedTimer &base, bool &firstTime, QList > &updatedFiles, const QString &path); + void fetch(const QFileInfo &info, QElapsedTimer &base, bool &firstTime, QVector > &updatedFiles, const QString &path); private: mutable QMutex mutex; diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp index cfc6b9c4cc..5dd8c05734 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -1110,7 +1110,7 @@ void QFileSystemModel::sort(int column, Qt::SortOrder order) emit layoutAboutToBeChanged(); QModelIndexList oldList = persistentIndexList(); - QList > oldNodes; + QVector > oldNodes; const int nodeCount = oldList.count(); oldNodes.reserve(nodeCount); for (int i = 0; i < nodeCount; ++i) { @@ -1756,7 +1756,7 @@ void QFileSystemModelPrivate::removeVisibleFile(QFileSystemNode *parentNode, int The thread has received new information about files, update and emit dataChanged if it has actually changed. */ -void QFileSystemModelPrivate::_q_fileSystemChanged(const QString &path, const QList > &updates) +void QFileSystemModelPrivate::_q_fileSystemChanged(const QString &path, const QVector > &updates) { #ifndef QT_NO_FILESYSTEMWATCHER Q_Q(QFileSystemModel); @@ -1875,12 +1875,12 @@ void QFileSystemModelPrivate::_q_resolvedName(const QString &fileName, const QSt void QFileSystemModelPrivate::init() { Q_Q(QFileSystemModel); - qRegisterMetaType > >(); + qRegisterMetaType > >(); #ifndef QT_NO_FILESYSTEMWATCHER q->connect(&fileInfoGatherer, SIGNAL(newListOfFiles(QString,QStringList)), q, SLOT(_q_directoryChanged(QString,QStringList))); - q->connect(&fileInfoGatherer, SIGNAL(updates(QString,QList >)), - q, SLOT(_q_fileSystemChanged(QString,QList >))); + q->connect(&fileInfoGatherer, SIGNAL(updates(QString,QVector >)), + q, SLOT(_q_fileSystemChanged(QString,QVector >))); q->connect(&fileInfoGatherer, SIGNAL(nameResolved(QString,QString)), q, SLOT(_q_resolvedName(QString,QString))); q->connect(&fileInfoGatherer, SIGNAL(directoryLoaded(QString)), diff --git a/src/widgets/dialogs/qfilesystemmodel.h b/src/widgets/dialogs/qfilesystemmodel.h index add1a7241a..515417f225 100644 --- a/src/widgets/dialogs/qfilesystemmodel.h +++ b/src/widgets/dialogs/qfilesystemmodel.h @@ -146,7 +146,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_directoryChanged(const QString &directory, const QStringList &list)) Q_PRIVATE_SLOT(d_func(), void _q_performDelayedSort()) - Q_PRIVATE_SLOT(d_func(), void _q_fileSystemChanged(const QString &path, const QList > &)) + Q_PRIVATE_SLOT(d_func(), void _q_fileSystemChanged(const QString &path, const QVector > &)) Q_PRIVATE_SLOT(d_func(), void _q_resolvedName(const QString &fileName, const QString &resolvedName)) friend class QFileDialogPrivate; diff --git a/src/widgets/dialogs/qfilesystemmodel_p.h b/src/widgets/dialogs/qfilesystemmodel_p.h index a35c50bfc7..d2a40a1cb5 100644 --- a/src/widgets/dialogs/qfilesystemmodel_p.h +++ b/src/widgets/dialogs/qfilesystemmodel_p.h @@ -283,7 +283,7 @@ public: void _q_directoryChanged(const QString &directory, const QStringList &list); void _q_performDelayedSort(); - void _q_fileSystemChanged(const QString &path, const QList > &); + void _q_fileSystemChanged(const QString &path, const QVector > &); void _q_resolvedName(const QString &fileName, const QString &resolvedName); static int naturalCompare(const QString &s1, const QString &s2, Qt::CaseSensitivity cs); -- cgit v1.2.3 From 5d63e325faa44cf1345d6f7b5cb39ec874527675 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 30 Nov 2015 11:31:43 +0100 Subject: Avoid dynamic switching between backingstore composition paths Make it opt-in because doing a normal backingstore flush does not seem to work on Cocoa once we use OpenGL on the window. Windows and Linux should be able to cope with this. This means that platforms outside Windows and Linux will continue to have the problem of having GL-based compositing enabled for ever after having a QOpenGL/QuickWidget shown in the window once, but the issue is most prevalent on Windows anyway, OS X machines can deal with OpenGL better in general. Task-number: QTBUG-49172 Change-Id: I30fd2efa95cc4f6eed9cf7f7613d0750355c775c Reviewed-by: Lars Knoll Reviewed-by: Eike Ziller Reviewed-by: Paul Olav Tvete --- src/widgets/kernel/qwidgetbackingstore.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index 6d43adc33b..b86c376385 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -104,7 +104,6 @@ void QWidgetBackingStore::qt_flush(QWidget *widget, const QRegion ®ion, QBack #ifndef QT_NO_OPENGL if (widgetTextures) { - Q_ASSERT(!widgetTextures->isEmpty()); qt_window_private(tlw->windowHandle())->compositing = true; widget->window()->d_func()->sendComposeStatus(widget->window(), false); // A window may have alpha even when the app did not request @@ -955,6 +954,8 @@ static void findAllTextureWidgetsRecursively(QWidget *tlw, QWidget *widget) } } +Q_GLOBAL_STATIC(QPlatformTextureList, qt_dummy_platformTextureList) + static QPlatformTextureList *widgetTexturesFor(QWidget *tlw, QWidget *widget) { foreach (QPlatformTextureList *tl, QWidgetPrivate::get(tlw)->topData()->widgetTextures) { @@ -965,6 +966,20 @@ static QPlatformTextureList *widgetTexturesFor(QWidget *tlw, QWidget *widget) return tl; } } + + if (QWidgetPrivate::get(tlw)->textureChildSeen) { + // No render-to-texture widgets in the (sub-)tree due to hidden or native + // children. Returning null results in using the normal backingstore flush path + // without OpenGL-based compositing. This is very desirable normally. However, + // some platforms cannot handle switching between the non-GL and GL paths for + // their windows so it has to be opt-in. + static bool switchableWidgetComposition = + QGuiApplicationPrivate::instance()->platformIntegration() + ->hasCapability(QPlatformIntegration::SwitchableWidgetComposition); + if (!switchableWidgetComposition) + return qt_dummy_platformTextureList(); + } + return 0; } -- cgit v1.2.3