diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index ffa9b87147..881d7cc76a 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -291,6 +291,7 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni \row \li InsertParagraphSeparator \li Enter \li Enter \li Enter \li Enter \row \li InsertLineSeparator \li Shift+Enter \li Meta+Enter, Meta+O \li Shift+Enter \li Shift+Enter \row \li Backspace \li (none) \li Meta+H \li (none) \li (none) + \row \li Cancel \li Escape \li Escape, Ctrl+. \li Escape \li Escape \endtable Note that, since the key sequences used for the standard shortcuts differ @@ -752,6 +753,7 @@ static const struct { \value ZoomIn Zoom in. \value ZoomOut Zoom out. \value FullScreen Toggle the window state to/from full screen. + \value Cancel Cancel the current operation. */ /*! diff --git a/src/gui/kernel/qkeysequence.h b/src/gui/kernel/qkeysequence.h index d6171c86f2..98a611aab5 100644 --- a/src/gui/kernel/qkeysequence.h +++ b/src/gui/kernel/qkeysequence.h @@ -137,7 +137,8 @@ public: FullScreen, Deselect, DeleteCompleteLine, - Backspace + Backspace, + Cancel }; Q_ENUM(StandardKey) diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp index 36a71fe2da..ce8548f628 100644 --- a/src/gui/kernel/qplatformtheme.cpp +++ b/src/gui/kernel/qplatformtheme.cpp @@ -323,7 +323,9 @@ const QKeyBinding QPlatformThemePrivate::keyBindings[] = { {QKeySequence::FullScreen, 1, Qt::Key_F11, KB_Win | KB_KDE}, {QKeySequence::Deselect, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_A, KB_X11}, {QKeySequence::DeleteCompleteLine, 0, Qt::CTRL | Qt::Key_U, KB_X11}, - {QKeySequence::Backspace, 0, Qt::META | Qt::Key_H, KB_Mac} + {QKeySequence::Backspace, 0, Qt::META | Qt::Key_H, KB_Mac}, + {QKeySequence::Cancel, 0, Qt::Key_Escape, KB_All}, + {QKeySequence::Cancel, 0, Qt::CTRL | Qt::Key_Period, KB_Mac} }; const uint QPlatformThemePrivate::numberOfKeyBindings = sizeof(QPlatformThemePrivate::keyBindings)/(sizeof(QKeyBinding)); diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 51679116b5..05e6cf3c9e 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -270,7 +270,6 @@ public: // for QNSView QPointer m_enterLeaveTargetWindow; bool m_windowUnderMouse; - bool m_ignoreWindowShouldClose; bool m_inConstructor; bool m_inSetVisible; bool m_inSetGeometry; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 5606f050a3..8a8e03d283 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -345,7 +345,6 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) , m_synchedWindowState(Qt::WindowActive) , m_windowModality(Qt::NonModal) , m_windowUnderMouse(false) - , m_ignoreWindowShouldClose(false) , m_inConstructor(true) , m_inSetVisible(false) , m_inSetGeometry(false) @@ -1219,9 +1218,10 @@ void QCocoaWindow::windowDidEndLiveResize() bool QCocoaWindow::windowShouldClose() { - // might have been set from qnsview.mm - if (m_ignoreWindowShouldClose) - return false; + // This callback should technically only determine if the window + // should (be allowed to) close, but since our QPA API to determine + // that also involves actually closing the window we do both at the + // same time, instead of doing the latter in windowWillClose. bool accepted = false; QWindowSystemInterface::handleCloseEvent(window(), &accepted); QWindowSystemInterface::flushWindowSystemEvents(); diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index 14a61554a3..028a34af1c 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -76,6 +76,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper)); bool m_resendKeyEvent; bool m_scrolling; bool m_exposedOnMoveToWindow; + NSEvent *m_currentlyInterpretedKeyEvent; } - (id)init; @@ -131,7 +132,6 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper)); - (void)handleKeyEvent:(NSEvent *)theEvent eventType:(int)eventType; - (void)keyDown:(NSEvent *)theEvent; - (void)keyUp:(NSEvent *)theEvent; -- (BOOL)performKeyEquivalent:(NSEvent *)theEvent; - (void)registerDragTypes; - (NSDragOperation)handleDrag:(id )sender; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 4db55c1b73..7da0c4d402 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -152,6 +152,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; m_mouseMoveHelper = [[QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) alloc] initWithView:self]; m_resendKeyEvent = false; m_scrolling = false; + m_currentlyInterpretedKeyEvent = 0; if (!touchDevice) { touchDevice = new QTouchDevice; @@ -1449,21 +1450,17 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) QObject *fo = QGuiApplication::focusObject(); if (m_sendKeyEvent && fo) { - // if escape is pressed we don't want interpretKeyEvents to close a dialog. This will be done via QWindowSystemInterface - if (keyCode == Qt::Key_Escape) - m_platformWindow->m_ignoreWindowShouldClose = true; - QInputMethodQueryEvent queryEvent(Qt::ImEnabled | Qt::ImHints); if (QCoreApplication::sendEvent(fo, &queryEvent)) { bool imEnabled = queryEvent.value(Qt::ImEnabled).toBool(); Qt::InputMethodHints hints = static_cast(queryEvent.value(Qt::ImHints).toUInt()); if (imEnabled && !(hints & Qt::ImhDigitsOnly || hints & Qt::ImhFormattedNumbersOnly || hints & Qt::ImhHiddenText)) { // pass the key event to the input method. note that m_sendKeyEvent may be set to false during this call + m_currentlyInterpretedKeyEvent = nsevent; [self interpretKeyEvents:[NSArray arrayWithObject:nsevent]]; + m_currentlyInterpretedKeyEvent = 0; } } - - m_platformWindow->m_ignoreWindowShouldClose = false;; } if (m_resendKeyEvent) m_sendKeyEvent = true; @@ -1491,21 +1488,23 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) [self handleKeyEvent:nsevent eventType:int(QEvent::KeyRelease)]; } -- (BOOL)performKeyEquivalent:(NSEvent *)nsevent +- (void)cancelOperation:(id)sender { - NSString *chars = [nsevent charactersIgnoringModifiers]; + Q_UNUSED(sender); - if ([nsevent type] == NSKeyDown && [chars length] > 0) { - QChar ch = [chars characterAtIndex:0]; - Qt::Key qtKey = qt_mac_cocoaKey2QtKey(ch); - // check for Command + Key_Period - if ([nsevent modifierFlags] & NSCommandKeyMask - && qtKey == Qt::Key_Period) { - [self handleKeyEvent:nsevent eventType:int(QEvent::KeyPress)]; - return YES; - } - } - return [super performKeyEquivalent:nsevent]; + NSEvent *currentEvent = [NSApp currentEvent]; + if (!currentEvent || currentEvent.type != NSKeyDown) + return; + + // Handling the key event may recurse back here through interpretKeyEvents + // (when IM is enabled), so we need to guard against that. + if (currentEvent == m_currentlyInterpretedKeyEvent) + return; + + // Send Command+Key_Period and Escape as normal keypresses so that + // the key sequence is delivered through Qt. That way clients can + // intercept the shortcut and override its effect. + [self handleKeyEvent:currentEvent eventType:int(QEvent::KeyPress)]; } - (void)flagsChanged:(NSEvent *)nsevent diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp index 2ebbaaee10..468bffe49e 100644 --- a/src/widgets/dialogs/qcolordialog.cpp +++ b/src/widgets/dialogs/qcolordialog.cpp @@ -2286,16 +2286,12 @@ bool QColorDialogPrivate::handleColorPickingMouseButtonRelease(QMouseEvent *e) bool QColorDialogPrivate::handleColorPickingKeyPress(QKeyEvent *e) { Q_Q(QColorDialog); - switch (e->key()) { - case Qt::Key_Escape: + if (e->matches(QKeySequence::Cancel)) { releaseColorPicking(); q->setCurrentColor(beforeScreenColorPicking); - break; - case Qt::Key_Return: - case Qt::Key_Enter: + } else if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) { q->setCurrentColor(grabScreenColor(QCursor::pos())); releaseColorPicking(); - break; } e->accept(); return true; diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp index d04241fee0..5124960ab4 100644 --- a/src/widgets/dialogs/qdialog.cpp +++ b/src/widgets/dialogs/qdialog.cpp @@ -651,11 +651,9 @@ void QDialog::keyPressEvent(QKeyEvent *e) // Calls reject() if Escape is pressed. Simulates a button // click for the default button if Enter is pressed. Move focus // for the arrow keys. Ignore the rest. -#ifdef Q_OS_MAC - if(e->modifiers() == Qt::ControlModifier && e->key() == Qt::Key_Period) { + if (e->matches(QKeySequence::Cancel)) { reject(); } else -#endif if (!e->modifiers() || (e->modifiers() & Qt::KeypadModifier && e->key() == Qt::Key_Enter)) { switch (e->key()) { case Qt::Key_Enter: @@ -671,9 +669,6 @@ void QDialog::keyPressEvent(QKeyEvent *e) } } break; - case Qt::Key_Escape: - reject(); - break; default: e->ignore(); return; diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 81beccd5c8..ee2b1e6dae 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -3778,6 +3778,12 @@ void QFileDialogPrivate::_q_nativeEnterDirectory(const QUrl &directory) bool QFileDialogPrivate::itemViewKeyboardEvent(QKeyEvent *event) { Q_Q(QFileDialog); + + if (event->matches(QKeySequence::Cancel)) { + q->hide(); + return true; + } + switch (event->key()) { case Qt::Key_Backspace: _q_navigateToParent(); @@ -3793,9 +3799,6 @@ bool QFileDialogPrivate::itemViewKeyboardEvent(QKeyEvent *event) { return true; } break; - case Qt::Key_Escape: - q->hide(); - return true; default: break; } @@ -3982,7 +3985,7 @@ void QFileDialogLineEdit::keyPressEvent(QKeyEvent *e) int key = e->key(); QLineEdit::keyPressEvent(e); - if (key != Qt::Key_Escape && key != Qt::Key_Back) + if (!e->matches(QKeySequence::Cancel) && key != Qt::Key_Back) e->accept(); } diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index ef9b55acd6..8a48100ea7 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -1450,11 +1450,8 @@ void QMessageBox::changeEvent(QEvent *ev) void QMessageBox::keyPressEvent(QKeyEvent *e) { Q_D(QMessageBox); - if (e->key() == Qt::Key_Escape -#ifdef Q_OS_MAC - || (e->modifiers() == Qt::ControlModifier && e->key() == Qt::Key_Period) -#endif - ) { + + if (e->matches(QKeySequence::Cancel)) { if (d->detectedEscapeButton) { #ifdef Q_OS_MAC d->detectedEscapeButton->animateClick(); diff --git a/src/widgets/dialogs/qprogressdialog.cpp b/src/widgets/dialogs/qprogressdialog.cpp index 97e9267a9d..bbb251c8b2 100644 --- a/src/widgets/dialogs/qprogressdialog.cpp +++ b/src/widgets/dialogs/qprogressdialog.cpp @@ -411,7 +411,8 @@ void QProgressDialog::setCancelButton(QPushButton *cancelButton) if (cancelButton) { connect(d->cancel, SIGNAL(clicked()), this, SIGNAL(canceled())); #ifndef QT_NO_SHORTCUT - d->escapeShortcut = new QShortcut(Qt::Key_Escape, this, SIGNAL(canceled())); + // FIXME: This only registers the primary key sequence of the cancel action + d->escapeShortcut = new QShortcut(QKeySequence::Cancel, this, SIGNAL(canceled())); #endif } else { #ifndef QT_NO_SHORTCUT diff --git a/src/widgets/itemviews/qabstractitemdelegate.cpp b/src/widgets/itemviews/qabstractitemdelegate.cpp index 6efe5ccb71..c2dd1ec8fd 100644 --- a/src/widgets/itemviews/qabstractitemdelegate.cpp +++ b/src/widgets/itemviews/qabstractitemdelegate.cpp @@ -455,6 +455,12 @@ bool QAbstractItemDelegatePrivate::editorEventFilter(QObject *object, QEvent *ev if (editorHandlesKeyEvent(editor, keyEvent)) return false; + if (keyEvent->matches(QKeySequence::Cancel)) { + // don't commit data + emit q->closeEditor(editor, QAbstractItemDelegate::RevertModelCache); + return true; + } + switch (keyEvent->key()) { case Qt::Key_Tab: if (tryFixup(editor)) { @@ -479,10 +485,6 @@ bool QAbstractItemDelegatePrivate::editorEventFilter(QObject *object, QEvent *ev QMetaObject::invokeMethod(q, "_q_commitDataAndCloseEditor", Qt::QueuedConnection, Q_ARG(QWidget*, editor)); return false; - case Qt::Key_Escape: - // don't commit data - emit q->closeEditor(editor, QAbstractItemDelegate::RevertModelCache); - return true; default: return false; } @@ -509,7 +511,7 @@ bool QAbstractItemDelegatePrivate::editorEventFilter(QObject *object, QEvent *ev emit q->closeEditor(editor, QAbstractItemDelegate::NoHint); } } else if (event->type() == QEvent::ShortcutOverride) { - if (static_cast(event)->key() == Qt::Key_Escape) { + if (static_cast(event)->matches(QKeySequence::Cancel)) { event->accept(); return true; } diff --git a/src/widgets/kernel/qwhatsthis.cpp b/src/widgets/kernel/qwhatsthis.cpp index 1e437c4fb7..81de2f25ca 100644 --- a/src/widgets/kernel/qwhatsthis.cpp +++ b/src/widgets/kernel/qwhatsthis.cpp @@ -459,7 +459,7 @@ bool QWhatsThisPrivate::eventFilter(QObject *o, QEvent *e) { QKeyEvent* kev = (QKeyEvent*)e; - if (kev->key() == Qt::Key_Escape) { + if (kev->matches(QKeySequence::Cancel)) { QWhatsThis::leaveWhatsThisMode(); return true; } else if (customWhatsThis) { diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 2c9cc5c07b..66c86a7bce 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -9349,7 +9349,8 @@ void QWidget::tabletEvent(QTabletEvent *event) call the base class implementation if you do not act upon the key. The default implementation closes popup widgets if the user - presses Esc. Otherwise the event is ignored, so that the widget's + presses the key sequence for QKeySequence::Cancel (typically the + Escape key). Otherwise the event is ignored, so that the widget's parent can interpret it. Note that QKeyEvent starts with isAccepted() == true, so you do not @@ -9362,7 +9363,7 @@ void QWidget::tabletEvent(QTabletEvent *event) void QWidget::keyPressEvent(QKeyEvent *event) { - if ((windowType() == Qt::Popup) && event->key() == Qt::Key_Escape) { + if ((windowType() == Qt::Popup) && event->matches(QKeySequence::Cancel)) { event->accept(); close(); } else { diff --git a/src/widgets/util/qcompleter.cpp b/src/widgets/util/qcompleter.cpp index fedc928f61..559f024e5f 100644 --- a/src/widgets/util/qcompleter.cpp +++ b/src/widgets/util/qcompleter.cpp @@ -1337,6 +1337,11 @@ bool QCompleter::eventFilter(QObject *o, QEvent *e) } // default implementation for keys not handled by the widget when popup is open + if (ke->matches(QKeySequence::Cancel)) { + d->popup->hide(); + return true; + } + switch (key) { #ifdef QT_KEYPAD_NAVIGATION case Qt::Key_Select: @@ -1357,7 +1362,6 @@ bool QCompleter::eventFilter(QObject *o, QEvent *e) break; case Qt::Key_Backtab: - case Qt::Key_Escape: d->popup->hide(); break; diff --git a/src/widgets/widgets/qabstractbutton.cpp b/src/widgets/widgets/qabstractbutton.cpp index 292bbc3325..a1707b9cab 100644 --- a/src/widgets/widgets/qabstractbutton.cpp +++ b/src/widgets/widgets/qabstractbutton.cpp @@ -1221,16 +1221,14 @@ void QAbstractButton::keyPressEvent(QKeyEvent *e) } break; } - case Qt::Key_Escape: - if (d->down) { + default: + if (e->matches(QKeySequence::Cancel) && d->down) { setDown(false); repaint(); //flush paint event before invoking potentially expensive operation QApplication::flush(); d->emitReleased(); - break; + return; } - // fall through - default: e->ignore(); } } diff --git a/src/widgets/widgets/qcalendarwidget.cpp b/src/widgets/widgets/qcalendarwidget.cpp index 2150fc7a50..48b224fe13 100644 --- a/src/widgets/widgets/qcalendarwidget.cpp +++ b/src/widgets/widgets/qcalendarwidget.cpp @@ -776,7 +776,7 @@ bool QCalendarTextNavigator::eventFilter(QObject *o, QEvent *e) applyDate(); emit editingFinished(); removeDateLabel(); - } else if (ke->key() == Qt::Key_Escape) { + } else if (ke->matches(QKeySequence::Cancel)) { removeDateLabel(); } else if (e->type() == QEvent::KeyPress) { createDateLabel(); @@ -3078,8 +3078,7 @@ void QCalendarWidget::resizeEvent(QResizeEvent * event) void QCalendarWidget::keyPressEvent(QKeyEvent * event) { Q_D(QCalendarWidget); - if(d->yearEdit->isVisible()&& event->key() == Qt::Key_Escape) - { + if (d->yearEdit->isVisible()&& event->matches(QKeySequence::Cancel)) { d->yearEdit->setValue(yearShown()); d->_q_yearEditingFinished(); return; diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 89fd3d3d57..aab28bf18a 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -654,8 +654,9 @@ void QComboBoxPrivateContainer::changeEvent(QEvent *e) bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e) { switch (e->type()) { - case QEvent::ShortcutOverride: - switch (static_cast(e)->key()) { + case QEvent::ShortcutOverride: { + QKeyEvent *keyEvent = static_cast(e); + switch (keyEvent->key()) { case Qt::Key_Enter: case Qt::Key_Return: #ifdef QT_KEYPAD_NAVIGATION @@ -667,17 +668,21 @@ bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e) } return true; case Qt::Key_Down: - if (!(static_cast(e)->modifiers() & Qt::AltModifier)) + if (!(keyEvent->modifiers() & Qt::AltModifier)) break; // fall through case Qt::Key_F4: - case Qt::Key_Escape: combo->hidePopup(); return true; default: + if (keyEvent->matches(QKeySequence::Cancel)) { + combo->hidePopup(); + return true; + } break; } - break; + break; + } case QEvent::MouseMove: if (isVisible()) { QMouseEvent *m = static_cast(e); diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp index a8da78a025..42987df3ec 100644 --- a/src/widgets/widgets/qdatetimeedit.cpp +++ b/src/widgets/widgets/qdatetimeedit.cpp @@ -2655,7 +2655,7 @@ bool QCalendarPopup::event(QEvent *event) { if (event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast(event); - if (keyEvent->key()== Qt::Key_Escape) + if (keyEvent->matches(QKeySequence::Cancel)) dateChanged = false; } return QWidget::event(event); diff --git a/src/widgets/widgets/qeffects.cpp b/src/widgets/widgets/qeffects.cpp index 708e90cc32..b256861d08 100644 --- a/src/widgets/widgets/qeffects.cpp +++ b/src/widgets/widgets/qeffects.cpp @@ -197,7 +197,7 @@ bool QAlphaWidget::eventFilter(QObject *o, QEvent *e) break; case QEvent::KeyPress: { QKeyEvent *ke = (QKeyEvent*)e; - if (ke->key() == Qt::Key_Escape) { + if (ke->matches(QKeySequence::Cancel)) { showWidget = false; } else { duration = 0; diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 0556c02b64..6e37f91197 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -2679,7 +2679,7 @@ QMenu::event(QEvent *e) if (kev->key() == Qt::Key_Up || kev->key() == Qt::Key_Down || kev->key() == Qt::Key_Left || kev->key() == Qt::Key_Right || kev->key() == Qt::Key_Enter || kev->key() == Qt::Key_Return - || kev->key() == Qt::Key_Escape) { + || kev->matches(QKeySequence::Cancel)) { e->accept(); return true; } @@ -2965,27 +2965,6 @@ void QMenu::keyPressEvent(QKeyEvent *e) } break; - case Qt::Key_Escape: -#ifdef QT_KEYPAD_NAVIGATION - case Qt::Key_Back: -#endif - key_consumed = true; - if (d->tornoff) { - close(); - return; - } - { - QPointer caused = d->causedPopup.widget; - d->hideMenu(this); // hide after getting causedPopup -#ifndef QT_NO_MENUBAR - if (QMenuBar *mb = qobject_cast(caused)) { - mb->d_func()->setCurrentAction(d->menuAction); - mb->d_func()->setKeyboardMode(true); - } -#endif - } - break; - case Qt::Key_Space: if (!style()->styleHint(QStyle::SH_Menu_SpaceActivatesItem, 0, this)) break; @@ -3022,6 +3001,28 @@ void QMenu::keyPressEvent(QKeyEvent *e) key_consumed = false; } + if (!key_consumed && (e->matches(QKeySequence::Cancel) +#ifdef QT_KEYPAD_NAVIGATION + || e->key() == Qt::Key_Back +#endif + )) { + key_consumed = true; + if (d->tornoff) { + close(); + return; + } + { + QPointer caused = d->causedPopup.widget; + d->hideMenu(this); // hide after getting causedPopup +#ifndef QT_NO_MENUBAR + if (QMenuBar *mb = qobject_cast(caused)) { + mb->d_func()->setCurrentAction(d->menuAction); + mb->d_func()->setKeyboardMode(true); + } +#endif + } + } + if (!key_consumed) { // send to menu bar if ((!e->modifiers() || e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ShiftModifier) && e->text().length()==1) { diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index d382131075..2e48607f82 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -1122,14 +1122,14 @@ void QMenuBar::keyPressEvent(QKeyEvent *e) } break; } - case Qt::Key_Escape: + default: + key_consumed = false; + } + + if (!key_consumed && e->matches(QKeySequence::Cancel)) { d->setCurrentAction(0); d->setKeyboardMode(false); key_consumed = true; - break; - - default: - key_consumed = false; } if(!key_consumed && @@ -1432,7 +1432,7 @@ bool QMenuBar::event(QEvent *e) case QEvent::ShortcutOverride: { QKeyEvent *kev = static_cast(e); //we only filter out escape if there is a current action - if (kev->key() == Qt::Key_Escape && d->currentAction) { + if (kev->matches(QKeySequence::Cancel) && d->currentAction) { e->accept(); return true; }