diff --git a/src/plugins/platforms/ios/qiosmenu.h b/src/plugins/platforms/ios/qiosmenu.h index 5bebcc3cc6159445fc1315cfa5446758348c8747..ec23b5550787ced9274540c53d1cd17ef3870dbe 100644 --- a/src/plugins/platforms/ios/qiosmenu.h +++ b/src/plugins/platforms/ios/qiosmenu.h @@ -135,6 +135,7 @@ private: void toggleShowUsingUIMenuController(bool show); void toggleShowUsingUIPickerView(bool show); QIOSMenuItemList visibleMenuItems() const; + QIOSMenuItemList filterFirstResponderActions(const QIOSMenuItemList &menuItems); void repositionMenu(); }; diff --git a/src/plugins/platforms/ios/qiosmenu.mm b/src/plugins/platforms/ios/qiosmenu.mm index 9936296ae8e842b401dc0454b0728991c950e31d..de77097bf8f7ed1d2855f1813680e2cc8ae5aa6b 100644 --- a/src/plugins/platforms/ios/qiosmenu.mm +++ b/src/plugins/platforms/ios/qiosmenu.mm @@ -474,7 +474,7 @@ void QIOSMenu::toggleShowUsingUIMenuController(bool show) { if (show) { Q_ASSERT(!m_menuController); - m_menuController = [[QUIMenuController alloc] initWithVisibleMenuItems:visibleMenuItems()]; + m_menuController = [[QUIMenuController alloc] initWithVisibleMenuItems:filterFirstResponderActions(visibleMenuItems())]; repositionMenu(); connect(qGuiApp->inputMethod(), &QInputMethod::keyboardRectangleChanged, this, &QIOSMenu::repositionMenu); } else { @@ -547,6 +547,36 @@ QIOSMenuItemList QIOSMenu::visibleMenuItems() const return visibleMenuItems; } +QIOSMenuItemList QIOSMenu::filterFirstResponderActions(const QIOSMenuItemList &menuItems) +{ + // UIResponderStandardEditActions found in first responder will be prepended to the edit + // menu automatically (or e.g made available as buttons on the virtual keyboard). So we + // filter them out to avoid duplicates, and let first responder handle the actions instead. + // In case of QIOSTextResponder, edit actions will be converted to key events that ends up + // triggering the shortcuts of the filtered menu items. + QIOSMenuItemList filteredMenuItems; + UIResponder *responder = [UIResponder currentFirstResponder]; + + for (int i = 0; i < menuItems.count(); ++i) { + QIOSMenuItem *menuItem = menuItems.at(i); + QKeySequence shortcut = menuItem->m_shortcut; + if ((shortcut == QKeySequence::Cut && [responder canPerformAction:@selector(cut:) withSender:nil]) + || (shortcut == QKeySequence::Copy && [responder canPerformAction:@selector(copy:) withSender:nil]) + || (shortcut == QKeySequence::Paste && [responder canPerformAction:@selector(paste:) withSender:nil]) + || (shortcut == QKeySequence::Delete && [responder canPerformAction:@selector(delete:) withSender:nil]) + || (shortcut == QKeySequence::SelectAll && [responder canPerformAction:@selector(selectAll:) withSender:nil]) + || (shortcut == QKeySequence::Undo && [responder canPerformAction:@selector(undo:) withSender:nil]) + || (shortcut == QKeySequence::Redo && [responder canPerformAction:@selector(redo:) withSender:nil]) + || (shortcut == QKeySequence::Bold && [responder canPerformAction:@selector(toggleBoldface:) withSender:nil]) + || (shortcut == QKeySequence::Italic && [responder canPerformAction:@selector(toggleItalics:) withSender:nil]) + || (shortcut == QKeySequence::Underline && [responder canPerformAction:@selector(toggleUnderline:) withSender:nil])) { + continue; + } + filteredMenuItems.append(menuItem); + } + return filteredMenuItems; +} + void QIOSMenu::repositionMenu() { switch (m_effectiveMenuType) {