summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard Moe Gustavsen <richard.gustavsen@nokia.com>2009-09-30 08:52:50 +0200
committerRichard Moe Gustavsen <richard.gustavsen@nokia.com>2009-10-01 14:52:40 +0200
commit45f095b8970dc3c1b6f6e97fa2323654ba848288 (patch)
tree73e1c8d019ebbc3cb2b6bd4e20f209a9e73e7287 /src
parentdf7669b7f41f4284e297c0e8d56b3d71019625d0 (diff)
Fix: Abstract slider does not understand wheel events properly
A wheel event contain delta values that describe the rotation angle the wheel was rotated (in 1/8 of a degree). For some mouse devices (thinking of mac mighty mouse/trackpad) the resolution is better than the standard 15 degrees. The Qt docs describe how to deal with this. But abstract scrollbar does did follow this recipe, but it does now with this patch. Reb-By: prasanth
Diffstat (limited to 'src')
-rw-r--r--src/gui/kernel/qapplication.cpp2
-rw-r--r--src/gui/kernel/qapplication_mac.mm20
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm20
-rw-r--r--src/gui/widgets/qabstractslider.cpp39
-rw-r--r--src/gui/widgets/qabstractslider_p.h1
-rw-r--r--src/gui/widgets/qtextedit.cpp5
6 files changed, 50 insertions, 37 deletions
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index df5097bc67..13325450b2 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -925,7 +925,7 @@ void QApplicationPrivate::initialize()
graphics_system = QGraphicsSystemFactory::create(graphics_system_name);
#endif
#ifndef QT_NO_WHEELEVENT
-#ifdef QT_MAC_USE_COCOA
+#ifdef Q_OS_MAC
QApplicationPrivate::wheel_scroll_lines = 1;
#else
QApplicationPrivate::wheel_scroll_lines = 3;
diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm
index c294e6221c..a95ae9db1b 100644
--- a/src/gui/kernel/qapplication_mac.mm
+++ b/src/gui/kernel/qapplication_mac.mm
@@ -1686,13 +1686,15 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event
// (actually two events; one for horizontal and one for vertical).
// As a results of this, and to make sure we dont't receive duplicate events,
// we try to detect when this happend by checking the 'compatibilityEvent'.
+ const int scrollFactor = 4 * 8;
SInt32 mdelt = 0;
GetEventParameter(event, kEventParamMouseWheelSmoothHorizontalDelta, typeSInt32, 0,
sizeof(mdelt), 0, &mdelt);
- wheel_deltaX = mdelt;
+ wheel_deltaX = mdelt * scrollFactor;
+ mdelt = 0;
GetEventParameter(event, kEventParamMouseWheelSmoothVerticalDelta, typeSInt32, 0,
sizeof(mdelt), 0, &mdelt);
- wheel_deltaY = mdelt;
+ wheel_deltaY = mdelt * scrollFactor;
GetEventParameter(event, kEventParamEventRef, typeEventRef, 0,
sizeof(compatibilityEvent), 0, &compatibilityEvent);
} else if (ekind == kEventMouseWheelMoved) {
@@ -1704,10 +1706,14 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event
EventMouseWheelAxis axis;
GetEventParameter(event, kEventParamMouseWheelAxis, typeMouseWheelAxis, 0,
sizeof(axis), 0, &axis);
+
+ // The 'new' event has acceleration applied by the OS, while the old (on
+ // Carbon only), has not. So we introduce acceleration here to be consistent:
+ int scrollFactor = 120 * qMin(5, qAbs(mdelt));
if (axis == kEventMouseWheelAxisX)
- wheel_deltaX = mdelt * 120;
+ wheel_deltaX = mdelt * scrollFactor;
else
- wheel_deltaY = mdelt * 120;
+ wheel_deltaY = mdelt * scrollFactor;
}
}
@@ -2660,7 +2666,11 @@ int QApplication::keyboardInputInterval()
void QApplication::setWheelScrollLines(int n)
{
- QApplicationPrivate::wheel_scroll_lines = n;
+ Q_UNUSED(n);
+ // On Mac, acceleration is handled by the OS. Multiplying wheel scroll
+ // deltas with n will not be as cross platform as one might think! So
+ // we choose to go native in this case (and let wheel_scroll_lines == 1).
+ // QApplicationPrivate::wheel_scroll_lines = n;
}
int QApplication::wheelScrollLines()
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index f482d1cf99..b1c5fc5485 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -789,18 +789,22 @@ extern "C" {
const EventRef carbonEvent = (EventRef)[theEvent eventRef];
const UInt32 carbonEventKind = carbonEvent ? ::GetEventKind(carbonEvent) : 0;
if (carbonEventKind == kEventMouseScroll) {
- // The mouse device containts pixel scroll
- // wheel support (Mighty Mouse, Trackpad)
- deltaX = (int)[theEvent deviceDeltaX] * 120;
- deltaY = (int)[theEvent deviceDeltaY] * 120;
- deltaZ = (int)[theEvent deviceDeltaZ] * 120;
+ // The mouse device containts pixel scroll wheel support (Mighty Mouse, Trackpad).
+ // Since deviceDelta is delivered as pixels rather than degrees, we need to
+ // convert from pixels to degrees in a sensible manner.
+ // It looks like four degrees per pixel behaves most native.
+ // Qt expects the unit for delta to be 1/8 of a degree:
+ const int scrollFactor = 4 * 8;
+ deltaX = (int)[theEvent deviceDeltaX] * scrollFactor;
+ deltaY = (int)[theEvent deviceDeltaY] * scrollFactor;
+ deltaZ = (int)[theEvent deviceDeltaZ] * scrollFactor;
} else { // carbonEventKind == kEventMouseWheelMoved
// Mouse wheel deltas seem to tick in at increments of 0.1.
// Qt widgets expect the delta to be a multiple of 120.
const int scrollFactor = 10 * 120;
- deltaX = [theEvent deltaX] * scrollFactor * qMax(0.6, 1.1 - qAbs([theEvent deltaX]));
- deltaY = [theEvent deltaY] * scrollFactor * qMax(0.6, 1.1 - qAbs([theEvent deltaY]));
- deltaZ = [theEvent deltaZ] * scrollFactor * qMax(0.6, 1.1 - qAbs([theEvent deltaZ]));
+ deltaX = [theEvent deltaX] * scrollFactor;
+ deltaY = [theEvent deltaY] * scrollFactor;
+ deltaZ = [theEvent deltaZ] * scrollFactor;
}
if (deltaX != 0) {
diff --git a/src/gui/widgets/qabstractslider.cpp b/src/gui/widgets/qabstractslider.cpp
index a50c105007..c3289b46f3 100644
--- a/src/gui/widgets/qabstractslider.cpp
+++ b/src/gui/widgets/qabstractslider.cpp
@@ -215,7 +215,8 @@ QT_BEGIN_NAMESPACE
QAbstractSliderPrivate::QAbstractSliderPrivate()
: minimum(0), maximum(99), singleStep(1), pageStep(10),
- value(0), position(0), pressValue(-1), tracking(true), blocktracking(false), pressed(false),
+ value(0), position(0), pressValue(-1), offset_accumulated(0), tracking(true),
+ blocktracking(false), pressed(false),
invertedAppearance(false), invertedControls(false),
orientation(Qt::Horizontal), repeatAction(QAbstractSlider::SliderNoAction)
{
@@ -691,38 +692,30 @@ void QAbstractSlider::wheelEvent(QWheelEvent * e)
e->ignore();
if (e->orientation() != d->orientation && !rect().contains(e->pos()))
return;
- static qreal offset = 0;
- static QAbstractSlider *offset_owner = 0;
- if (offset_owner != this){
- offset_owner = this;
- offset = 0;
- }
- // On Mac/Cocoa, always scroll one step. The mouse wheel acceleration
- // is higher than on other systems, so this works well in practice.
-#ifdef QT_MAC_USE_COCOA
- int step = 1;
-#else
int step = qMin(QApplication::wheelScrollLines() * d->singleStep, d->pageStep);
-#endif
if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::ShiftModifier))
step = d->pageStep;
- int currentOffset = qRound(qreal(e->delta()) * step / 120);
- if (currentOffset == 0)
- currentOffset = (e->delta() < 0 ? -1 : 1);
- offset += currentOffset;
- if (d->invertedControls)
- offset = -offset;
+ qreal currentOffset = qreal(e->delta()) * step / 120;
+ d->offset_accumulated += d->invertedControls ? -currentOffset : currentOffset;
- int prevValue = d->value;
- d->position = d->overflowSafeAdd(int(offset)); // value will be updated by triggerAction()
+ if (int(d->offset_accumulated) == 0) {
+ // QAbstractSlider works on integer values. So if the accumulated
+ // offset is less than +/- 1, we need to wait until we get more
+ // wheel events (this means that the wheel resolution is higher than
+ // 15 degrees, e.g. when using mac mighty mouse/trackpad):
+ return;
+ }
+ int prevValue = d->value;
+ d->position = d->overflowSafeAdd(int(d->offset_accumulated)); // value will be updated by triggerAction()
triggerAction(SliderMove);
+
if (prevValue == d->value) {
- offset = 0;
+ d->offset_accumulated = 0;
} else {
- offset -= int(offset);
+ d->offset_accumulated -= int(d->offset_accumulated);
e->accept();
}
}
diff --git a/src/gui/widgets/qabstractslider_p.h b/src/gui/widgets/qabstractslider_p.h
index 071b8df3b6..9324d44e1d 100644
--- a/src/gui/widgets/qabstractslider_p.h
+++ b/src/gui/widgets/qabstractslider_p.h
@@ -69,6 +69,7 @@ public:
void setSteps(int single, int page);
int minimum, maximum, singleStep, pageStep, value, position, pressValue;
+ float offset_accumulated;
uint tracking : 1;
uint blocktracking :1;
uint pressed : 1;
diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp
index dc78fd5ecb..3fe9bb4acc 100644
--- a/src/gui/widgets/qtextedit.cpp
+++ b/src/gui/widgets/qtextedit.cpp
@@ -174,8 +174,13 @@ void QTextEditPrivate::init(const QString &html)
if (!html.isEmpty())
control->setHtml(html);
+#ifdef Q_OS_MAC
+ hbar->setSingleStep(1);
+ vbar->setSingleStep(1);
+#else
hbar->setSingleStep(20);
vbar->setSingleStep(20);
+#endif
viewport->setBackgroundRole(QPalette::Base);
q->setAcceptDrops(true);