diff options
Diffstat (limited to 'src/widgets')
-rw-r--r-- | src/widgets/kernel/qapplication.cpp | 68 | ||||
-rw-r--r-- | src/widgets/kernel/qapplication_p.h | 1 |
2 files changed, 52 insertions, 17 deletions
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index a0a363ba2b..2d23bb61a2 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -424,6 +424,7 @@ QWidget *QApplicationPrivate::hidden_focus_widget = 0; // will get keyboard inpu QWidget *QApplicationPrivate::active_window = 0; // toplevel with keyboard focus #ifndef QT_NO_WHEELEVENT int QApplicationPrivate::wheel_scroll_lines; // number of lines to scroll +QWidget *QApplicationPrivate::wheel_widget = Q_NULLPTR; #endif bool qt_in_tab_key_event = false; int qt_antialiasing_threshold = -1; @@ -3307,7 +3308,6 @@ bool QApplication::notify(QObject *receiver, QEvent *e) case QEvent::Wheel: { QWidget* w = static_cast<QWidget *>(receiver); - QWheelEvent* wheel = static_cast<QWheelEvent*>(e); // QTBUG-40656, QTBUG-42731: ignore wheel events when a popup (QComboBox) is open. if (const QWidget *popup = QApplication::activePopupWidget()) { @@ -3315,27 +3315,61 @@ bool QApplication::notify(QObject *receiver, QEvent *e) return true; } - QPoint relpos = wheel->pos(); - bool eventAccepted = wheel->isAccepted(); + QWheelEvent* wheel = static_cast<QWheelEvent*>(e); + const bool spontaneous = wheel->spontaneous(); + const Qt::ScrollPhase phase = wheel->phase(); - if (e->spontaneous() && wheel->phase() == Qt::ScrollUpdate) - QApplicationPrivate::giveFocusAccordingToFocusPolicy(w, e, relpos); + if (phase == Qt::NoScrollPhase || phase == Qt::ScrollBegin + || (phase == Qt::ScrollUpdate && !QApplicationPrivate::wheel_widget)) { + + if (spontaneous && phase == Qt::ScrollBegin) + QApplicationPrivate::wheel_widget = Q_NULLPTR; + + const QPoint &relpos = wheel->pos(); + + if (spontaneous && (phase == Qt::NoScrollPhase || phase == Qt::ScrollUpdate)) + QApplicationPrivate::giveFocusAccordingToFocusPolicy(w, e, relpos); - while (w) { QWheelEvent we(relpos, wheel->globalPos(), wheel->pixelDelta(), wheel->angleDelta(), wheel->delta(), wheel->orientation(), wheel->buttons(), - wheel->modifiers(), wheel->phase(), wheel->source()); - we.spont = wheel->spontaneous(); - res = d->notify_helper(w, w == receiver ? wheel : &we); - eventAccepted = ((w == receiver) ? wheel : &we)->isAccepted(); - e->spont = false; - if ((res && eventAccepted) - || w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation)) - break; + wheel->modifiers(), phase, wheel->source()); + bool eventAccepted; + while (w) { + we.spont = spontaneous && w == receiver; + we.ignore(); + res = d->notify_helper(w, &we); + eventAccepted = we.isAccepted(); + if (res && eventAccepted) { + if (spontaneous && phase != Qt::NoScrollPhase) + QApplicationPrivate::wheel_widget = w; + break; + } + if (w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation)) + break; - relpos += w->pos(); - w = w->parentWidget(); + we.p += w->pos(); + w = w->parentWidget(); + } + wheel->setAccepted(eventAccepted); + } else if (QApplicationPrivate::wheel_widget) { + if (!spontaneous) { + // wheel_widget may forward the wheel event to a delegate widget, + // either directly or indirectly (e.g. QAbstractScrollArea will + // forward to its QScrollBars through viewportEvent()). In that + // case, the event will not be spontaneous but synthesized, so + // we can send it straigth to the receiver. + d->notify_helper(w, wheel); + } else { + const QPoint &relpos = QApplicationPrivate::wheel_widget->mapFromGlobal(wheel->globalPos()); + QWheelEvent we(relpos, wheel->globalPos(), wheel->pixelDelta(), wheel->angleDelta(), wheel->delta(), wheel->orientation(), wheel->buttons(), + wheel->modifiers(), wheel->phase(), wheel->source()); + we.spont = true; + we.ignore(); + d->notify_helper(QApplicationPrivate::wheel_widget, &we); + wheel->setAccepted(we.isAccepted()); + if (phase == Qt::ScrollEnd) + QApplicationPrivate::wheel_widget = Q_NULLPTR; + } } - wheel->setAccepted(eventAccepted); } break; #endif diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h index b884b32016..0482f83a8a 100644 --- a/src/widgets/kernel/qapplication_p.h +++ b/src/widgets/kernel/qapplication_p.h @@ -208,6 +208,7 @@ public: static QWidget *active_window; #ifndef QT_NO_WHEELEVENT static int wheel_scroll_lines; + static QWidget *wheel_widget; #endif static int enabledAnimations; // Combination of QPlatformTheme::UiEffect |