diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 25c2bdebfbd..77e12564849 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -2784,7 +2784,7 @@ void QWindowPrivate::maybeSynthesizeContextMenuEvent(QMouseEvent *event) && event->type() == QGuiApplicationPrivate::contextMenuEventType()) { QContextMenuEvent e(QContextMenuEvent::Mouse, event->scenePosition().toPoint(), event->globalPosition().toPoint(), event->modifiers()); - qCDebug(lcPopup) << "synthesized QContextMenuEvent after un-accepted" << event->type() << ":" << &e; + qCDebug(lcPopup) << "synthesized QContextMenuEvent after ignored" << event->type() << ":" << &e; QGuiApplication::sendEvent(q_func(), &e); } #endif diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp index ecc633c269d..9dae651284f 100644 --- a/src/widgets/graphicsview/qgraphicsview.cpp +++ b/src/widgets/graphicsview/qgraphicsview.cpp @@ -3354,8 +3354,9 @@ void QGraphicsView::mouseReleaseEvent(QMouseEvent *event) else QCoreApplication::sendEvent(d->scene, &mouseEvent); - // Update the last mouse event selected state. + // Update the last and current mouse events' accepted state. d->lastMouseEvent.setAccepted(mouseEvent.isAccepted()); + event->setAccepted(mouseEvent.isAccepted()); #ifndef QT_NO_CURSOR if (mouseEvent.isAccepted() && mouseEvent.buttons() == 0 && viewport()->testAttribute(Qt::WA_SetCursor)) { diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 9b2d6ca31d4..d337679fb2d 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -505,6 +505,7 @@ void QWidgetWindow::handleNonClientAreaMouseEvent(QMouseEvent *e) void QWidgetWindow::handleMouseEvent(QMouseEvent *event) { + Q_D(QWidgetWindow); if (auto *activePopupWidget = QApplication::activePopupWidget()) { QPointF mapped = event->position(); if (activePopupWidget != m_widget) @@ -647,7 +648,7 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) if (!receiver) return; - if (d_func()->isPopup() && receiver->window()->windowHandle() != this) { + if (d->isPopup() && receiver->window()->windowHandle() != this) { receiver = widget; mapped = event->position().toPoint(); } @@ -664,16 +665,8 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) &qt_button_down, qt_last_mouse_receiver); event->setAccepted(translated.isAccepted()); } -#ifndef QT_NO_CONTEXTMENU - if (event->type() == QGuiApplicationPrivate::contextMenuEventType() - && event->button() == Qt::RightButton - && m_widget->rect().contains(event->position().toPoint())) { - QContextMenuEvent e(QContextMenuEvent::Mouse, mapped.toPoint(), event->globalPosition().toPoint(), event->modifiers()); - QGuiApplication::forwardEvent(receiver, &e, event); - if (e.isAccepted()) - event->accept(); - } -#endif + + d->maybeSynthesizeContextMenuEvent(event); } void QWidgetWindow::handleTouchEvent(QTouchEvent *event) @@ -1165,28 +1158,36 @@ void QWidgetWindow::handleGestureEvent(QNativeGestureEvent *e) #ifndef QT_NO_CONTEXTMENU void QWidgetWindow::handleContextMenuEvent(QContextMenuEvent *e) { - // We are only interested in keyboard originating context menu events here, - // mouse originated context menu events for widgets are generated in mouse handling methods. - if (e->reason() != QContextMenuEvent::Keyboard) - return; - - QWidget *fw = QWidget::keyboardGrabber(); - if (!fw) { - if (QApplication::activePopupWidget()) { - fw = (QApplication::activePopupWidget()->focusWidget() - ? QApplication::activePopupWidget()->focusWidget() - : QApplication::activePopupWidget()); - } else if (QApplication::focusWidget()) { - fw = QApplication::focusWidget(); - } else { - fw = m_widget; + QWidget *receiver = qt_last_mouse_receiver.get(); + QPoint pos = e->pos(); + QPoint globalPos = e->globalPos(); + + // Keyboard-originating context menu events are delivered to the focus widget, + // independently of event position. + if (e->reason() == QContextMenuEvent::Keyboard) { + receiver = QWidget::keyboardGrabber(); + if (!receiver) { + if (QApplication::activePopupWidget()) { + receiver = (QApplication::activePopupWidget()->focusWidget() + ? QApplication::activePopupWidget()->focusWidget() + : QApplication::activePopupWidget()); + } else if (QApplication::focusWidget()) { + receiver = QApplication::focusWidget(); + } else { + receiver = m_widget; + } } + if (Q_LIKELY(receiver)) { + pos = receiver->inputMethodQuery(Qt::ImCursorRectangle).toRect().center(); + globalPos = receiver->mapToGlobal(pos); + } + } else if (Q_LIKELY(receiver)) { + pos = receiver->mapFromGlobal(e->globalPos()); } - if (fw && fw->isEnabled()) { - QPoint pos = fw->inputMethodQuery(Qt::ImCursorRectangle).toRect().center(); - QContextMenuEvent widgetEvent(QContextMenuEvent::Keyboard, pos, fw->mapToGlobal(pos), - e->modifiers()); - QGuiApplication::forwardEvent(fw, &widgetEvent, e); + + if (receiver && receiver->isEnabled()) { + QContextMenuEvent widgetEvent(e->reason(), pos, globalPos, e->modifiers()); + QGuiApplication::forwardEvent(receiver, &widgetEvent, e); } } #endif // QT_NO_CONTEXTMENU