iOS: send context menu event rather than instantly showing edit menu

This allows Qt Quick items to react to the QContextMenuEvent, rather
than immediately showing a native edit menu.

Task-number: QTBUG-35598
Change-Id: Id8f492b549431a42aa26f2d72b418301d2cab3dd
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
(cherry picked from commit e426737d73bdda1b936e52179b08108250907e03)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Mitch Curtis 2025-01-21 12:18:30 +08:00 committed by Qt Cherry-pick Bot
parent ef42c65ab1
commit 56c39a2622

View File

@ -14,6 +14,8 @@
#include "qiosglobal.h"
#include "qiostextinputoverlay.h"
#include "qioswindow.h"
#include "quiview.h"
typedef QPair<int, int> SelectionPair;
typedef void (^Block)(void);
@ -130,6 +132,24 @@ static void executeBlockWithoutAnimation(Block block)
@end
void showEditMenu(UIView *focusView, QPoint touchPos)
{
const bool mouseTriggered = false;
const Qt::KeyboardModifiers keyboardModifiers = Qt::NoModifier;
QWindow *qtWindow = quiview_cast(focusView).platformWindow->window();
const auto globalTouchPos = qtWindow->mapToGlobal(touchPos);
const bool contextMenuEventAccepted = QWindowSystemInterface::handleContextMenuEvent<
QWindowSystemInterface::SynchronousDelivery>(qtWindow, mouseTriggered, touchPos,
globalTouchPos, keyboardModifiers);
if (!contextMenuEventAccepted) {
// Fall back to show the default platform menu, like we did
// before we started sending context menu events. This is
// to be backwards compatible with Widgets and Quick items.
QIOSTextInputOverlay::s_editMenu.visible = YES;
}
}
// -------------------------------------------------------------------------
@interface QIOSLoupeLayer : CALayer
@ -469,12 +489,14 @@ static void executeBlockWithoutAnimation(Block block)
// Tell the sub class to move the loupe to the correct position
[self updateFocalPoint:QPointF::fromCGPoint(_lastTouchPoint)];
break;
case UIGestureRecognizerStateEnded:
case UIGestureRecognizerStateEnded: {
// Restore cursor blinking, and hide the loupe
QGuiApplication::styleHints()->setCursorFlashTime(_originalCursorFlashTime);
QIOSTextInputOverlay::s_editMenu.visible = YES;
const QPoint touchPos = QPointF::fromCGPoint(_lastTouchPoint).toPoint();
showEditMenu(_focusView, touchPos);
_loupeLayer.visible = NO;
break;
}
default:
_loupeLayer.visible = NO;
break;
@ -956,7 +978,10 @@ static void executeBlockWithoutAnimation(Block block)
_menuShouldBeVisible = true;
self.state = UIGestureRecognizerStateFailed;
dispatch_async(dispatch_get_main_queue(), ^{
QIOSTextInputOverlay::s_editMenu.visible = _menuShouldBeVisible;
if (_menuShouldBeVisible)
showEditMenu(_focusView, touchPos.toPoint());
else
QIOSTextInputOverlay::s_editMenu.visible = false;
});
} else {
// The menu is hidden, and the cursor will change position once