summaryrefslogtreecommitdiffstats
path: root/src/widgets
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-12-29 15:56:33 +0100
committerLars Knoll <lars.knoll@qt.io>2017-12-30 12:09:53 +0100
commitdb92f2f3aac60218756a1aa8811cf192acc0b0e6 (patch)
treef28a47aebb2f08e221fe7bffafce62a0a96cf7fd /src/widgets
parentdd61a1d98ea9fbffeaf0e2adcd0ddd58105f6a75 (diff)
parent44da5b863597e761df3545dc7ff02a9b53bbb13d (diff)
Merge remote-tracking branch 'origin/5.9' into 5.10
Conflicts: .qmake.conf mkspecs/win32-g++/qmake.conf src/corelib/global/qglobal_p.h src/corelib/global/qoperatingsystemversion_p.h src/corelib/io/qfilesystemengine_win.cpp src/network/bearer/qbearerengine.cpp src/platformsupport/input/libinput/qlibinputpointer.cpp src/sql/doc/snippets/code/doc_src_sql-driver.cpp src/widgets/kernel/qwidget_p.h src/widgets/kernel/qwidgetwindow.cpp src/widgets/styles/qfusionstyle.cpp tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp Change-Id: I80e2722f481b12fff5d967c28f89208c0e9a1dd8
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/dialogs/qfileinfogatherer.cpp35
-rw-r--r--src/widgets/dialogs/qfileinfogatherer_p.h3
-rw-r--r--src/widgets/dialogs/qfilesystemmodel.cpp7
-rw-r--r--src/widgets/itemviews/qheaderview.cpp23
-rw-r--r--src/widgets/itemviews/qtreeview.cpp3
-rw-r--r--src/widgets/kernel/qgesturemanager_p.h4
-rw-r--r--src/widgets/kernel/qwidget.cpp281
-rw-r--r--src/widgets/kernel/qwidget_p.h10
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp7
-rw-r--r--src/widgets/styles/qfusionstyle.cpp39
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp2
-rw-r--r--src/widgets/widgets/qabstractscrollarea.cpp25
-rw-r--r--src/widgets/widgets/qabstractscrollarea_p.h1
-rw-r--r--src/widgets/widgets/qwidgetresizehandler.cpp2
14 files changed, 267 insertions, 175 deletions
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<QPair<QString, QFileInfo> > 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
diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp
index f88ac71cf3..2b79831a74 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);
@@ -744,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);
diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp
index c7966f624f..c3c9bdf51c 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);
@@ -2788,9 +2790,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;
@@ -3169,6 +3171,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<QFont>()) {
+ const QFont sectionFont = qvariant_cast<QFont>(variant);
+ painter.setFont(sectionFont);
+ } else {
+ painter.setFont(q->font());
+ }
+
painter.setOpacity(0.75);
q->paintSection(&painter, rect, section);
painter.end();
diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp
index d6d0fd4322..e593d82576 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)));
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 <functional>
+
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<QObject *>{}(object, rhs.object))
return true;
if (object == rhs.object)
return gesture < rhs.gesture;
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 2ee9d307c9..680c179bd9 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -126,15 +126,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
@@ -145,11 +136,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
@@ -1200,6 +1186,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
@@ -1352,8 +1339,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();
@@ -1425,8 +1411,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
@@ -1444,12 +1428,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(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))
@@ -2312,7 +2303,7 @@ bool QWidgetPrivate::paintOnScreen() const
return true;
}
- return !qt_enable_backingstore;
+ return false;
#endif
}
@@ -5490,11 +5481,11 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
setSystemClip(pdev->paintEngine(), pdev->devicePixelRatioF(), rgn.translated(offset));
QPainter p(pdev);
p.translate(offset);
- context.painter = &p;
+ context.painter = context.sharedPainter = &p;
graphicsEffect->draw(&p);
setSystemClip(pdev->paintEngine(), 1, QRegion());
} else {
- context.painter = sharedPainter;
+ context.painter = context.sharedPainter = sharedPainter;
if (sharedPainter->worldTransform() != sourced->lastEffectTransform) {
sourced->invalidateCache();
sourced->lastEffectTransform = sharedPainter->worldTransform();
@@ -5980,9 +5971,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());
}
}
@@ -7585,21 +7576,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();
}
/*!
@@ -7624,6 +7601,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.
@@ -7632,15 +7630,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()));
}
/*!
@@ -7653,10 +7658,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.
@@ -7664,14 +7670,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<QWidget *>(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)
@@ -10931,25 +11010,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;
-
- 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);
- }
+ d->repaint(rect);
}
/*!
@@ -10960,24 +11021,22 @@ 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 <typename T>
+void QWidgetPrivate::repaint(T r)
+{
+ Q_Q(QWidget);
- if (!isVisible() || !updatesEnabled() || rgn.isEmpty())
+ if (!q->isVisible() || !q->updatesEnabled() || r.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 = q->window()->d_func()->maybeTopData();
+ if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) {
+ tlwExtra->inRepaint = true;
+ tlwExtra->backingStoreTracker->markDirty(r, q, QWidgetBackingStore::UpdateNow);
+ tlwExtra->inRepaint = false;
}
}
@@ -11018,26 +11077,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;
- }
-
- 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);
- }
+ Q_D(QWidget);
+ d->update(rect);
}
/*!
@@ -11047,29 +11088,33 @@ void QWidget::update(const QRect &rect)
*/
void QWidget::update(const QRegion &rgn)
{
- if (!isVisible() || !updatesEnabled())
+ Q_D(QWidget);
+ d->update(rgn);
+}
+
+template <typename T>
+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;
}
- 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 = q->window()->d_func()->maybeTopData();
+ if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore)
+ tlwExtra->backingStoreTracker->markDirty(clipped, q);
}
-
/*!
\internal
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index 4a86f87c71..37690b9719 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -344,6 +344,13 @@ public:
void setSharedPainter(QPainter *painter);
QWidgetBackingStore *maybeBackingStore() const;
QWidgetWindow *windowHandle() const;
+
+ template <typename T>
+ void repaint(T t);
+
+ template <typename T>
+ void update(T t);
+
void init(QWidget *desktopWidget, Qt::WindowFlags f);
void create_sys(WId window, bool initializeWindow, bool destroyOldWindow);
void createRecursively();
@@ -516,6 +523,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 d8d6eab7b1..34b12a74b2 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -99,6 +99,13 @@ public:
#if QT_CONFIG(opengl)
QOpenGLContext *shareContext() const override;
#endif
+
+ void processSafeAreaMarginsChanged() override
+ {
+ Q_Q(QWidgetWindow);
+ if (QWidget *widget = q->widget())
+ QWidgetPrivate::get(widget)->updateContentsRect();
+ }
};
QRectF QWidgetWindowPrivate::closestAcceptableGeometry(const QRectF &rect) const
diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp
index e002b49d25..88c98f45f9 100644
--- a/src/widgets/styles/qfusionstyle.cpp
+++ b/src/widgets/styles/qfusionstyle.cpp
@@ -763,7 +763,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());
@@ -777,18 +777,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()));
}
}
@@ -1558,9 +1560,9 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
bool enabled = menuItem->state & State_Enabled;
bool ignoreCheckMark = false;
- int checkcol = qMax<int>(menuItem->maxIconWidth, QStyleHelper::dpiScaled(20));
- const int margin = QStyleHelper::dpiScaled(4);
-
+ 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<const QComboBox*>(widget) ||
@@ -1570,10 +1572,9 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
if (!ignoreCheckMark) {
// Check
- const int indicatorWidth = proxy()->pixelMetric(PM_IndicatorWidth, option, widget);
- const int indicatorHeight = proxy()->pixelMetric(PM_IndicatorHeight, option, widget);
- QRect checkRect(option->rect.left() + indicatorWidth / 2,
- option->rect.center().y() - indicatorHeight / 2 + 1, indicatorWidth, indicatorHeight);
+ 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) {
@@ -1585,7 +1586,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(margin, margin, -margin, -margin));
+ const int adjustment = checkRect.height() * 0.3;
+ painter->drawEllipse(checkRect.adjusted(adjustment, adjustment, -adjustment, -adjustment));
}
} else {
// Check box
@@ -1614,7 +1616,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
QPainter *p = painter;
QRect vCheckRect = visualRect(opt->direction, menuitem->rect,
- QRect(menuitem->rect.x() + margin, 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;
@@ -1665,11 +1667,10 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
discol = menuitem->palette.text().color();
p->setPen(discol);
}
- const int lm = QStyleHelper::dpiScaled(windowsItemFrame + windowsItemHMargin + 2) + checkcol;
- const int rm = QStyleHelper::dpiScaled(windowsRightBorder + 1) + tab;
- const int xpos = menuitem->rect.x() + lm;
+ int xm = checkColHOffset + checkcol + windowsItemHMargin;
+ int xpos = menuitem->rect.x() + xm;
- QRect textRect(xpos, y + windowsItemVMargin, w - lm - rm, h - 2 * windowsItemVMargin);
+ QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
QRect vTextRect = visualRect(opt->direction, menuitem->rect, textRect);
QStringRef s(&menuitem->text);
if (!s.isEmpty()) { // draw text
diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp
index a721357ddc..494b28c909 100644
--- a/src/widgets/styles/qstylesheetstyle.cpp
+++ b/src/widgets/styles/qstylesheetstyle.cpp
@@ -3657,7 +3657,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()) {
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
@@ -334,16 +334,27 @@ void QAbstractScrollAreaPrivate::setSingleFingerPanEnabled(bool on)
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 );
diff --git a/src/widgets/widgets/qwidgetresizehandler.cpp b/src/widgets/widgets/qwidgetresizehandler.cpp
index d4f14ad1d4..45010d1768 100644
--- a/src/widgets/widgets/qwidgetresizehandler.cpp
+++ b/src/widgets/widgets/qwidgetresizehandler.cpp
@@ -121,7 +121,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