From 0817e2a81ec1b0fc1e5cd7ed9473177c75dc6f1e Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Tue, 7 Nov 2017 12:11:45 +0100 Subject: Doc: Update the list of highlighted examples Update the list of highlighted examples for modules in qtbase, based on which examples have been updated to use C++11 features, the new signal/slot connection syntax, and documentation improvements. Not all the modules have highlighted examples yet as some of the work is still ongoing. Task-number: QTBUG-60641 Change-Id: If28d59c10ca1a30e5db408970f20159434ac94f8 Reviewed-by: Nico Vertriest Reviewed-by: Leena Miettinen Reviewed-by: Venugopal Shivashankar --- src/widgets/doc/qtwidgets.qdocconf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/widgets') diff --git a/src/widgets/doc/qtwidgets.qdocconf b/src/widgets/doc/qtwidgets.qdocconf index a49eb439af..88957b0f94 100644 --- a/src/widgets/doc/qtwidgets.qdocconf +++ b/src/widgets/doc/qtwidgets.qdocconf @@ -48,4 +48,6 @@ imagedirs += images \ navigation.landingpage = "Qt Widgets" navigation.cppclassespage = "Qt Widgets C++ Classes" manifestmeta.highlighted.names = "QtWidgets/Calendar Widget Example" \ - "QtWidgets/Simple Tree Model Example" + "QtWidgets/Editable Tree Model Example" \ + "QtWidgets/Address Book Example" \ + "QtWidgets/Application Example" -- cgit v1.2.3 From fb880bbdff7b4ff3ef1a3451d868ce595a14c29f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lund=20Martsum?= Date: Tue, 21 Nov 2017 08:46:57 +0100 Subject: QMenu: Corner case size fix (high DPI + multi screen) We always need to set the QMenu screen explicit also when it is about to be shown on the primary screen. The reason is QWidget::metric (called from style/sizeHint) may use qApp->devicePixelRatioF() when it does not know about the topLevelWindow. That may not be the same value as DPR on primary screen. It can be argued that it likely is a bug in QWidget::metric, but fixing that looks to be a somewhat dangerous behavior change. Task-number: QTBUG-59794 Change-Id: I6ed0e808aa31bee5b77c0e19ce61a77548fdbb38 Reviewed-by: Morten Kristensen Reviewed-by: Richard Moe Gustavsen Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Gabriel de Dietrich --- src/widgets/widgets/qmenu.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 196348f8e8..cf306e63bd 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -853,8 +853,7 @@ void QMenuPrivate::adjustMenuScreen(const QPoint &p) // The windowHandle must point to the screen where the menu will be shown. // The (item) size calculations depend on the menu screen, // so a wrong screen would often cause wrong sizes (on high DPI) - const QScreen *primaryScreen = QApplication::primaryScreen(); - const QScreen *currentScreen = q->windowHandle() ? q->windowHandle()->screen() : primaryScreen; + const QScreen *currentScreen = q->windowHandle() ? q->windowHandle()->screen() : nullptr; const int screenNumberForPoint = QApplication::desktop()->screenNumber(p); QScreen *actualScreen = QGuiApplication::screens().at(screenNumberForPoint); if (actualScreen && currentScreen != actualScreen) { -- cgit v1.2.3 From 155f954d9941e9eee14d86ee7bc30411aea60dee Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 24 Nov 2017 08:49:35 +0100 Subject: Fix -Wclazy-connect-not-normalized in Windows code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qwindowsxpstyle.cpp(289,35): warning: Signature is not normalized. Use void* instead of void * [-Wclazy-connect-not-normalized] qwindowsxpstyle.cpp(292,35): warning: Signature is not normalized. Use void* instead of void * [-Wclazy-connect-not-normalized] Change-Id: I773530452c0837c5066f9174c25ae37e57086e76 Reviewed-by: Sérgio Martins --- src/widgets/dialogs/qwizard_win.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/widgets') diff --git a/src/widgets/dialogs/qwizard_win.cpp b/src/widgets/dialogs/qwizard_win.cpp index 666b192e9c..bedcd1b0c2 100644 --- a/src/widgets/dialogs/qwizard_win.cpp +++ b/src/widgets/dialogs/qwizard_win.cpp @@ -263,7 +263,7 @@ static bool getCaptionQFont(int dpi, QFont *result) QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface(); return ni && QMetaObject::invokeMethod(ni, "logFontToQFont", Qt::DirectConnection, Q_RETURN_ARG(QFont, *result), - Q_ARG(const void *, &logFont), + Q_ARG(const void*, &logFont), Q_ARG(int, dpi)); } -- cgit v1.2.3 From c9f68a5858f053aa5a0b1e8fd4c751ed441e0338 Mon Sep 17 00:00:00 2001 From: Yulong Bai Date: Tue, 21 Nov 2017 14:38:15 +0100 Subject: QFusionStyle: fix the checkbox rendering in HiDPI situation 1. Make the checkbox's box size hidpi scale-able. Making the size not only anchored to icon size, but also the menuItem's rect height in empty or too small icon cases. 2. Make the checkmark's pen width in propotion to the box's size to keep consistent visual effects among different dpi settings 3. Also make the radio button hidpi scale-able. Task-number: QTBUG-63576 Change-Id: I4369aaa18ee68908a26a118cf04292ee4c3e9847 Reviewed-by: Richard Moe Gustavsen --- src/widgets/styles/qfusionstyle.cpp | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp index 774eca1018..0b56c1e3a8 100644 --- a/src/widgets/styles/qfusionstyle.cpp +++ b/src/widgets/styles/qfusionstyle.cpp @@ -786,7 +786,7 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, painter->drawRect(rect); QColor checkMarkColor = option->palette.text().color().darker(120); - const int checkMarkPadding = QStyleHelper::dpiScaled(3); + const int checkMarkPadding = 1 + rect.width() * 0.2; // at least one pixel padding if (checkbox->state & State_NoChange) { gradient = QLinearGradient(rect.topLeft(), rect.bottomLeft()); @@ -800,18 +800,20 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, painter->drawRect(rect.adjusted(checkMarkPadding, checkMarkPadding, -checkMarkPadding, -checkMarkPadding)); } else if (checkbox->state & (State_On)) { - QPen checkPen = QPen(checkMarkColor, QStyleHelper::dpiScaled(1.8)); + qreal penWidth = QStyleHelper::dpiScaled(1.8); + penWidth = qMax(penWidth , 0.18 * rect.height()); + penWidth = qMin(penWidth , 0.30 * rect.height()); + QPen checkPen = QPen(checkMarkColor, penWidth); checkMarkColor.setAlpha(210); - painter->translate(-1, 0.5); + painter->translate(-0.8, 0.5); painter->setPen(checkPen); painter->setBrush(Qt::NoBrush); - painter->translate(0.2, 0.0); // Draw checkmark QPainterPath path; - path.moveTo(2 + checkMarkPadding, rect.height() / 2.0); + path.moveTo(1.33 * checkMarkPadding, rect.height() / 2.0); path.lineTo(rect.width() / 2.0, rect.height() - checkMarkPadding); - path.lineTo(rect.width() - checkMarkPadding - 0.5, checkMarkPadding); + path.lineTo(rect.width() - checkMarkPadding * 0.92, checkMarkPadding); painter->drawPath(path.translated(rect.topLeft())); } } @@ -1580,8 +1582,9 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio bool enabled = menuItem->state & State_Enabled; bool ignoreCheckMark = false; - int checkcol = qMax(menuItem->maxIconWidth, 20); - + const int checkColHOffset = windowsItemHMargin + windowsItemFrame - 1; + int checkcol = qMax(menuItem->rect.height() * 0.7, + qMax(menuItem->maxIconWidth * 1.0, dpiScaled(17))); // icon checkbox's highlihgt column width if ( #if QT_CONFIG(combobox) qobject_cast(widget) || @@ -1591,7 +1594,9 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio if (!ignoreCheckMark) { // Check - QRect checkRect(option->rect.left() + 7, option->rect.center().y() - 6, 14, 14); + const int boxMargin = dpiScaled(4); + const int boxWidth = checkcol - 2 * boxMargin; + QRect checkRect(option->rect.left() + boxMargin + checkColHOffset, option->rect.center().y() - boxWidth/2 + 1, boxWidth, boxWidth); checkRect = visualRect(menuItem->direction, menuItem->rect, checkRect); if (checkable) { if (menuItem->checkType & QStyleOptionMenuItem::Exclusive) { @@ -1603,7 +1608,8 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio QPalette::ColorRole textRole = !enabled ? QPalette::Text: selected ? QPalette::HighlightedText : QPalette::ButtonText; painter->setBrush(option->palette.brush( option->palette.currentColorGroup(), textRole)); - painter->drawEllipse(checkRect.adjusted(4, 4, -4, -4)); + const int adjustment = checkRect.height() * 0.3; + painter->drawEllipse(checkRect.adjusted(adjustment, adjustment, -adjustment, -adjustment)); } } else { // Check box @@ -1632,7 +1638,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio QPainter *p = painter; QRect vCheckRect = visualRect(opt->direction, menuitem->rect, - QRect(menuitem->rect.x() + 4, menuitem->rect.y(), + QRect(menuitem->rect.x() + checkColHOffset, menuitem->rect.y(), checkcol, menuitem->rect.height())); if (!menuItem->icon.isNull()) { QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal; @@ -1683,7 +1689,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio discol = menuitem->palette.text().color(); p->setPen(discol); } - int xm = windowsItemFrame + checkcol + windowsItemHMargin + 2; + int xm = checkColHOffset + checkcol + windowsItemHMargin; int xpos = menuitem->rect.x() + xm; QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin); -- cgit v1.2.3 From 77687bc64e9ae7172586271de91b266be7ab19ce Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 29 Aug 2017 09:02:31 +0200 Subject: QFileSystemModel::index(): Add a list size check This prevents an out of range assert when monitoring directory with activity (for example, temp). Task-number: QTBUG-62841 Change-Id: Id3aa4098e9bbd665c7b17a667516885fa7c7f473 Reviewed-by: Jesus Fernandez Reviewed-by: Martin Rotter Reviewed-by: Richard Moe Gustavsen --- src/widgets/dialogs/qfilesystemmodel.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/widgets') diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp index bf14b5c6fd..179c5861c9 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -260,7 +260,10 @@ QModelIndex QFileSystemModel::index(int row, int column, const QModelIndex &pare Q_ASSERT(parentNode); // now get the internal pointer for the index - const QString &childName = parentNode->visibleChildren.at(d->translateVisibleLocation(parentNode, row)); + const int i = d->translateVisibleLocation(parentNode, row); + if (i >= parentNode->visibleChildren.size()) + return QModelIndex(); + const QString &childName = parentNode->visibleChildren.at(i); const QFileSystemModelPrivate::QFileSystemNode *indexNode = parentNode->children.value(childName); Q_ASSERT(indexNode); -- cgit v1.2.3 From d2d6c6f7813fa38ced6b80ead763ed6e6daaa951 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lund=20Martsum?= Date: Thu, 7 Dec 2017 11:19:40 +0100 Subject: QWidgetResizeHandler - undo (potential) move break When the mode is center we are typically moving the dock widget, but we should however not stop if the mode is Center. Though the regression (in commit e662b4ed721ee36f0a17cc413494b7d09395d52e) is not easy to reproduce it is clear that the code later may call "mouseMoveEvent(e)" and the mode is also checked for being Center and in that case the eventfilter (function) returns true (not false). Change-Id: I3936ec56833d613f78920d9ccf8ddb66e19e9802 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/widgets/widgets/qwidgetresizehandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/widgets') diff --git a/src/widgets/widgets/qwidgetresizehandler.cpp b/src/widgets/widgets/qwidgetresizehandler.cpp index 09c5e52219..8a1f26dbc2 100644 --- a/src/widgets/widgets/qwidgetresizehandler.cpp +++ b/src/widgets/widgets/qwidgetresizehandler.cpp @@ -120,7 +120,7 @@ bool QWidgetResizeHandler::eventFilter(QObject *o, QEvent *ee) break; const QRect widgetRect = widget->rect().marginsAdded(QMargins(range, range, range, range)); const QPoint cursorPoint = widget->mapFromGlobal(e->globalPos()); - if (!widgetRect.contains(cursorPoint) || mode == Center || mode == Nowhere) + if (!widgetRect.contains(cursorPoint) || mode == Nowhere) return false; if (e->button() == Qt::LeftButton) { #if 0 // Used to be included in Qt4 for Q_WS_X11 -- cgit v1.2.3 From eff7a5f38cd2814c57a8214dbd53bd6fd345023b Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sun, 10 Dec 2017 18:06:05 +0100 Subject: QFileSystemModel: properly align file size column The file size column was not properly horizontally aligned. The model only returned Qt::AlignRight with no horizontal alignment. This lead to a top alignment within QStyle::alignedRect(). Task-number: QTBUG-64098 Change-Id: Iaef30200a63bd0975c88a67d0af2eb1d5254f588 Reviewed-by: Richard Moe Gustavsen --- 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 179c5861c9..7458cfdd80 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -747,7 +747,7 @@ QVariant QFileSystemModel::data(const QModelIndex &index, int role) const break; case Qt::TextAlignmentRole: if (index.column() == 1) - return Qt::AlignRight; + return QVariant(Qt::AlignTrailing | Qt::AlignVCenter); break; case FilePermissions: int p = permissions(index); -- cgit v1.2.3 From 26aa20407d2e3feb97d80dabc1d922d4ef21a433 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Thu, 30 Nov 2017 21:45:32 +0100 Subject: QHeaderView: Fix painting vertical headers in rtl mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In rtl mode, the headers were not painted correctly. The style option selectedPosition was not filled correctly and the paint rect needed to be adjusted by one pixel to fit the table grid. Task-number: QTBUG-56520 Change-Id: Ib92d5ab6ff730bba67eca35c83cd638e613f58b9 Reviewed-by: Friedemann Kleint Reviewed-by: Thorbjørn Lund Martsum Reviewed-by: Richard Moe Gustavsen --- src/widgets/itemviews/qheaderview.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index 4e4c9572a3..9eb6c3465f 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -2319,18 +2319,20 @@ void QHeaderView::paintEvent(QPaintEvent *e) d->prepareSectionSelected(); // clear and resize the bit array QRect currentSectionRect; - int logical; const int width = d->viewport->width(); const int height = d->viewport->height(); + const int rtlHorizontalOffset = d->reverse() ? 1 : 0; for (int i = start; i <= end; ++i) { if (d->isVisualIndexHidden(i)) continue; painter.save(); - logical = logicalIndex(i); + const int logical = logicalIndex(i); if (d->orientation == Qt::Horizontal) { - currentSectionRect.setRect(sectionViewportPosition(logical), 0, sectionSize(logical), height); + currentSectionRect.setRect(sectionViewportPosition(logical) + rtlHorizontalOffset, + 0, sectionSize(logical), height); } else { - currentSectionRect.setRect(0, sectionViewportPosition(logical), width, sectionSize(logical)); + currentSectionRect.setRect(0, sectionViewportPosition(logical), + width, sectionSize(logical)); } currentSectionRect.translate(offset); @@ -2776,9 +2778,9 @@ void QHeaderView::paintSection(QPainter *painter, const QRect &rect, int logical if (first && last) opt.position = QStyleOptionHeader::OnlyOneSection; else if (first) - opt.position = QStyleOptionHeader::Beginning; + opt.position = d->reverse() ? QStyleOptionHeader::End : QStyleOptionHeader::Beginning; else if (last) - opt.position = QStyleOptionHeader::End; + opt.position = d->reverse() ? QStyleOptionHeader::Beginning : QStyleOptionHeader::End; else opt.position = QStyleOptionHeader::Middle; opt.orientation = d->orientation; -- cgit v1.2.3 From 06e903cf684a829716736702b95b66846c713fd5 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sat, 9 Dec 2017 22:41:41 +0100 Subject: QHeaderView: Use correct font for drag'n'drop indicator pixmap QHeaderViewPrivate::setupSectionIndicator() did not honor the font set for the QHeaderView which results in a wrong font in the indicator pixmap. Fix it by using the correct font for the dragged section as it is done in paintEvent() Task-number: QTBUG-65017 Change-Id: I5393c6861073de22f30ffa13e12c5e2cf8aa7776 Reviewed-by: Friedemann Kleint Reviewed-by: Richard Moe Gustavsen --- src/widgets/itemviews/qheaderview.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/widgets') diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index 9eb6c3465f..0905a20812 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -3159,6 +3159,15 @@ void QHeaderViewPrivate::setupSectionIndicator(int section, int position) QRect rect(0, 0, w, h); QPainter painter(&pm); + const QVariant variant = model->headerData(section, orientation, + Qt::FontRole); + if (variant.isValid() && variant.canConvert()) { + const QFont sectionFont = qvariant_cast(variant); + painter.setFont(sectionFont); + } else { + painter.setFont(q->font()); + } + painter.setOpacity(0.75); q->paintSection(&painter, rect, section); painter.end(); -- cgit v1.2.3 From 7257862fb2edfab0219d6cd45c83677049404f7d Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 11 Dec 2017 16:55:02 +0100 Subject: Set sharedPainter correctly for QGraphicsEffect Autotest is taken from the previously reverted 8b1377fde16a2049a1c27f6d005bff84a8f85f28. Task-number: QTBUG-60231 Change-Id: I44dd79cba22b6baefdd6d95c176790bef0b7eafe Reviewed-by: Andy Nichols --- src/widgets/kernel/qwidget.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index de734b6f51..125f1cf246 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -5528,11 +5528,11 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP setSystemClip(pdev, rgn.translated(offset)); QPainter p(pdev); p.translate(offset); - context.painter = &p; + context.painter = context.sharedPainter = &p; graphicsEffect->draw(&p); setSystemClip(pdev, QRegion()); } else { - context.painter = sharedPainter; + context.painter = context.sharedPainter = sharedPainter; if (sharedPainter->worldTransform() != sourced->lastEffectTransform) { sourced->invalidateCache(); sourced->lastEffectTransform = sharedPainter->worldTransform(); -- cgit v1.2.3 From ba44cdae38406c429c7fb43863a6883bd0f79cf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 1 Dec 2017 19:03:05 +0100 Subject: Teach QPlatformWindow about safe area margins and implement for iOS The safe area margins of a window represent the area that is safe to place content within, without intersecting areas of the screen where system UI is placed, or where a screen bezel may cover the content. QWidget will incorporate the safe area margins into its contents margins, so that they are are never smaller than the safe area margins. This can be disabled by unsetting the Qt::WA_ContentsMarginsRespectsSafeArea widget attribute, which is set by default. QLayouts will automatically use the contents area of a widget for their layout, unless the Qt::WA_LayoutOnEntireRect attribute has been set. This can be used, along with a contents margin of 0 on the actual layout, to allow e.g. a background image to underlay the status bar and other system areas on an iOS device, while still allowing child widgets of that background to be inset based on the safe area. [ChangeLog][iOS/tvOS] Qt will now take the safe area margins of the device into account when computing layouts for QtWidgets. Change-Id: Ife3827ab663f0625c1451e75b14fb8eeffb00754 Reviewed-by: Richard Moe Gustavsen --- src/widgets/kernel/qwidget.cpp | 154 ++++++++++++++++++++++++++++------- src/widgets/kernel/qwidget_p.h | 3 + src/widgets/kernel/qwidgetwindow.cpp | 7 ++ 3 files changed, 134 insertions(+), 30 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 125f1cf246..f279453ebd 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1198,6 +1198,7 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f) q->setAttribute(Qt::WA_QuitOnClose); // might be cleared in adjustQuitOnCloseAttribute() adjustQuitOnCloseAttribute(); + q->setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea); q->setAttribute(Qt::WA_WState_Hidden); //give potential windows a bigger "pre-initial" size; create_sys() will give them a new size later @@ -1423,8 +1424,6 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO Q_UNUSED(initializeWindow); Q_UNUSED(destroyOldWindow); - Qt::WindowFlags flags = data.window_flags; - if (!q->testAttribute(Qt::WA_NativeWindow) && !q->isWindow()) return; // we only care about real toplevels @@ -1442,12 +1441,19 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO win->setProperty(propertyName, q->property(propertyName)); } + Qt::WindowFlags &flags = data.window_flags; + +#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) + if (q->testAttribute(Qt::WA_ContentsMarginsRespectsSafeArea)) + flags |= Qt::MaximizeUsingFullscreenGeometryHint; +#endif + if (q->testAttribute(Qt::WA_ShowWithoutActivating)) win->setProperty("_q_showWithoutActivating", QVariant(true)); if (q->testAttribute(Qt::WA_MacAlwaysShowToolWindow)) win->setProperty("_q_macAlwaysShowToolWindow", QVariant::fromValue(QVariant(true))); setNetWmWindowTypes(true); // do nothing if none of WA_X11NetWmWindowType* is set - win->setFlags(data.window_flags); + win->setFlags(flags); fixPosIncludesFrame(); if (q->testAttribute(Qt::WA_Moved) || !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowManagement)) @@ -7588,21 +7594,7 @@ void QWidget::setContentsMargins(int left, int top, int right, int bottom) d->rightmargin = right; d->bottommargin = bottom; - if (QLayout *l=d->layout) - l->update(); //force activate; will do updateGeometry - else - updateGeometry(); - - if (isVisible()) { - update(); - QResizeEvent e(data->crect.size(), data->crect.size()); - QApplication::sendEvent(this, &e); - } else { - setAttribute(Qt::WA_PendingResizeEvent, true); - } - - QEvent e(QEvent::ContentsRectChange); - QApplication::sendEvent(this, &e); + d->updateContentsRect(); } /*! @@ -7627,6 +7619,27 @@ void QWidget::setContentsMargins(const QMargins &margins) margins.right(), margins.bottom()); } +void QWidgetPrivate::updateContentsRect() +{ + Q_Q(QWidget); + + if (layout) + layout->update(); //force activate; will do updateGeometry + else + q->updateGeometry(); + + if (q->isVisible()) { + q->update(); + QResizeEvent e(q->data->crect.size(), q->data->crect.size()); + QApplication::sendEvent(q, &e); + } else { + q->setAttribute(Qt::WA_PendingResizeEvent, true); + } + + QEvent e(QEvent::ContentsRectChange); + QApplication::sendEvent(q, &e); +} + /*! Returns the widget's contents margins for \a left, \a top, \a right, and \a bottom. @@ -7635,15 +7648,22 @@ void QWidget::setContentsMargins(const QMargins &margins) */ void QWidget::getContentsMargins(int *left, int *top, int *right, int *bottom) const { - Q_D(const QWidget); + QMargins m = contentsMargins(); if (left) - *left = d->leftmargin; + *left = m.left(); if (top) - *top = d->topmargin; + *top = m.top(); if (right) - *right = d->rightmargin; + *right = m.right(); if (bottom) - *bottom = d->bottommargin; + *bottom = m.bottom(); +} + +// FIXME: Move to qmargins.h for next minor Qt release +QMargins operator|(const QMargins &m1, const QMargins &m2) +{ + return QMargins(qMax(m1.left(), m2.left()), qMax(m1.top(), m2.top()), + qMax(m1.right(), m2.right()), qMax(m1.bottom(), m2.bottom())); } /*! @@ -7656,10 +7676,11 @@ void QWidget::getContentsMargins(int *left, int *top, int *right, int *bottom) c QMargins QWidget::contentsMargins() const { Q_D(const QWidget); - return QMargins(d->leftmargin, d->topmargin, d->rightmargin, d->bottommargin); + QMargins userMargins(d->leftmargin, d->topmargin, d->rightmargin, d->bottommargin); + return testAttribute(Qt::WA_ContentsMarginsRespectsSafeArea) ? + userMargins | d->safeAreaMargins() : userMargins; } - /*! Returns the area inside the widget's margins. @@ -7667,14 +7688,87 @@ QMargins QWidget::contentsMargins() const */ QRect QWidget::contentsRect() const { - Q_D(const QWidget); - return QRect(QPoint(d->leftmargin, d->topmargin), - QPoint(data->crect.width() - 1 - d->rightmargin, - data->crect.height() - 1 - d->bottommargin)); - + return rect() - contentsMargins(); } +QMargins QWidgetPrivate::safeAreaMargins() const +{ + Q_Q(const QWidget); + QWidget *nativeWidget = q->window(); + if (!nativeWidget->windowHandle()) + return QMargins(); + + QPlatformWindow *platformWindow = nativeWidget->windowHandle()->handle(); + if (!platformWindow) + return QMargins(); + + QMargins safeAreaMargins = platformWindow->safeAreaMargins(); + + if (!q->isWindow()) { + // In theory the native parent widget already has a contents rect reflecting + // the safe area of that widget, but we can't be sure that the widget or child + // widgets of that widget have respected the contents rect when setting their + // geometry, so we need to manually compute the safe area. + + // Unless the native widget doesn't have any margins, in which case there's + // nothing for us to compute. + if (safeAreaMargins.isNull()) + return QMargins(); + + // Or, if one of our ancestors are in a layout that does not have WA_LayoutOnEntireRect + // set, then we know that the layout has already taken care of placing us inside the + // safe area, by taking the contents rect of its parent widget into account. + const QWidget *assumedSafeWidget = nullptr; + for (const QWidget *w = q; w != nativeWidget; w = w->parentWidget()) { + QWidget *parentWidget = w->parentWidget(); + if (parentWidget->testAttribute(Qt::WA_LayoutOnEntireRect)) + continue; // Layout not going to help us + + QLayout *layout = parentWidget->layout(); + if (!layout) + continue; + if (layout->geometry().isNull()) + continue; // Layout hasn't been activated yet + + if (layout->indexOf(const_cast(w)) < 0) + continue; // Widget is not in layout + + assumedSafeWidget = w; + break; + } + +#if !defined(QT_DEBUG) + if (assumedSafeWidget) { + // We found a layout that we assume will take care of keeping us within the safe area + // For debug builds we still map the safe area using the fallback logic, so that we + // can detect any misbehaving layouts. + return QMargins(); + } +#endif + + // In all other cases we need to map the safe area of the native parent to the widget. + // This depends on the widget being positioned and sized already, which means the initial + // layout will be wrong, but the layout will then adjust itself. + QPoint topLeftMargins = q->mapFrom(nativeWidget, QPoint(safeAreaMargins.left(), safeAreaMargins.top())); + QRect widgetRect = q->isVisible() ? q->visibleRegion().boundingRect() : q->rect(); + QPoint bottomRightMargins = widgetRect.bottomRight() - q->mapFrom(nativeWidget, + nativeWidget->rect().bottomRight() - QPoint(safeAreaMargins.right(), safeAreaMargins.bottom())); + + // Margins should never be negative + safeAreaMargins = QMargins(qMax(0, topLeftMargins.x()), qMax(0, topLeftMargins.y()), + qMax(0, bottomRightMargins.x()), qMax(0, bottomRightMargins.y())); + + if (!safeAreaMargins.isNull() && assumedSafeWidget) { + QLayout *layout = assumedSafeWidget->parentWidget()->layout(); + qWarning() << layout << "is laying out" << assumedSafeWidget + << "outside of the contents rect of" << layout->parentWidget(); + return QMargins(); // Return empty margin to visually highlight the error + } + } + + return safeAreaMargins; +} /*! \fn void QWidget::customContextMenuRequested(const QPoint &pos) diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index a24d13e0e1..0c012d1932 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -513,6 +513,9 @@ public: void setLayoutItemMargins(int left, int top, int right, int bottom); void setLayoutItemMargins(QStyle::SubElement element, const QStyleOption *opt = 0); + void updateContentsRect(); + QMargins safeAreaMargins() const; + // aboutToDestroy() is called just before the contents of // QWidget::destroy() is executed. It's used to signal QWidget // sub-classes that their internals are about to be released. diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index abaebad821..165dce04e9 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -87,6 +87,13 @@ public: } QRectF closestAcceptableGeometry(const QRectF &rect) const Q_DECL_OVERRIDE; + + void processSafeAreaMarginsChanged() override + { + Q_Q(QWidgetWindow); + if (QWidget *widget = q->widget()) + QWidgetPrivate::get(widget)->updateContentsRect(); + } }; QRectF QWidgetWindowPrivate::closestAcceptableGeometry(const QRectF &rect) const -- cgit v1.2.3 From 3d65284b60bfc8e01c4ea4b86344a508b6f49358 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 14 Dec 2017 11:55:16 +0100 Subject: QWidget: Remove dead code for handling painting without a backingstore Change-Id: Iacf852c8620ea06d790cddcf6774b772f754e08a Reviewed-by: Richard Moe Gustavsen --- src/widgets/kernel/qwidget.cpp | 67 ++++++++++++------------------------------ 1 file changed, 18 insertions(+), 49 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index f279453ebd..a82f97270d 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -127,15 +127,6 @@ QT_BEGIN_NAMESPACE -static bool qt_enable_backingstore = true; -#if 0 // Used to be included in Qt4 for Q_WS_X11 -// for compatibility with Qt 4.0 -Q_WIDGETS_EXPORT void qt_x11_set_global_double_buffer(bool enable) -{ - qt_enable_backingstore = enable; -} -#endif - #if 0 // Used to be included in Qt4 for Q_WS_MAC bool qt_mac_clearDirtyOnWidgetInsideDrawWidget = false; #endif @@ -146,11 +137,6 @@ static inline bool qRectIntersects(const QRect &r1, const QRect &r2) qMax(r1.top(), r2.top()) <= qMin(r1.bottom(), r2.bottom())); } -static inline bool hasBackingStoreSupport() -{ - return true; -} - #if 0 // Used to be included in Qt4 for Q_WS_MAC # define QT_NO_PAINT_DEBUG #endif @@ -1351,8 +1337,7 @@ void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow) // a real toplevel window needs a backing store if (isWindow() && windowType() != Qt::Desktop) { d->topData()->backingStoreTracker.destroy(); - if (hasBackingStoreSupport()) - d->topData()->backingStoreTracker.create(this); + d->topData()->backingStoreTracker.create(this); } d->setModal_sys(); @@ -2339,7 +2324,7 @@ bool QWidgetPrivate::paintOnScreen() const return true; } - return !qt_enable_backingstore; + return false; #endif } @@ -11036,15 +11021,11 @@ void QWidget::repaint(const QRect &rect) if (!isVisible() || !updatesEnabled() || rect.isEmpty()) return; - if (hasBackingStoreSupport()) { - QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); - if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) { - tlwExtra->inRepaint = true; - tlwExtra->backingStoreTracker->markDirty(rect, this, QWidgetBackingStore::UpdateNow); - tlwExtra->inRepaint = false; - } - } else { - d->repaint_sys(rect); + QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); + if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) { + tlwExtra->inRepaint = true; + tlwExtra->backingStoreTracker->markDirty(rect, this, QWidgetBackingStore::UpdateNow); + tlwExtra->inRepaint = false; } } @@ -11065,15 +11046,11 @@ void QWidget::repaint(const QRegion &rgn) if (!isVisible() || !updatesEnabled() || rgn.isEmpty()) return; - if (hasBackingStoreSupport()) { - QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); - if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) { - tlwExtra->inRepaint = true; - tlwExtra->backingStoreTracker->markDirty(rgn, this, QWidgetBackingStore::UpdateNow); - tlwExtra->inRepaint = false; - } - } else { - d->repaint_sys(rgn); + QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); + if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) { + tlwExtra->inRepaint = true; + tlwExtra->backingStoreTracker->markDirty(rgn, this, QWidgetBackingStore::UpdateNow); + tlwExtra->inRepaint = false; } } @@ -11127,13 +11104,9 @@ void QWidget::update(const QRect &rect) return; } - if (hasBackingStoreSupport()) { - QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); - if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) - tlwExtra->backingStoreTracker->markDirty(r, this); - } else { - d_func()->repaint_sys(r); - } + QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); + if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) + tlwExtra->backingStoreTracker->markDirty(r, this); } /*! @@ -11156,13 +11129,9 @@ void QWidget::update(const QRegion &rgn) return; } - if (hasBackingStoreSupport()) { - QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); - if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) - tlwExtra->backingStoreTracker->markDirty(r, this); - } else { - d_func()->repaint_sys(r); - } + QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); + if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) + tlwExtra->backingStoreTracker->markDirty(r, this); } -- cgit v1.2.3 From d48c502ce535c913424440557cdfe7fa6e383dea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 14 Dec 2017 12:14:11 +0100 Subject: Share QWidget update and repaint code for QRect and QRegion QWidgetBackingStore::markDirty has an optimization for QRect, so we don't want to unify these two functions by calling update/repaint(QRegion(rect)). Change-Id: Id2a42f478f71863da45697041e0ab0130c74b9d2 Reviewed-by: Richard Moe Gustavsen --- src/widgets/kernel/qwidget.cpp | 74 ++++++++++++++++-------------------------- src/widgets/kernel/qwidget_p.h | 7 ++++ 2 files changed, 35 insertions(+), 46 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index a82f97270d..b57a0d4779 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -11012,21 +11012,7 @@ void QWidget::repaint(int x, int y, int w, int h) void QWidget::repaint(const QRect &rect) { Q_D(QWidget); - - if (testAttribute(Qt::WA_WState_ConfigPending)) { - update(rect); - return; - } - - if (!isVisible() || !updatesEnabled() || rect.isEmpty()) - return; - - QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); - if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) { - tlwExtra->inRepaint = true; - tlwExtra->backingStoreTracker->markDirty(rect, this, QWidgetBackingStore::UpdateNow); - tlwExtra->inRepaint = false; - } + d->repaint(rect); } /*! @@ -11037,19 +11023,21 @@ void QWidget::repaint(const QRect &rect) void QWidget::repaint(const QRegion &rgn) { Q_D(QWidget); + d->repaint(rgn); +} - if (testAttribute(Qt::WA_WState_ConfigPending)) { - update(rgn); - return; - } +template +void QWidgetPrivate::repaint(T r) +{ + Q_Q(QWidget); - if (!isVisible() || !updatesEnabled() || rgn.isEmpty()) + if (!q->isVisible() || !q->updatesEnabled() || r.isEmpty()) return; - QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); + QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData(); if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) { tlwExtra->inRepaint = true; - tlwExtra->backingStoreTracker->markDirty(rgn, this, QWidgetBackingStore::UpdateNow); + tlwExtra->backingStoreTracker->markDirty(r, q, QWidgetBackingStore::UpdateNow); tlwExtra->inRepaint = false; } } @@ -11091,22 +11079,8 @@ void QWidget::update() */ void QWidget::update(const QRect &rect) { - if (!isVisible() || !updatesEnabled()) - return; - - QRect r = rect & QWidget::rect(); - - if (r.isEmpty()) - return; - - if (testAttribute(Qt::WA_WState_InPaintEvent)) { - QApplication::postEvent(this, new QUpdateLaterEvent(r)); - return; - } - - QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); - if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) - tlwExtra->backingStoreTracker->markDirty(r, this); + Q_D(QWidget); + d->update(rect); } /*! @@ -11116,25 +11090,33 @@ void QWidget::update(const QRect &rect) */ void QWidget::update(const QRegion &rgn) { - if (!isVisible() || !updatesEnabled()) + Q_D(QWidget); + d->update(rgn); +} + +template +void QWidgetPrivate::update(T r) +{ + Q_Q(QWidget); + + if (!q->isVisible() || !q->updatesEnabled()) return; - QRegion r = rgn & QWidget::rect(); + T clipped = r & q->rect(); - if (r.isEmpty()) + if (clipped.isEmpty()) return; - if (testAttribute(Qt::WA_WState_InPaintEvent)) { - QApplication::postEvent(this, new QUpdateLaterEvent(r)); + if (q->testAttribute(Qt::WA_WState_InPaintEvent)) { + QApplication::postEvent(q, new QUpdateLaterEvent(clipped)); return; } - QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); + QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData(); if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) - tlwExtra->backingStoreTracker->markDirty(r, this); + tlwExtra->backingStoreTracker->markDirty(clipped, q); } - /*! \internal diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 0c012d1932..15704f32c9 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -342,6 +342,13 @@ public: QPainter *sharedPainter() const; void setSharedPainter(QPainter *painter); QWidgetBackingStore *maybeBackingStore() const; + + template + void repaint(T t); + + template + void update(T t); + void init(QWidget *desktopWidget, Qt::WindowFlags f); void create_sys(WId window, bool initializeWindow, bool destroyOldWindow); void createRecursively(); -- cgit v1.2.3 From 9e1b6b6e53d01bed76dc624e4b6c0d5f7748bf85 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 28 Jul 2017 09:00:18 +0200 Subject: QFileSystemModel: Enable experimental code path for per-file watching QFileSystemModel had a #ifdefed out experimental code path for watching single files to track changes in size, which got outdated over time. Replace the #ifdef 0 by a check for the environment variable QT_FILESYSTEMMODEL_WATCH_FILES, fix it up and apply some fixes to related code to make it work: - Split file names signaled by QFileSystemWatcher on '/' always. - Do not instantiate QDirIterator on "", which means "current directory" and results in mixed-up directories. - Check on lastModified() in QExtendedInformation::operator==() so that changes trigger an update in _q_fileSystemChanged(). - Fix the #ifdefed out part to compile and not to add directories to the watcher. [ChangeLog][QtWidgets][QFileSystemModel] It is now possible to enable per-file watching by setting the environment variable QT_FILESYSTEMMODEL_WATCH_FILES, allowing to track for example changes in file size. Task-number: QTBUG-46684 Change-Id: Ia5da9170866416c9529251f889814b23d7a7d069 Reviewed-by: Edward Welbourne --- src/widgets/dialogs/qfileinfogatherer.cpp | 35 ++++++++++++++++--------------- src/widgets/dialogs/qfileinfogatherer_p.h | 3 ++- 2 files changed, 20 insertions(+), 18 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/dialogs/qfileinfogatherer.cpp b/src/widgets/dialogs/qfileinfogatherer.cpp index 710ee611b9..aef13a563f 100644 --- a/src/widgets/dialogs/qfileinfogatherer.cpp +++ b/src/widgets/dialogs/qfileinfogatherer.cpp @@ -196,7 +196,7 @@ void QFileInfoGatherer::fetchExtendedInformation(const QString &path, const QStr */ void QFileInfoGatherer::updateFile(const QString &filePath) { - QString dir = filePath.mid(0, filePath.lastIndexOf(QDir::separator())); + QString dir = filePath.mid(0, filePath.lastIndexOf(QLatin1Char('/'))); QString fileName = filePath.mid(dir.length() + 1); fetchExtendedInformation(dir, QStringList(fileName)); } @@ -267,19 +267,19 @@ QExtendedInformation QFileInfoGatherer::getInfo(const QFileInfo &fileInfo) const info.icon = m_iconProvider->icon(fileInfo); info.displayType = m_iconProvider->type(fileInfo); #ifndef QT_NO_FILESYSTEMWATCHER - // ### Not ready to listen all modifications - #if 0 - // Enable the next two commented out lines to get updates when the file sizes change... + // ### Not ready to listen all modifications by default + static const bool watchFiles = qEnvironmentVariableIsSet("QT_FILESYSTEMMODEL_WATCH_FILES"); + if (watchFiles) { if (!fileInfo.exists() && !fileInfo.isSymLink()) { - info.size = -1; - //watcher->removePath(fileInfo.absoluteFilePath()); + watcher->removePath(fileInfo.absoluteFilePath()); } else { - if (!fileInfo.absoluteFilePath().isEmpty() && fileInfo.exists() && fileInfo.isReadable() - && !watcher->files().contains(fileInfo.absoluteFilePath())) { - //watcher->addPath(fileInfo.absoluteFilePath()); + const QString path = fileInfo.absoluteFilePath(); + if (!path.isEmpty() && fileInfo.exists() && fileInfo.isFile() && fileInfo.isReadable() + && !watcher->files().contains(path)) { + watcher->addPath(path); } } - #endif + } #endif #ifdef Q_OS_WIN @@ -329,14 +329,15 @@ void QFileInfoGatherer::getFileInfos(const QString &path, const QStringList &fil QVector > updatedFiles; QStringList filesToCheck = files; - QString itPath = QDir::fromNativeSeparators(files.isEmpty() ? path : QLatin1String("")); - QDirIterator dirIt(itPath, QDir::AllEntries | QDir::System | QDir::Hidden); QStringList allFiles; - while (!abort.load() && dirIt.hasNext()) { - dirIt.next(); - fileInfo = dirIt.fileInfo(); - allFiles.append(fileInfo.fileName()); - fetch(fileInfo, base, firstTime, updatedFiles, path); + if (files.isEmpty()) { + QDirIterator dirIt(path, QDir::AllEntries | QDir::System | QDir::Hidden); + while (!abort.load() && dirIt.hasNext()) { + dirIt.next(); + fileInfo = dirIt.fileInfo(); + allFiles.append(fileInfo.fileName()); + fetch(fileInfo, base, firstTime, updatedFiles, path); + } } if (!allFiles.isEmpty()) emit newListOfFiles(path, allFiles); diff --git a/src/widgets/dialogs/qfileinfogatherer_p.h b/src/widgets/dialogs/qfileinfogatherer_p.h index 52578126de..0cf2ed1f58 100644 --- a/src/widgets/dialogs/qfileinfogatherer_p.h +++ b/src/widgets/dialogs/qfileinfogatherer_p.h @@ -84,7 +84,8 @@ public: bool operator ==(const QExtendedInformation &fileInfo) const { return mFileInfo == fileInfo.mFileInfo && displayType == fileInfo.displayType - && permissions() == fileInfo.permissions(); + && permissions() == fileInfo.permissions() + && lastModified() == fileInfo.lastModified(); } #ifndef QT_NO_FSFILEENGINE -- cgit v1.2.3 From 1adb1ef6bab6247f5914e94380f8b05e11cb8d7e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 30 Oct 2017 15:16:33 +0100 Subject: QStyleSheetStyle: Draw menu item also when font is set Task-number: QTBUG-64055 Change-Id: I0674e7b43bb56aa1834c8df10794714dbcc4e5e3 Reviewed-by: Andy Shaw --- src/widgets/styles/qstylesheetstyle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/widgets') diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 6a99d21988..e8b90b87b3 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -3655,7 +3655,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q if ((pseudo == PseudoElement_MenuSeparator) && subRule.hasDrawable()) { subRule.drawRule(p, opt->rect); } else if ((pseudo == PseudoElement_Item) - && (allRules.hasBox() || allRules.hasBorder() + && (allRules.hasBox() || allRules.hasBorder() || subRule.hasFont || (allRules.background() && !allRules.background()->pixmap.isNull()))) { subRule.drawRule(p, opt->rect); if (subRule.hasBackground()) { -- cgit v1.2.3 From 93dabeba9dc5f6cbab60e65b3cc8df5fe48745a9 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 17 Nov 2017 20:57:00 +0100 Subject: QTreeView: Make sure QHeaderView is notified on layoutChanged() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QHeaderViewPrivate::_q_layoutChanged() was not called when used in a QTreeView because it was explicitly disconnected in setModel(). The disconnect was added sometime prio to Qt 4.3, but there the signal was connected to the doItemsLayout() slot. This was correct since QTreeView::doItemsLayout() is calling header->doItemsLayout(). In Qt 4.3.0 _q_layoutChanged() was introduced and the disconnect was adjusted. But since _q_layoutChanged() is doing much more than doItemsLayout() (e.g. restoring hidden sections), functionality was lost. The problem was already observed for Qt 4.6 (QTBUG-18196) but only partially fixed. Task-number: QTBUG-41124 Task-number: QTBUG-54610 Change-Id: Id13a9930d0163812e12a0287016bab9c3aa02068 Reviewed-by: Thorbjørn Lund Martsum --- src/widgets/itemviews/qtreeview.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index bbbadecff8..20e99d2aee 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -237,9 +237,6 @@ void QTreeView::setModel(QAbstractItemModel *model) // QAbstractItemView connects to a private slot disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(_q_rowsRemoved(QModelIndex,int,int))); - // do header layout after the tree - disconnect(d->model, SIGNAL(layoutChanged()), - d->header, SLOT(_q_layoutChanged())); // QTreeView has a public slot for this connect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(rowsRemoved(QModelIndex,int,int))); -- cgit v1.2.3 From 3841a7dd49667ceabdcbc416fa1e149bed7ed86e Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 12 Dec 2017 15:53:44 +0100 Subject: Prevent infinite relayout when adding scrollbars When one scrollbar is added, this may cause the other to be needed as well. This change does a second calculation immediately instead of relying on a signal through a QueuedConnection. Task-number: QTBUG-62818 Task-number: QTBUG-56280 Change-Id: Iee9a083e3a6cd3765e6bb9206687a8a6e7f99cff Reviewed-by: Paul Olav Tvete Reviewed-by: Andy Nichols --- src/widgets/widgets/qabstractscrollarea.cpp | 25 +++++++++++++++++++------ src/widgets/widgets/qabstractscrollarea_p.h | 1 + 2 files changed, 20 insertions(+), 6 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp index 249ebd35d3..c6d66bafd4 100644 --- a/src/widgets/widgets/qabstractscrollarea.cpp +++ b/src/widgets/widgets/qabstractscrollarea.cpp @@ -333,17 +333,28 @@ void QAbstractScrollAreaPrivate::setSingleFingerPanEnabled(bool on) #endif void QAbstractScrollAreaPrivate::layoutChildren() +{ + bool needH = false; + bool needV = false; + layoutChildren_helper(&needH, &needV); + // Call a second time if one scrollbar was needed and not the other to + // check if it needs to readjust accordingly + if (needH != needV) + layoutChildren_helper(&needH, &needV); +} + +void QAbstractScrollAreaPrivate::layoutChildren_helper(bool *needHorizontalScrollbar, bool *needVerticalScrollbar) { Q_Q(QAbstractScrollArea); bool htransient = hbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, hbar); - bool needh = (hbarpolicy != Qt::ScrollBarAlwaysOff) && ((hbarpolicy == Qt::ScrollBarAlwaysOn && !htransient) - || ((hbarpolicy == Qt::ScrollBarAsNeeded || htransient) - && hbar->minimum() < hbar->maximum() && !hbar->sizeHint().isEmpty())); + bool needh = *needHorizontalScrollbar || ((hbarpolicy != Qt::ScrollBarAlwaysOff) && ((hbarpolicy == Qt::ScrollBarAlwaysOn && !htransient) + || ((hbarpolicy == Qt::ScrollBarAsNeeded || htransient) + && hbar->minimum() < hbar->maximum() && !hbar->sizeHint().isEmpty()))); bool vtransient = vbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, vbar); - bool needv = (vbarpolicy != Qt::ScrollBarAlwaysOff) && ((vbarpolicy == Qt::ScrollBarAlwaysOn && !vtransient) - || ((vbarpolicy == Qt::ScrollBarAsNeeded || vtransient) - && vbar->minimum() < vbar->maximum() && !vbar->sizeHint().isEmpty())); + bool needv = *needVerticalScrollbar || ((vbarpolicy != Qt::ScrollBarAlwaysOff) && ((vbarpolicy == Qt::ScrollBarAlwaysOn && !vtransient) + || ((vbarpolicy == Qt::ScrollBarAsNeeded || vtransient) + && vbar->minimum() < vbar->maximum() && !vbar->sizeHint().isEmpty()))); QStyleOption opt(0); opt.init(q); @@ -522,6 +533,8 @@ void QAbstractScrollAreaPrivate::layoutChildren() viewportRect.adjust(left, top, -right, -bottom); viewport->setGeometry(QStyle::visualRect(opt.direction, opt.rect, viewportRect)); // resize the viewport last + *needHorizontalScrollbar = needh; + *needVerticalScrollbar = needv; } /*! diff --git a/src/widgets/widgets/qabstractscrollarea_p.h b/src/widgets/widgets/qabstractscrollarea_p.h index c52e7f9fd4..49f97bcb61 100644 --- a/src/widgets/widgets/qabstractscrollarea_p.h +++ b/src/widgets/widgets/qabstractscrollarea_p.h @@ -95,6 +95,7 @@ public: void init(); void layoutChildren(); + void layoutChildren_helper(bool *needHorizontalScrollbar, bool *needVerticalScrollbar); // ### Fix for 4.4, talk to Bjoern E or Girish. virtual void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) {} bool canStartScrollingAt( const QPoint &startPos ); -- cgit v1.2.3 From 0857db89bf2d36a1501c708521daacdbc83d5c5b Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 6 Dec 2017 17:45:53 +0100 Subject: Widgets: check if parent exists before calling parent->locale() If a top level, parentless widget has Qt::WA_WindowPropagation set, Qt will crash when trying to resolve the widgets locale. The reason is that we try to access the QLocale of the non-existing parent. This patch will add a check if a parent exists before trying to access it. Task-number: QTBUG-61213 Change-Id: I09a6351a12dc1fffab3069b70e3d7b3932317c85 Reviewed-by: Edward Welbourne --- src/widgets/kernel/qwidget.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index b57a0d4779..b38565493e 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -6007,9 +6007,9 @@ void QWidgetPrivate::resolveLocale() Q_Q(const QWidget); if (!q->testAttribute(Qt::WA_SetLocale)) { - setLocale_helper(q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation) - ? QLocale() - : q->parentWidget()->locale()); + QWidget *parent = q->parentWidget(); + setLocale_helper(!parent || (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)) + ? QLocale() : parent->locale()); } } -- cgit v1.2.3 From b0938cb6c1fa29ec2d2a4fb9273e515cd0d6c08e Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sun, 17 Dec 2017 11:42:41 +0100 Subject: QGestureManager: fix UB (invalid pointer comparison) Comparing pointers with op< that do not point into the same array is UB. Fix, in the usual way, by using std::less. Change-Id: Id2c957557719887b2016632d683dbab8af07b34c Reviewed-by: Thiago Macieira --- src/widgets/kernel/qgesturemanager_p.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qgesturemanager_p.h b/src/widgets/kernel/qgesturemanager_p.h index e57652afba..3df80bab55 100644 --- a/src/widgets/kernel/qgesturemanager_p.h +++ b/src/widgets/kernel/qgesturemanager_p.h @@ -59,6 +59,8 @@ #ifndef QT_NO_GESTURES +#include + QT_BEGIN_NAMESPACE class QBasicTimer; @@ -112,7 +114,7 @@ private: ObjectGesture(QObject *o, const Qt::GestureType &g) : object(o), gesture(g) { } inline bool operator<(const ObjectGesture &rhs) const { - if (object < rhs.object) + if (std::less{}(object, rhs.object)) return true; if (object == rhs.object) return gesture < rhs.gesture; -- cgit v1.2.3