diff options
Diffstat (limited to 'src/widgets/kernel/qwidgetwindow.cpp')
-rw-r--r-- | src/widgets/kernel/qwidgetwindow.cpp | 62 |
1 files changed, 59 insertions, 3 deletions
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 10ec4d3745..900818d5c6 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -47,6 +47,7 @@ #include <QtGui/qaccessible.h> #endif #include <private/qwidgetbackingstore_p.h> +#include <qpa/qwindowsysteminterface_p.h> QT_BEGIN_NAMESPACE @@ -199,7 +200,11 @@ bool QWidgetWindow::event(QEvent *event) handleTabletEvent(static_cast<QTabletEvent *>(event)); return true; #endif - +#ifndef QT_NO_CONTEXTMENU + case QEvent::ContextMenu: + handleContextMenuEvent(static_cast<QContextMenuEvent *>(event)); + return true; +#endif default: break; } @@ -212,9 +217,31 @@ QPointer<QWidget> qt_last_mouse_receiver = 0; void QWidgetWindow::handleEnterLeaveEvent(QEvent *event) { if (event->type() == QEvent::Leave) { + QWidget *enter = 0; + // Check from window system event queue if the next queued enter targets a window + // in the same window hierarchy (e.g. enter a child of this window). If so, + // remove the enter event from queue and handle both in single dispatch. + QWindowSystemInterfacePrivate::EnterEvent *systemEvent = + static_cast<QWindowSystemInterfacePrivate::EnterEvent *> + (QWindowSystemInterfacePrivate::peekWindowSystemEvent(QWindowSystemInterfacePrivate::Enter)); + if (systemEvent) { + if (QWidgetWindow *enterWindow = qobject_cast<QWidgetWindow *>(systemEvent->enter)) + { + QWindow *thisParent = this; + QWindow *enterParent = enterWindow; + while (thisParent->parent()) + thisParent = thisParent->parent(); + while (enterParent->parent()) + enterParent = enterParent->parent(); + if (thisParent == enterParent) { + enter = enterWindow->widget(); + QWindowSystemInterfacePrivate::removeWindowSystemEvent(systemEvent); + } + } + } QWidget *leave = qt_last_mouse_receiver ? qt_last_mouse_receiver.data() : m_widget; - QApplicationPrivate::dispatchEnterLeave(0, leave); - qt_last_mouse_receiver = 0; + QApplicationPrivate::dispatchEnterLeave(enter, leave); + qt_last_mouse_receiver = enter; } else { QApplicationPrivate::dispatchEnterLeave(m_widget, 0); qt_last_mouse_receiver = m_widget; @@ -595,6 +622,35 @@ void QWidgetWindow::handleTabletEvent(QTabletEvent *event) } #endif // QT_NO_TABLETEVENT +#ifndef QT_NO_CONTEXTMENU +void QWidgetWindow::handleContextMenuEvent(QContextMenuEvent *e) +{ + // We are only interested in keyboard originating context menu events here, + // mouse originated context menu events for widgets are generated in mouse handling methods. + if (e->reason() != QContextMenuEvent::Keyboard) + return; + + QWidget *fw = QWidget::keyboardGrabber(); + if (!fw) { + if (QApplication::activePopupWidget()) { + fw = (QApplication::activePopupWidget()->focusWidget() + ? QApplication::activePopupWidget()->focusWidget() + : QApplication::activePopupWidget()); + } else if (QApplication::focusWidget()) { + fw = QApplication::focusWidget(); + } else { + fw = m_widget; + } + } + if (fw && fw->isEnabled()) { + QPoint pos = fw->inputMethodQuery(Qt::ImMicroFocus).toRect().center(); + QContextMenuEvent widgetEvent(QContextMenuEvent::Keyboard, pos, fw->mapToGlobal(pos), + e->modifiers()); + QGuiApplication::sendSpontaneousEvent(fw, &widgetEvent); + } +} +#endif // QT_NO_CONTEXTMENU + void QWidgetWindow::updateObjectName() { QString name = m_widget->objectName(); |