QWindow: synthesize a QContextMenuEvent from relevant mouse events

QWindow receives keyboard originated context menu events, so it should
also receive events originating from a right-button mouse event.

Remove the incorrect statement about the special acceptance flag for
context menu events. There is no such thing, the event gets delievered
after the corresponding mouse press/release event.

Fixes: QTBUG-59988
Task-number: QTBUG-93486
Change-Id: I148310440604e74f600932cc1898fa152c483a61
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Volker Hilsheimer 2021-05-05 12:30:45 +02:00
parent 718d1f88d7
commit 3d71c4b740
2 changed files with 30 additions and 5 deletions

View File

@ -1934,11 +1934,6 @@ QIconDragEvent::~QIconDragEvent()
When this event occurs it is customary to show a QMenu with a
context menu, if this is relevant to the context.
Context menu events contain a special accept flag that indicates
whether the receiver accepted the event. If the event handler does
not accept the event then, if possible, whatever triggered the event will be
handled as a regular input event.
*/
#ifndef QT_NO_CONTEXTMENU

View File

@ -41,6 +41,9 @@
#include <qpa/qplatformwindow.h>
#include <qpa/qplatformintegration.h>
#ifndef QT_NO_CONTEXTMENU
#include <qpa/qplatformtheme.h>
#endif
#include "qsurfaceformat.h"
#ifndef QT_NO_OPENGL
#include <qpa/qplatformopenglcontext.h>
@ -2491,6 +2494,33 @@ bool QWindow::event(QEvent *ev)
default:
return QObject::event(ev);
}
#ifndef QT_NO_CONTEXTMENU
/*
QGuiApplicationPrivate::processContextMenuEvent blocks mouse-triggered
context menu events that the QPA plugin might generate. In practice that
never happens, as even on Windows WM_CONTEXTMENU is never generated by
the OS (we never call the default window procedure that would do that in
response to unhandled WM_RBUTTONUP).
So, we always have to syntheize QContextMenuEvent for mouse events anyway.
QWidgetWindow synthesizes QContextMenuEvent similar to this code, and
never calls QWindow::event, so we have to do it here as well.
This logic could be simplified by always synthesizing events in
QGuiApplicationPrivate, or perhaps even in each QPA plugin. See QTBUG-93486.
*/
static const QEvent::Type contextMenuTrigger =
QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::ContextMenuOnMouseRelease).toBool() ?
QEvent::MouseButtonRelease : QEvent::MouseButtonPress;
if (QMouseEvent *me = static_cast<QMouseEvent *>(ev);
ev->type() == contextMenuTrigger && me->button() == Qt::RightButton) {
QSinglePointEvent *pev = static_cast<QSinglePointEvent*>(ev);
QContextMenuEvent e(QContextMenuEvent::Mouse, me->position().toPoint(),
pev->globalPosition().toPoint(), pev->modifiers());
QGuiApplication::sendEvent(this, &e);
}
#endif
return true;
}