diff options
-rw-r--r-- | src/gui/kernel/qapplication.cpp | 2 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_mac.mm | 20 | ||||
-rw-r--r-- | src/gui/kernel/qcocoaview_mac.mm | 20 | ||||
-rw-r--r-- | src/gui/widgets/qabstractslider.cpp | 39 | ||||
-rw-r--r-- | src/gui/widgets/qabstractslider_p.h | 1 | ||||
-rw-r--r-- | src/gui/widgets/qtextedit.cpp | 5 |
6 files changed, 50 insertions, 37 deletions
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index df5097b..1332545 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 c294e62..a95ae9d 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 f482d1c..b1c5fc5 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 a50c105..c3289b4 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 071b8df..9324d44 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 dc78fd5..3fe9bb4 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); |