Clean up cancel operation handling on OS X
The logic for handling cancel operations was spread out through the code base and sometimes hard-coded to only include the Escape key shortcut, missing the Command+. shortcut. We now intercept both attempts at cancel operations from the system through cancelOperation, which we forward as normal key events. A new QKeySequence::StandardKey has been added for the Cancel sequence, which maps to Escape on all platforms, and Command+. in addition for OS X. The hard-coded logic in QWidget and subclasses for dealing with closing the dialogs has been replaced with this key sequence, which allows clients to override the behavior. Note that the widget code is not wrapped in checks for QT_NO_SHORTCUT, as we don't care about keeping widgets building and working under that define. The logic in QCocoaWindow to bypass windowShouldClose when delivering IM events has been removed as we now handle that specific case by also forwarding Escape as a cancel operation. Task-number: QTBUG-47557 Task-number: QTBUG-45771 Task-number: QTBUG-44076 Change-Id: Ibe0b3a4819f8659d246a2142dd7d9cd3a826ef78 Reviewed-by: Tim Blechmann <tim@klingt.org> Reviewed-by: Morten Johan Sørvig <morten.sorvig@theqtcompany.com> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@theqtcompany.com>
This commit is contained in:
parent
b2e664df61
commit
126c2cb8fb
@ -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.
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
@ -137,7 +137,8 @@ public:
|
||||
FullScreen,
|
||||
Deselect,
|
||||
DeleteCompleteLine,
|
||||
Backspace
|
||||
Backspace,
|
||||
Cancel
|
||||
};
|
||||
Q_ENUM(StandardKey)
|
||||
|
||||
|
@ -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));
|
||||
|
@ -270,7 +270,6 @@ public: // for QNSView
|
||||
QPointer<QWindow> m_enterLeaveTargetWindow;
|
||||
bool m_windowUnderMouse;
|
||||
|
||||
bool m_ignoreWindowShouldClose;
|
||||
bool m_inConstructor;
|
||||
bool m_inSetVisible;
|
||||
bool m_inSetGeometry;
|
||||
|
@ -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();
|
||||
|
@ -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 <NSDraggingInfo>)sender;
|
||||
|
@ -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<Qt::InputMethodHints>(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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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<QKeyEvent*>(event)->key() == Qt::Key_Escape) {
|
||||
if (static_cast<QKeyEvent*>(event)->matches(QKeySequence::Cancel)) {
|
||||
event->accept();
|
||||
return true;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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<QKeyEvent*>(e)->key()) {
|
||||
case QEvent::ShortcutOverride: {
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(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<QKeyEvent*>(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;
|
||||
}
|
||||
case QEvent::MouseMove:
|
||||
if (isVisible()) {
|
||||
QMouseEvent *m = static_cast<QMouseEvent *>(e);
|
||||
|
@ -2655,7 +2655,7 @@ bool QCalendarPopup::event(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::KeyPress) {
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
|
||||
if (keyEvent->key()== Qt::Key_Escape)
|
||||
if (keyEvent->matches(QKeySequence::Cancel))
|
||||
dateChanged = false;
|
||||
}
|
||||
return QWidget::event(event);
|
||||
|
@ -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;
|
||||
|
@ -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<QWidget> caused = d->causedPopup.widget;
|
||||
d->hideMenu(this); // hide after getting causedPopup
|
||||
#ifndef QT_NO_MENUBAR
|
||||
if (QMenuBar *mb = qobject_cast<QMenuBar*>(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<QWidget> caused = d->causedPopup.widget;
|
||||
d->hideMenu(this); // hide after getting causedPopup
|
||||
#ifndef QT_NO_MENUBAR
|
||||
if (QMenuBar *mb = qobject_cast<QMenuBar*>(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) {
|
||||
|
@ -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<QKeyEvent*>(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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user