diff options
-rw-r--r-- | src/gui/kernel/qguiapplication.cpp | 19 | ||||
-rw-r--r-- | src/gui/kernel/qguiapplication_p.h | 3 | ||||
-rw-r--r-- | src/gui/kernel/qwindowsysteminterface.cpp | 12 | ||||
-rw-r--r-- | src/gui/kernel/qwindowsysteminterface.h | 5 | ||||
-rw-r--r-- | src/gui/kernel/qwindowsysteminterface_p.h | 18 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qtwindowsglobal.h | 5 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowscontext.cpp | 23 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowscontext.h | 3 | ||||
-rw-r--r-- | src/widgets/kernel/qwidgetwindow.cpp | 35 | ||||
-rw-r--r-- | src/widgets/kernel/qwidgetwindow_qpa_p.h | 3 |
10 files changed, 124 insertions, 2 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index a67917ca3b..64d2f8001f 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1211,6 +1211,12 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv QGuiApplicationPrivate::processFileOpenEvent( static_cast<QWindowSystemInterfacePrivate::FileOpenEvent *>(e)); break; +#ifndef QT_NO_CONTEXTMENU + case QWindowSystemInterfacePrivate::ContextMenu: + QGuiApplicationPrivate::processContextMenuEvent( + static_cast<QWindowSystemInterfacePrivate::ContextMenuEvent *>(e)); + break; +#endif default: qWarning() << "Unknown user input event type:" << e->type; break; @@ -1639,6 +1645,19 @@ void QGuiApplicationPrivate::processPlatformPanelEvent(QWindowSystemInterfacePri QGuiApplication::sendSpontaneousEvent(e->window.data(), &ev); } +#ifndef QT_NO_CONTEXTMENU +void QGuiApplicationPrivate::processContextMenuEvent(QWindowSystemInterfacePrivate::ContextMenuEvent *e) +{ + // Widgets do not care about mouse triggered context menu events. Also, do not forward event + // to a window blocked by a modal window. + if (!e->window || e->mouseTriggered || e->window->d_func()->blockedByModalWindow) + return; + + QContextMenuEvent ev(QContextMenuEvent::Keyboard, e->pos, e->globalPos, e->modifiers); + QGuiApplication::sendSpontaneousEvent(e->window.data(), &ev); +} +#endif + Q_GUI_EXPORT uint qHash(const QGuiApplicationPrivate::ActiveTouchPointsKey &k) { return qHash(k.device) + k.touchPointId; diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index 0c81d78f86..44a9275688 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -138,6 +138,9 @@ public: static void processTabletLeaveProximityEvent(QWindowSystemInterfacePrivate::TabletLeaveProximityEvent *e); static void processPlatformPanelEvent(QWindowSystemInterfacePrivate::PlatformPanelEvent *e); +#ifndef QT_NO_CONTEXTMENU + static void processContextMenuEvent(QWindowSystemInterfacePrivate::ContextMenuEvent *e); +#endif #ifndef QT_NO_DRAGANDDROP static QPlatformDragQtResponse processDrag(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions); diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index 82e0e44ac7..6fb10b6c75 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -630,6 +630,18 @@ void QWindowSystemInterface::handlePlatformPanelEvent(QWindow *w) QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } +#ifndef QT_NO_CONTEXTMENU +void QWindowSystemInterface::handleContextMenuEvent(QWindow *w, bool mouseTriggered, + const QPoint &pos, const QPoint &globalPos, + Qt::KeyboardModifiers modifiers) +{ + QWindowSystemInterfacePrivate::ContextMenuEvent *e = + new QWindowSystemInterfacePrivate::ContextMenuEvent(w, mouseTriggered, pos, + globalPos, modifiers); + QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); +} +#endif + Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier) { QWindowSystemInterface::handleMouseEvent(w, local, global, b, mods); } diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h index 74b5a136f4..b4b2e845fc 100644 --- a/src/gui/kernel/qwindowsysteminterface.h +++ b/src/gui/kernel/qwindowsysteminterface.h @@ -175,6 +175,11 @@ public: static void handleTabletLeaveProximityEvent(int device, int pointerType, qint64 uid); static void handlePlatformPanelEvent(QWindow *w); +#ifndef QT_NO_CONTEXTMENU + static void handleContextMenuEvent(QWindow *w, bool mouseTriggered, + const QPoint &pos, const QPoint &globalPos, + Qt::KeyboardModifiers modifiers); +#endif // For event dispatcher implementations static bool sendWindowSystemEvents(QEventLoop::ProcessEventsFlags flags); diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h index 4e907f3f51..1b5351db71 100644 --- a/src/gui/kernel/qwindowsysteminterface_p.h +++ b/src/gui/kernel/qwindowsysteminterface_p.h @@ -77,7 +77,8 @@ public: Tablet, TabletEnterProximity, TabletLeaveProximity, - PlatformPanel + PlatformPanel, + ContextMenu }; class WindowSystemEvent { @@ -333,6 +334,21 @@ public: QPointer<QWindow> window; }; +#ifndef QT_NO_CONTEXTMENU + class ContextMenuEvent : public WindowSystemEvent { + public: + explicit ContextMenuEvent(QWindow *w, bool mouseTriggered, const QPoint &pos, + const QPoint &globalPos, Qt::KeyboardModifiers modifiers) + : WindowSystemEvent(ContextMenu), window(w), mouseTriggered(mouseTriggered), pos(pos), + globalPos(globalPos), modifiers(modifiers) { } + QPointer<QWindow> window; + bool mouseTriggered; + QPoint pos; // Only valid if triggered by mouse + QPoint globalPos; // Only valid if triggered by mouse + Qt::KeyboardModifiers modifiers; + }; +#endif + class WindowSystemEventList { QList<WindowSystemEvent *> impl; mutable QMutex mutex; diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h index 73f963b6b8..7ff8edb588 100644 --- a/src/plugins/platforms/windows/qtwindowsglobal.h +++ b/src/plugins/platforms/windows/qtwindowsglobal.h @@ -105,6 +105,7 @@ enum WindowsEventType // Simplify event types ThemeChanged = ThemingEventFlag + 1, DisplayChangedEvent = 437, SettingChangedEvent = DisplayChangedEvent + 1, + ContextMenu = 123, UnknownEvent = 542 }; @@ -194,6 +195,10 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI return QtWindows::DisplayChangedEvent; case WM_THEMECHANGED: return QtWindows::ThemeChanged; +#ifndef QT_NO_CONTEXTMENU + case WM_CONTEXTMENU: + return QtWindows::ContextMenu; +#endif default: break; } diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 3d4871d7a2..42db58ae6c 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -869,6 +869,11 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, QWindowsWindow::baseWindowOf(modalWindow)->alertWindow(); break; #endif +#ifndef QT_NO_CONTEXTMENU + case QtWindows::ContextMenu: + handleContextMenuEvent(platformWindow->window(), msg); + return true; +#endif default: break; } @@ -900,6 +905,24 @@ void QWindowsContext::handleFocusEvent(QtWindows::WindowsEventType et, } } +#ifndef QT_NO_CONTEXTMENU +void QWindowsContext::handleContextMenuEvent(QWindow *window, const MSG &msg) +{ + bool mouseTriggered = false; + QPoint globalPos; + QPoint pos; + if (msg.lParam != (int)0xffffffff) { + mouseTriggered = true; + globalPos.setX(msg.pt.x); + globalPos.setY(msg.pt.y); + pos = QWindowsGeometryHint::mapFromGlobal(msg.hwnd, globalPos); + } + + QWindowSystemInterface::handleContextMenuEvent(window, mouseTriggered, pos, globalPos, + QWindowsKeyMapper::queryKeyboardModifiers()); +} +#endif + /*! \brief Windows functions for actual windows. diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h index dcc636bfc0..ef48a52e07 100644 --- a/src/plugins/platforms/windows/qwindowscontext.h +++ b/src/plugins/platforms/windows/qwindowscontext.h @@ -187,6 +187,9 @@ public: private: void handleFocusEvent(QtWindows::WindowsEventType et, QWindowsWindow *w); +#ifndef QT_NO_CONTEXTMENU + void handleContextMenuEvent(QWindow *window, const MSG &msg); +#endif void unregisterWindowClasses(); QScopedPointer<QWindowsContextPrivate> d; diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 5f25e1274e..900818d5c6 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -200,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; } @@ -618,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(); diff --git a/src/widgets/kernel/qwidgetwindow_qpa_p.h b/src/widgets/kernel/qwidgetwindow_qpa_p.h index 80aa022ce2..e832249107 100644 --- a/src/widgets/kernel/qwidgetwindow_qpa_p.h +++ b/src/widgets/kernel/qwidgetwindow_qpa_p.h @@ -92,6 +92,9 @@ protected: #ifndef QT_NO_TABLETEVENT void handleTabletEvent(QTabletEvent *); #endif +#ifndef QT_NO_CONTEXTMENU + void handleContextMenuEvent(QContextMenuEvent *); +#endif private slots: void updateObjectName(); |