Add QPlatformTheme::ScrollSingleStepDistance theme hint

The hard coded value of 20 used in various QAbstractScrollArea
subclasses does not represent the default behavior on all of
our platforms. On macOS e.g. the native NSScrollView has a
default line scroll value of 10 pixels.

The default value isn't changed for macOS in this patch, as it
has to be done in coordination with other changes to make the
behavior change atomic.

Task-number: QTBUG-130667
Change-Id: I532dbd3e2e946a00f426475adfa851d35a656c1b
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
Tor Arne Vestbø 2024-10-30 16:07:13 +01:00
parent 498ae026e9
commit 369d975c90
9 changed files with 34 additions and 15 deletions

View File

@ -158,6 +158,10 @@ QT_BEGIN_NAMESPACE
\value MouseCursorSize (QSize) Size of the mouse cursor.
This enum value has been added in Qt 6.5.
\value ScrollSingleStepDistance (int) The distance in logical pixels that scrollable
controls should scroll in response to a single step (e.g. scroll-bar arrow click,
mouse wheel line).
\sa themeHint(), QStyle::pixelMetric()
*/
@ -710,6 +714,8 @@ QVariant QPlatformTheme::defaultThemeHint(ThemeHint hint)
return false;
case MenuSelectionWraps:
return true;
case ScrollSingleStepDistance:
return 20;
}
return QVariant();

View File

@ -100,6 +100,7 @@ public:
ShowIconsInMenus,
PreferFileIconFromTheme,
MenuSelectionWraps,
ScrollSingleStepDistance,
};
Q_ENUM(ThemeHint)

View File

@ -389,6 +389,8 @@ void QGraphicsViewPrivate::recalculateContentSize()
const qreal oldLeftIndent = leftIndent;
const qreal oldTopIndent = topIndent;
const auto singleStep = defaultSingleStep();
// If the whole scene fits horizontally, we center the scene horizontally,
// and ignore the horizontal scroll bars.
const int left = q_round_bound(viewRect.left());
@ -413,7 +415,7 @@ void QGraphicsViewPrivate::recalculateContentSize()
hbar->setRange(left, right);
hbar->setPageStep(width);
hbar->setSingleStep(width / 20);
hbar->setSingleStep(width / singleStep);
if (oldLeftIndent != 0)
hbar->setValue(-oldLeftIndent);
@ -443,7 +445,7 @@ void QGraphicsViewPrivate::recalculateContentSize()
vbar->setRange(top, bottom);
vbar->setPageStep(height);
vbar->setSingleStep(height / 20);
vbar->setSingleStep(height / singleStep);
if (oldTopIndent != 0)
vbar->setValue(-oldTopIndent);

View File

@ -24,6 +24,9 @@
#include "qscrollbar_p.h"
#include <qwidget.h>
#include <private/qguiapplication_p.h>
#include <qpa/qplatformtheme.h>
#include <private/qapplication_p.h>
#ifdef Q_OS_WIN
@ -1500,6 +1503,12 @@ void QAbstractScrollArea::setupViewport(QWidget *viewport)
Q_UNUSED(viewport);
}
int QAbstractScrollAreaPrivate::defaultSingleStep() const
{
auto *platformTheme = QGuiApplicationPrivate::platformTheme();
return platformTheme->themeHint(QPlatformTheme::ScrollSingleStepDistance).value<int>();
}
QT_END_NAMESPACE
#include "moc_qabstractscrollarea.cpp"

View File

@ -73,6 +73,8 @@ public:
inline bool viewportEvent(QEvent *event)
{ return q_func()->viewportEvent(event); }
QScopedPointer<QObject> viewportFilter;
int defaultSingleStep() const;
};
class QAbstractScrollAreaFilter : public QObject

View File

@ -1170,6 +1170,8 @@ void QMdiAreaPrivate::updateScrollBars()
const int startX = q->isLeftToRight() ? childrenRect.left() : viewportRect.right()
- childrenRect.right();
const auto singleStep = defaultSingleStep();
// Horizontal scroll bar.
if (isSubWindowsTiled && hbar->value() != 0)
hbar->setValue(0);
@ -1177,7 +1179,7 @@ void QMdiAreaPrivate::updateScrollBars()
hbar->setRange(qMin(0, xOffset),
qMax(0, xOffset + childrenRect.width() - viewportRect.width()));
hbar->setPageStep(childrenRect.width());
hbar->setSingleStep(childrenRect.width() / 20);
hbar->setSingleStep(childrenRect.width() / singleStep);
// Vertical scroll bar.
if (isSubWindowsTiled && vbar->value() != 0)
@ -1186,7 +1188,7 @@ void QMdiAreaPrivate::updateScrollBars()
vbar->setRange(qMin(0, yOffset),
qMax(0, yOffset + childrenRect.height() - viewportRect.height()));
vbar->setPageStep(childrenRect.height());
vbar->setSingleStep(childrenRect.height() / 20);
vbar->setSingleStep(childrenRect.height() / singleStep);
}
/*!

View File

@ -781,7 +781,7 @@ void QPlainTextEditPrivate::init(const QString &txt)
if (!txt.isEmpty())
control->setPlainText(txt);
hbar->setSingleStep(20);
hbar->setSingleStep(defaultSingleStep());
vbar->setSingleStep(1);
viewport->setBackgroundRole(QPalette::Base);

View File

@ -101,13 +101,8 @@ QT_BEGIN_NAMESPACE
\sa setWidget()
*/
QScrollArea::QScrollArea(QWidget *parent)
: QAbstractScrollArea(*new QScrollAreaPrivate,parent)
: QScrollArea(*new QScrollAreaPrivate, parent)
{
Q_D(QScrollArea);
d->viewport->setBackgroundRole(QPalette::NoRole);
d->vbar->setSingleStep(20);
d->hbar->setSingleStep(20);
d->layoutChildren();
}
/*!
@ -118,8 +113,9 @@ QScrollArea::QScrollArea(QScrollAreaPrivate &dd, QWidget *parent)
{
Q_D(QScrollArea);
d->viewport->setBackgroundRole(QPalette::NoRole);
d->vbar->setSingleStep(20);
d->hbar->setSingleStep(20);
const auto singleStep = d->defaultSingleStep();
d->vbar->setSingleStep(singleStep);
d->hbar->setSingleStep(singleStep);
d->layoutChildren();
}

View File

@ -170,8 +170,9 @@ void QTextEditPrivate::init(const QString &html)
if (!html.isEmpty())
control->setHtml(html);
hbar->setSingleStep(20);
vbar->setSingleStep(20);
const auto singleStep = defaultSingleStep();
hbar->setSingleStep(singleStep);
vbar->setSingleStep(singleStep);
viewport->setBackgroundRole(QPalette::Base);
q->setMouseTracking(true);