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 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 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 Backspace \li (none) \li Meta+H \li (none) \li (none)
|
||||||
|
\row \li Cancel \li Escape \li Escape, Ctrl+. \li Escape \li Escape
|
||||||
\endtable
|
\endtable
|
||||||
|
|
||||||
Note that, since the key sequences used for the standard shortcuts differ
|
Note that, since the key sequences used for the standard shortcuts differ
|
||||||
@ -752,6 +753,7 @@ static const struct {
|
|||||||
\value ZoomIn Zoom in.
|
\value ZoomIn Zoom in.
|
||||||
\value ZoomOut Zoom out.
|
\value ZoomOut Zoom out.
|
||||||
\value FullScreen Toggle the window state to/from full screen.
|
\value FullScreen Toggle the window state to/from full screen.
|
||||||
|
\value Cancel Cancel the current operation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -137,7 +137,8 @@ public:
|
|||||||
FullScreen,
|
FullScreen,
|
||||||
Deselect,
|
Deselect,
|
||||||
DeleteCompleteLine,
|
DeleteCompleteLine,
|
||||||
Backspace
|
Backspace,
|
||||||
|
Cancel
|
||||||
};
|
};
|
||||||
Q_ENUM(StandardKey)
|
Q_ENUM(StandardKey)
|
||||||
|
|
||||||
|
@ -323,7 +323,9 @@ const QKeyBinding QPlatformThemePrivate::keyBindings[] = {
|
|||||||
{QKeySequence::FullScreen, 1, Qt::Key_F11, KB_Win | KB_KDE},
|
{QKeySequence::FullScreen, 1, Qt::Key_F11, KB_Win | KB_KDE},
|
||||||
{QKeySequence::Deselect, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_A, KB_X11},
|
{QKeySequence::Deselect, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_A, KB_X11},
|
||||||
{QKeySequence::DeleteCompleteLine, 0, Qt::CTRL | Qt::Key_U, 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));
|
const uint QPlatformThemePrivate::numberOfKeyBindings = sizeof(QPlatformThemePrivate::keyBindings)/(sizeof(QKeyBinding));
|
||||||
|
@ -270,7 +270,6 @@ public: // for QNSView
|
|||||||
QPointer<QWindow> m_enterLeaveTargetWindow;
|
QPointer<QWindow> m_enterLeaveTargetWindow;
|
||||||
bool m_windowUnderMouse;
|
bool m_windowUnderMouse;
|
||||||
|
|
||||||
bool m_ignoreWindowShouldClose;
|
|
||||||
bool m_inConstructor;
|
bool m_inConstructor;
|
||||||
bool m_inSetVisible;
|
bool m_inSetVisible;
|
||||||
bool m_inSetGeometry;
|
bool m_inSetGeometry;
|
||||||
|
@ -345,7 +345,6 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
|
|||||||
, m_synchedWindowState(Qt::WindowActive)
|
, m_synchedWindowState(Qt::WindowActive)
|
||||||
, m_windowModality(Qt::NonModal)
|
, m_windowModality(Qt::NonModal)
|
||||||
, m_windowUnderMouse(false)
|
, m_windowUnderMouse(false)
|
||||||
, m_ignoreWindowShouldClose(false)
|
|
||||||
, m_inConstructor(true)
|
, m_inConstructor(true)
|
||||||
, m_inSetVisible(false)
|
, m_inSetVisible(false)
|
||||||
, m_inSetGeometry(false)
|
, m_inSetGeometry(false)
|
||||||
@ -1219,9 +1218,10 @@ void QCocoaWindow::windowDidEndLiveResize()
|
|||||||
|
|
||||||
bool QCocoaWindow::windowShouldClose()
|
bool QCocoaWindow::windowShouldClose()
|
||||||
{
|
{
|
||||||
// might have been set from qnsview.mm
|
// This callback should technically only determine if the window
|
||||||
if (m_ignoreWindowShouldClose)
|
// should (be allowed to) close, but since our QPA API to determine
|
||||||
return false;
|
// that also involves actually closing the window we do both at the
|
||||||
|
// same time, instead of doing the latter in windowWillClose.
|
||||||
bool accepted = false;
|
bool accepted = false;
|
||||||
QWindowSystemInterface::handleCloseEvent(window(), &accepted);
|
QWindowSystemInterface::handleCloseEvent(window(), &accepted);
|
||||||
QWindowSystemInterface::flushWindowSystemEvents();
|
QWindowSystemInterface::flushWindowSystemEvents();
|
||||||
|
@ -76,6 +76,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
|
|||||||
bool m_resendKeyEvent;
|
bool m_resendKeyEvent;
|
||||||
bool m_scrolling;
|
bool m_scrolling;
|
||||||
bool m_exposedOnMoveToWindow;
|
bool m_exposedOnMoveToWindow;
|
||||||
|
NSEvent *m_currentlyInterpretedKeyEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)init;
|
- (id)init;
|
||||||
@ -131,7 +132,6 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
|
|||||||
- (void)handleKeyEvent:(NSEvent *)theEvent eventType:(int)eventType;
|
- (void)handleKeyEvent:(NSEvent *)theEvent eventType:(int)eventType;
|
||||||
- (void)keyDown:(NSEvent *)theEvent;
|
- (void)keyDown:(NSEvent *)theEvent;
|
||||||
- (void)keyUp:(NSEvent *)theEvent;
|
- (void)keyUp:(NSEvent *)theEvent;
|
||||||
- (BOOL)performKeyEquivalent:(NSEvent *)theEvent;
|
|
||||||
|
|
||||||
- (void)registerDragTypes;
|
- (void)registerDragTypes;
|
||||||
- (NSDragOperation)handleDrag:(id <NSDraggingInfo>)sender;
|
- (NSDragOperation)handleDrag:(id <NSDraggingInfo>)sender;
|
||||||
|
@ -152,6 +152,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
|
|||||||
m_mouseMoveHelper = [[QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) alloc] initWithView:self];
|
m_mouseMoveHelper = [[QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) alloc] initWithView:self];
|
||||||
m_resendKeyEvent = false;
|
m_resendKeyEvent = false;
|
||||||
m_scrolling = false;
|
m_scrolling = false;
|
||||||
|
m_currentlyInterpretedKeyEvent = 0;
|
||||||
|
|
||||||
if (!touchDevice) {
|
if (!touchDevice) {
|
||||||
touchDevice = new QTouchDevice;
|
touchDevice = new QTouchDevice;
|
||||||
@ -1449,21 +1450,17 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
|
|||||||
|
|
||||||
QObject *fo = QGuiApplication::focusObject();
|
QObject *fo = QGuiApplication::focusObject();
|
||||||
if (m_sendKeyEvent && fo) {
|
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);
|
QInputMethodQueryEvent queryEvent(Qt::ImEnabled | Qt::ImHints);
|
||||||
if (QCoreApplication::sendEvent(fo, &queryEvent)) {
|
if (QCoreApplication::sendEvent(fo, &queryEvent)) {
|
||||||
bool imEnabled = queryEvent.value(Qt::ImEnabled).toBool();
|
bool imEnabled = queryEvent.value(Qt::ImEnabled).toBool();
|
||||||
Qt::InputMethodHints hints = static_cast<Qt::InputMethodHints>(queryEvent.value(Qt::ImHints).toUInt());
|
Qt::InputMethodHints hints = static_cast<Qt::InputMethodHints>(queryEvent.value(Qt::ImHints).toUInt());
|
||||||
if (imEnabled && !(hints & Qt::ImhDigitsOnly || hints & Qt::ImhFormattedNumbersOnly || hints & Qt::ImhHiddenText)) {
|
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
|
// 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]];
|
[self interpretKeyEvents:[NSArray arrayWithObject:nsevent]];
|
||||||
|
m_currentlyInterpretedKeyEvent = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_platformWindow->m_ignoreWindowShouldClose = false;;
|
|
||||||
}
|
}
|
||||||
if (m_resendKeyEvent)
|
if (m_resendKeyEvent)
|
||||||
m_sendKeyEvent = true;
|
m_sendKeyEvent = true;
|
||||||
@ -1491,21 +1488,23 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
|
|||||||
[self handleKeyEvent:nsevent eventType:int(QEvent::KeyRelease)];
|
[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) {
|
NSEvent *currentEvent = [NSApp currentEvent];
|
||||||
QChar ch = [chars characterAtIndex:0];
|
if (!currentEvent || currentEvent.type != NSKeyDown)
|
||||||
Qt::Key qtKey = qt_mac_cocoaKey2QtKey(ch);
|
return;
|
||||||
// check for Command + Key_Period
|
|
||||||
if ([nsevent modifierFlags] & NSCommandKeyMask
|
// Handling the key event may recurse back here through interpretKeyEvents
|
||||||
&& qtKey == Qt::Key_Period) {
|
// (when IM is enabled), so we need to guard against that.
|
||||||
[self handleKeyEvent:nsevent eventType:int(QEvent::KeyPress)];
|
if (currentEvent == m_currentlyInterpretedKeyEvent)
|
||||||
return YES;
|
return;
|
||||||
}
|
|
||||||
}
|
// Send Command+Key_Period and Escape as normal keypresses so that
|
||||||
return [super performKeyEquivalent:nsevent];
|
// 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
|
- (void)flagsChanged:(NSEvent *)nsevent
|
||||||
|
@ -2286,16 +2286,12 @@ bool QColorDialogPrivate::handleColorPickingMouseButtonRelease(QMouseEvent *e)
|
|||||||
bool QColorDialogPrivate::handleColorPickingKeyPress(QKeyEvent *e)
|
bool QColorDialogPrivate::handleColorPickingKeyPress(QKeyEvent *e)
|
||||||
{
|
{
|
||||||
Q_Q(QColorDialog);
|
Q_Q(QColorDialog);
|
||||||
switch (e->key()) {
|
if (e->matches(QKeySequence::Cancel)) {
|
||||||
case Qt::Key_Escape:
|
|
||||||
releaseColorPicking();
|
releaseColorPicking();
|
||||||
q->setCurrentColor(beforeScreenColorPicking);
|
q->setCurrentColor(beforeScreenColorPicking);
|
||||||
break;
|
} else if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
|
||||||
case Qt::Key_Return:
|
|
||||||
case Qt::Key_Enter:
|
|
||||||
q->setCurrentColor(grabScreenColor(QCursor::pos()));
|
q->setCurrentColor(grabScreenColor(QCursor::pos()));
|
||||||
releaseColorPicking();
|
releaseColorPicking();
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
e->accept();
|
e->accept();
|
||||||
return true;
|
return true;
|
||||||
|
@ -651,11 +651,9 @@ void QDialog::keyPressEvent(QKeyEvent *e)
|
|||||||
// Calls reject() if Escape is pressed. Simulates a button
|
// Calls reject() if Escape is pressed. Simulates a button
|
||||||
// click for the default button if Enter is pressed. Move focus
|
// click for the default button if Enter is pressed. Move focus
|
||||||
// for the arrow keys. Ignore the rest.
|
// for the arrow keys. Ignore the rest.
|
||||||
#ifdef Q_OS_MAC
|
if (e->matches(QKeySequence::Cancel)) {
|
||||||
if(e->modifiers() == Qt::ControlModifier && e->key() == Qt::Key_Period) {
|
|
||||||
reject();
|
reject();
|
||||||
} else
|
} else
|
||||||
#endif
|
|
||||||
if (!e->modifiers() || (e->modifiers() & Qt::KeypadModifier && e->key() == Qt::Key_Enter)) {
|
if (!e->modifiers() || (e->modifiers() & Qt::KeypadModifier && e->key() == Qt::Key_Enter)) {
|
||||||
switch (e->key()) {
|
switch (e->key()) {
|
||||||
case Qt::Key_Enter:
|
case Qt::Key_Enter:
|
||||||
@ -671,9 +669,6 @@ void QDialog::keyPressEvent(QKeyEvent *e)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Escape:
|
|
||||||
reject();
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
e->ignore();
|
e->ignore();
|
||||||
return;
|
return;
|
||||||
|
@ -3778,6 +3778,12 @@ void QFileDialogPrivate::_q_nativeEnterDirectory(const QUrl &directory)
|
|||||||
bool QFileDialogPrivate::itemViewKeyboardEvent(QKeyEvent *event) {
|
bool QFileDialogPrivate::itemViewKeyboardEvent(QKeyEvent *event) {
|
||||||
|
|
||||||
Q_Q(QFileDialog);
|
Q_Q(QFileDialog);
|
||||||
|
|
||||||
|
if (event->matches(QKeySequence::Cancel)) {
|
||||||
|
q->hide();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
switch (event->key()) {
|
switch (event->key()) {
|
||||||
case Qt::Key_Backspace:
|
case Qt::Key_Backspace:
|
||||||
_q_navigateToParent();
|
_q_navigateToParent();
|
||||||
@ -3793,9 +3799,6 @@ bool QFileDialogPrivate::itemViewKeyboardEvent(QKeyEvent *event) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Escape:
|
|
||||||
q->hide();
|
|
||||||
return true;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3982,7 +3985,7 @@ void QFileDialogLineEdit::keyPressEvent(QKeyEvent *e)
|
|||||||
|
|
||||||
int key = e->key();
|
int key = e->key();
|
||||||
QLineEdit::keyPressEvent(e);
|
QLineEdit::keyPressEvent(e);
|
||||||
if (key != Qt::Key_Escape && key != Qt::Key_Back)
|
if (!e->matches(QKeySequence::Cancel) && key != Qt::Key_Back)
|
||||||
e->accept();
|
e->accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1450,11 +1450,8 @@ void QMessageBox::changeEvent(QEvent *ev)
|
|||||||
void QMessageBox::keyPressEvent(QKeyEvent *e)
|
void QMessageBox::keyPressEvent(QKeyEvent *e)
|
||||||
{
|
{
|
||||||
Q_D(QMessageBox);
|
Q_D(QMessageBox);
|
||||||
if (e->key() == Qt::Key_Escape
|
|
||||||
#ifdef Q_OS_MAC
|
if (e->matches(QKeySequence::Cancel)) {
|
||||||
|| (e->modifiers() == Qt::ControlModifier && e->key() == Qt::Key_Period)
|
|
||||||
#endif
|
|
||||||
) {
|
|
||||||
if (d->detectedEscapeButton) {
|
if (d->detectedEscapeButton) {
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
d->detectedEscapeButton->animateClick();
|
d->detectedEscapeButton->animateClick();
|
||||||
|
@ -411,7 +411,8 @@ void QProgressDialog::setCancelButton(QPushButton *cancelButton)
|
|||||||
if (cancelButton) {
|
if (cancelButton) {
|
||||||
connect(d->cancel, SIGNAL(clicked()), this, SIGNAL(canceled()));
|
connect(d->cancel, SIGNAL(clicked()), this, SIGNAL(canceled()));
|
||||||
#ifndef QT_NO_SHORTCUT
|
#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
|
#endif
|
||||||
} else {
|
} else {
|
||||||
#ifndef QT_NO_SHORTCUT
|
#ifndef QT_NO_SHORTCUT
|
||||||
|
@ -455,6 +455,12 @@ bool QAbstractItemDelegatePrivate::editorEventFilter(QObject *object, QEvent *ev
|
|||||||
if (editorHandlesKeyEvent(editor, keyEvent))
|
if (editorHandlesKeyEvent(editor, keyEvent))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (keyEvent->matches(QKeySequence::Cancel)) {
|
||||||
|
// don't commit data
|
||||||
|
emit q->closeEditor(editor, QAbstractItemDelegate::RevertModelCache);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
switch (keyEvent->key()) {
|
switch (keyEvent->key()) {
|
||||||
case Qt::Key_Tab:
|
case Qt::Key_Tab:
|
||||||
if (tryFixup(editor)) {
|
if (tryFixup(editor)) {
|
||||||
@ -479,10 +485,6 @@ bool QAbstractItemDelegatePrivate::editorEventFilter(QObject *object, QEvent *ev
|
|||||||
QMetaObject::invokeMethod(q, "_q_commitDataAndCloseEditor",
|
QMetaObject::invokeMethod(q, "_q_commitDataAndCloseEditor",
|
||||||
Qt::QueuedConnection, Q_ARG(QWidget*, editor));
|
Qt::QueuedConnection, Q_ARG(QWidget*, editor));
|
||||||
return false;
|
return false;
|
||||||
case Qt::Key_Escape:
|
|
||||||
// don't commit data
|
|
||||||
emit q->closeEditor(editor, QAbstractItemDelegate::RevertModelCache);
|
|
||||||
return true;
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -509,7 +511,7 @@ bool QAbstractItemDelegatePrivate::editorEventFilter(QObject *object, QEvent *ev
|
|||||||
emit q->closeEditor(editor, QAbstractItemDelegate::NoHint);
|
emit q->closeEditor(editor, QAbstractItemDelegate::NoHint);
|
||||||
}
|
}
|
||||||
} else if (event->type() == QEvent::ShortcutOverride) {
|
} 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();
|
event->accept();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -459,7 +459,7 @@ bool QWhatsThisPrivate::eventFilter(QObject *o, QEvent *e)
|
|||||||
{
|
{
|
||||||
QKeyEvent* kev = (QKeyEvent*)e;
|
QKeyEvent* kev = (QKeyEvent*)e;
|
||||||
|
|
||||||
if (kev->key() == Qt::Key_Escape) {
|
if (kev->matches(QKeySequence::Cancel)) {
|
||||||
QWhatsThis::leaveWhatsThisMode();
|
QWhatsThis::leaveWhatsThisMode();
|
||||||
return true;
|
return true;
|
||||||
} else if (customWhatsThis) {
|
} 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.
|
call the base class implementation if you do not act upon the key.
|
||||||
|
|
||||||
The default implementation closes popup widgets if the user
|
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.
|
parent can interpret it.
|
||||||
|
|
||||||
Note that QKeyEvent starts with isAccepted() == true, so you do not
|
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)
|
void QWidget::keyPressEvent(QKeyEvent *event)
|
||||||
{
|
{
|
||||||
if ((windowType() == Qt::Popup) && event->key() == Qt::Key_Escape) {
|
if ((windowType() == Qt::Popup) && event->matches(QKeySequence::Cancel)) {
|
||||||
event->accept();
|
event->accept();
|
||||||
close();
|
close();
|
||||||
} else {
|
} 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
|
// 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) {
|
switch (key) {
|
||||||
#ifdef QT_KEYPAD_NAVIGATION
|
#ifdef QT_KEYPAD_NAVIGATION
|
||||||
case Qt::Key_Select:
|
case Qt::Key_Select:
|
||||||
@ -1357,7 +1362,6 @@ bool QCompleter::eventFilter(QObject *o, QEvent *e)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::Key_Backtab:
|
case Qt::Key_Backtab:
|
||||||
case Qt::Key_Escape:
|
|
||||||
d->popup->hide();
|
d->popup->hide();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1221,16 +1221,14 @@ void QAbstractButton::keyPressEvent(QKeyEvent *e)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Qt::Key_Escape:
|
default:
|
||||||
if (d->down) {
|
if (e->matches(QKeySequence::Cancel) && d->down) {
|
||||||
setDown(false);
|
setDown(false);
|
||||||
repaint(); //flush paint event before invoking potentially expensive operation
|
repaint(); //flush paint event before invoking potentially expensive operation
|
||||||
QApplication::flush();
|
QApplication::flush();
|
||||||
d->emitReleased();
|
d->emitReleased();
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
// fall through
|
|
||||||
default:
|
|
||||||
e->ignore();
|
e->ignore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -776,7 +776,7 @@ bool QCalendarTextNavigator::eventFilter(QObject *o, QEvent *e)
|
|||||||
applyDate();
|
applyDate();
|
||||||
emit editingFinished();
|
emit editingFinished();
|
||||||
removeDateLabel();
|
removeDateLabel();
|
||||||
} else if (ke->key() == Qt::Key_Escape) {
|
} else if (ke->matches(QKeySequence::Cancel)) {
|
||||||
removeDateLabel();
|
removeDateLabel();
|
||||||
} else if (e->type() == QEvent::KeyPress) {
|
} else if (e->type() == QEvent::KeyPress) {
|
||||||
createDateLabel();
|
createDateLabel();
|
||||||
@ -3078,8 +3078,7 @@ void QCalendarWidget::resizeEvent(QResizeEvent * event)
|
|||||||
void QCalendarWidget::keyPressEvent(QKeyEvent * event)
|
void QCalendarWidget::keyPressEvent(QKeyEvent * event)
|
||||||
{
|
{
|
||||||
Q_D(QCalendarWidget);
|
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->yearEdit->setValue(yearShown());
|
||||||
d->_q_yearEditingFinished();
|
d->_q_yearEditingFinished();
|
||||||
return;
|
return;
|
||||||
|
@ -654,8 +654,9 @@ void QComboBoxPrivateContainer::changeEvent(QEvent *e)
|
|||||||
bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e)
|
bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e)
|
||||||
{
|
{
|
||||||
switch (e->type()) {
|
switch (e->type()) {
|
||||||
case QEvent::ShortcutOverride:
|
case QEvent::ShortcutOverride: {
|
||||||
switch (static_cast<QKeyEvent*>(e)->key()) {
|
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(e);
|
||||||
|
switch (keyEvent->key()) {
|
||||||
case Qt::Key_Enter:
|
case Qt::Key_Enter:
|
||||||
case Qt::Key_Return:
|
case Qt::Key_Return:
|
||||||
#ifdef QT_KEYPAD_NAVIGATION
|
#ifdef QT_KEYPAD_NAVIGATION
|
||||||
@ -667,17 +668,21 @@ bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e)
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
case Qt::Key_Down:
|
case Qt::Key_Down:
|
||||||
if (!(static_cast<QKeyEvent*>(e)->modifiers() & Qt::AltModifier))
|
if (!(keyEvent->modifiers() & Qt::AltModifier))
|
||||||
break;
|
break;
|
||||||
// fall through
|
// fall through
|
||||||
case Qt::Key_F4:
|
case Qt::Key_F4:
|
||||||
case Qt::Key_Escape:
|
|
||||||
combo->hidePopup();
|
combo->hidePopup();
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
|
if (keyEvent->matches(QKeySequence::Cancel)) {
|
||||||
|
combo->hidePopup();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case QEvent::MouseMove:
|
case QEvent::MouseMove:
|
||||||
if (isVisible()) {
|
if (isVisible()) {
|
||||||
QMouseEvent *m = static_cast<QMouseEvent *>(e);
|
QMouseEvent *m = static_cast<QMouseEvent *>(e);
|
||||||
|
@ -2655,7 +2655,7 @@ bool QCalendarPopup::event(QEvent *event)
|
|||||||
{
|
{
|
||||||
if (event->type() == QEvent::KeyPress) {
|
if (event->type() == QEvent::KeyPress) {
|
||||||
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
|
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
|
||||||
if (keyEvent->key()== Qt::Key_Escape)
|
if (keyEvent->matches(QKeySequence::Cancel))
|
||||||
dateChanged = false;
|
dateChanged = false;
|
||||||
}
|
}
|
||||||
return QWidget::event(event);
|
return QWidget::event(event);
|
||||||
|
@ -197,7 +197,7 @@ bool QAlphaWidget::eventFilter(QObject *o, QEvent *e)
|
|||||||
break;
|
break;
|
||||||
case QEvent::KeyPress: {
|
case QEvent::KeyPress: {
|
||||||
QKeyEvent *ke = (QKeyEvent*)e;
|
QKeyEvent *ke = (QKeyEvent*)e;
|
||||||
if (ke->key() == Qt::Key_Escape) {
|
if (ke->matches(QKeySequence::Cancel)) {
|
||||||
showWidget = false;
|
showWidget = false;
|
||||||
} else {
|
} else {
|
||||||
duration = 0;
|
duration = 0;
|
||||||
|
@ -2679,7 +2679,7 @@ QMenu::event(QEvent *e)
|
|||||||
if (kev->key() == Qt::Key_Up || kev->key() == Qt::Key_Down
|
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_Left || kev->key() == Qt::Key_Right
|
||||||
|| kev->key() == Qt::Key_Enter || kev->key() == Qt::Key_Return
|
|| kev->key() == Qt::Key_Enter || kev->key() == Qt::Key_Return
|
||||||
|| kev->key() == Qt::Key_Escape) {
|
|| kev->matches(QKeySequence::Cancel)) {
|
||||||
e->accept();
|
e->accept();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -2965,27 +2965,6 @@ void QMenu::keyPressEvent(QKeyEvent *e)
|
|||||||
}
|
}
|
||||||
break;
|
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:
|
case Qt::Key_Space:
|
||||||
if (!style()->styleHint(QStyle::SH_Menu_SpaceActivatesItem, 0, this))
|
if (!style()->styleHint(QStyle::SH_Menu_SpaceActivatesItem, 0, this))
|
||||||
break;
|
break;
|
||||||
@ -3022,6 +3001,28 @@ void QMenu::keyPressEvent(QKeyEvent *e)
|
|||||||
key_consumed = false;
|
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 (!key_consumed) { // send to menu bar
|
||||||
if ((!e->modifiers() || e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ShiftModifier) &&
|
if ((!e->modifiers() || e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ShiftModifier) &&
|
||||||
e->text().length()==1) {
|
e->text().length()==1) {
|
||||||
|
@ -1122,14 +1122,14 @@ void QMenuBar::keyPressEvent(QKeyEvent *e)
|
|||||||
}
|
}
|
||||||
break; }
|
break; }
|
||||||
|
|
||||||
case Qt::Key_Escape:
|
default:
|
||||||
|
key_consumed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!key_consumed && e->matches(QKeySequence::Cancel)) {
|
||||||
d->setCurrentAction(0);
|
d->setCurrentAction(0);
|
||||||
d->setKeyboardMode(false);
|
d->setKeyboardMode(false);
|
||||||
key_consumed = true;
|
key_consumed = true;
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
key_consumed = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!key_consumed &&
|
if(!key_consumed &&
|
||||||
@ -1432,7 +1432,7 @@ bool QMenuBar::event(QEvent *e)
|
|||||||
case QEvent::ShortcutOverride: {
|
case QEvent::ShortcutOverride: {
|
||||||
QKeyEvent *kev = static_cast<QKeyEvent*>(e);
|
QKeyEvent *kev = static_cast<QKeyEvent*>(e);
|
||||||
//we only filter out escape if there is a current action
|
//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();
|
e->accept();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user