From 870f19f44b1eb2b93c7151dd48b8d9cd471acae8 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 27 Jan 2012 14:09:36 +0100 Subject: Add native event filters to Windows, forward to Widgets. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use prototypically for qwizard_win.cpp. Change-Id: I075e81ae1bc3d62d9f27e51c73c800ffd71cbcd6 Reviewed-by: Samuel Rødal --- src/gui/kernel/qguiapplication.cpp | 5 ++ src/gui/kernel/qguiapplication_p.h | 2 + src/gui/kernel/qwindow.cpp | 8 ++ src/gui/kernel/qwindow.h | 1 + src/gui/kernel/qwindowsysteminterface_qpa.cpp | 24 +++++ src/gui/kernel/qwindowsysteminterface_qpa.h | 2 + src/plugins/platforms/windows/qwindowscontext.cpp | 14 ++- src/widgets/dialogs/qwizard.cpp | 13 +-- src/widgets/dialogs/qwizard.h | 4 +- src/widgets/dialogs/qwizard_win.cpp | 17 ++-- src/widgets/graphicsview/qgraphicswidget.h | 4 - src/widgets/kernel/qwidget.cpp | 105 ++++------------------ src/widgets/kernel/qwidget.h | 14 +-- src/widgets/kernel/qwidgetwindow_qpa.cpp | 5 ++ src/widgets/kernel/qwidgetwindow_qpa_p.h | 1 + 15 files changed, 93 insertions(+), 126 deletions(-) (limited to 'src') diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 093151707c..1ba6d67742 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -571,6 +571,11 @@ bool QGuiApplication::compressEvent(QEvent *event, QObject *receiver, QPostEvent return QCoreApplication::compressEvent(event, receiver, postedEvents); } +bool QGuiApplicationPrivate::processNativeEvent(QWindow *window, const QByteArray &eventType, void *message, long *result) +{ + return window->nativeEvent(eventType, message, result); +} + void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e) { switch(e->type) { diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index ed21eecca3..baa74df009 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -135,6 +135,8 @@ public: static Qt::DropAction processDrag(QWindow *w, QMimeData *dropData, const QPoint &p); static Qt::DropAction processDrop(QWindow *w, QMimeData *dropData, const QPoint &p); + static bool processNativeEvent(QWindow *window, const QByteArray &eventType, void *message, long *result); + static inline Qt::Alignment visualAlignment(Qt::LayoutDirection direction, Qt::Alignment alignment) { if (!(alignment & Qt::AlignHorizontal_Mask)) diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index d6194b5607..e85d8379fa 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -1035,6 +1035,14 @@ void QWindow::touchEvent(QTouchEvent *ev) ev->ignore(); } +bool QWindow::nativeEvent(const QByteArray &eventType, void *message, long *result) +{ + Q_UNUSED(eventType); + Q_UNUSED(message); + Q_UNUSED(result); + return false; +} + /*! \fn QPoint QWindow::mapToGlobal(const QPoint &pos) const diff --git a/src/gui/kernel/qwindow.h b/src/gui/kernel/qwindow.h index 0342f9b669..4e6a8591d8 100644 --- a/src/gui/kernel/qwindow.h +++ b/src/gui/kernel/qwindow.h @@ -288,6 +288,7 @@ protected: virtual void wheelEvent(QWheelEvent *); #endif virtual void touchEvent(QTouchEvent *); + virtual bool nativeEvent(const QByteArray &eventType, void *message, long *result); QWindow(QWindowPrivate &dd, QWindow *parent); diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.cpp b/src/gui/kernel/qwindowsysteminterface_qpa.cpp index 999e1a67d1..ae94b75076 100644 --- a/src/gui/kernel/qwindowsysteminterface_qpa.cpp +++ b/src/gui/kernel/qwindowsysteminterface_qpa.cpp @@ -60,6 +60,17 @@ QMutex QWindowSystemInterfacePrivate::queueMutex; extern QPointer qt_last_mouse_receiver; +/*! + \class QWindowSystemInterface + \since 5.0 + \internal + \preliminary + \ingroup qpa + \brief The QWindowSystemInterface provides an event queue for the QPA platform. + + The platform plugins call the various functions to notify about events. The events are queued + until sendWindowSystemEvents() is called by the event dispatcher. +*/ void QWindowSystemInterface::handleEnterEvent(QWindow *tlw) { @@ -379,4 +390,17 @@ Qt::DropAction QWindowSystemInterface::handleDrop(QWindow *w, QMimeData *dropDat return QGuiApplicationPrivate::processDrop(w, dropData, p); } +/*! + \fn static QWindowSystemInterface::handleNativeEvent(QWindow *window, const QByteArray &eventType, void *message, long *result) + \brief Passes a native event identified by \a eventType to the \a window. + + \note This function can only be called from the GUI thread. + \sa QPlatformNativeInterface::setEventFilter() +*/ + +bool QWindowSystemInterface::handleNativeEvent(QWindow *window, const QByteArray &eventType, void *message, long *result) +{ + return QGuiApplicationPrivate::processNativeEvent(window, eventType, message, result); +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.h b/src/gui/kernel/qwindowsysteminterface_qpa.h index 66d55c9884..b99363eda7 100644 --- a/src/gui/kernel/qwindowsysteminterface_qpa.h +++ b/src/gui/kernel/qwindowsysteminterface_qpa.h @@ -120,6 +120,8 @@ public: static Qt::DropAction handleDrag(QWindow *w, QMimeData *dropData, const QPoint &p); static Qt::DropAction handleDrop(QWindow *w, QMimeData *dropData, const QPoint &p); + static bool handleNativeEvent(QWindow *window, const QByteArray &eventType, void *message, long *result); + // Changes to the screen static void handleScreenOrientationChange(QScreen *screen, Qt::ScreenOrientation newOrientation); static void handleScreenGeometryChange(QScreen *screen, const QRect &newGeometry); diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 30c4c0818a..02411d3daf 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -241,6 +241,7 @@ struct QWindowsContextPrivate { QWindowsScreenManager m_screenManager; QSharedPointer m_creationContext; const HRESULT m_oleInitializeResult; + const QByteArray m_eventType; EventFilter m_eventFilters[EventFilterTypeCount]; }; @@ -248,7 +249,8 @@ QWindowsContextPrivate::QWindowsContextPrivate() : m_systemInfo(0), m_displayContext(GetDC(0)), m_defaultDPI(GetDeviceCaps(m_displayContext,LOGPIXELSY)), - m_oleInitializeResult(OleInitialize(NULL)) + m_oleInitializeResult(OleInitialize(NULL)), + m_eventType(QByteArrayLiteral("windows_generic_MSG")) { QWindowsContext::user32dll.init(); QWindowsContext::shell32dll.init(); @@ -633,7 +635,7 @@ QByteArray QWindowsContext::comErrorString(HRESULT hr) QWindowsContext::EventFilter QWindowsContext::setEventFilter(const QByteArray &eventType, EventFilter filter) { int eventFilterType = -1; - if (eventType == QByteArrayLiteral("windows_generic_MSG")) + if (eventType == d->m_eventType) eventFilterType = QWindowsContextPrivate::GenericWindowsEventFilter; if (eventFilterType < 0) { qWarning("%s: Attempt to set unsupported event filter '%s'.", @@ -665,8 +667,8 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, msg.pt.x = GET_X_LPARAM(lParam); msg.pt.y = GET_Y_LPARAM(lParam); + long filterResult = 0; if (d->m_eventFilters[QWindowsContextPrivate::GenericWindowsEventFilter]) { - long filterResult = 0; if (d->m_eventFilters[QWindowsContextPrivate::GenericWindowsEventFilter](&msg, &filterResult)) { *result = LRESULT(filterResult); return true; @@ -734,6 +736,12 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, return false; } + filterResult = 0; + if (QWindowSystemInterface::handleNativeEvent(platformWindow->window(), d->m_eventType, &msg, &filterResult)) { + *result = LRESULT(filterResult); + return true; + } + switch (et) { case QtWindows::KeyDownEvent: case QtWindows::KeyEvent: diff --git a/src/widgets/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp index 2c56ffc391..4e707ab7c1 100644 --- a/src/widgets/dialogs/qwizard.cpp +++ b/src/widgets/dialogs/qwizard.cpp @@ -3205,16 +3205,17 @@ void QWizard::paintEvent(QPaintEvent * event) #endif } -#if defined(Q_WS_WIN) +#if defined(Q_OS_WIN) /*! \reimp */ -bool QWizard::winEvent(MSG *message, long *result) +bool QWizard::nativeEvent(const QByteArray &eventType, void *message, long *result) { #if !defined(QT_NO_STYLE_WINDOWSVISTA) Q_D(QWizard); - if (d->isVistaThemeEnabled()) { - const bool winEventResult = d->vistaHelper->handleWinEvent(message, result); + if (d->isVistaThemeEnabled() && eventType == QByteArrayLiteral("windows_generic_MSG")) { + MSG *windowsMessage = static_cast(message); + const bool winEventResult = d->vistaHelper->handleWinEvent(windowsMessage, result); if (QVistaHelper::vistaState() != d->vistaState) { d->vistaState = QVistaHelper::vistaState(); d->vistaStateChanged = true; @@ -3222,10 +3223,10 @@ bool QWizard::winEvent(MSG *message, long *result) } return winEventResult; } else { - return QDialog::winEvent(message, result); + return QDialog::nativeEvent(eventType, message, result); } #else - return QDialog::winEvent(message, result); + return QDialog::nativeEvent(eventType, message, result); #endif } #endif diff --git a/src/widgets/dialogs/qwizard.h b/src/widgets/dialogs/qwizard.h index cd8920671f..caa9d5e648 100644 --- a/src/widgets/dialogs/qwizard.h +++ b/src/widgets/dialogs/qwizard.h @@ -189,8 +189,8 @@ protected: bool event(QEvent *event); void resizeEvent(QResizeEvent *event); void paintEvent(QPaintEvent *event); -#if defined(Q_WS_WIN) - bool winEvent(MSG * message, long * result); +#ifdef Q_OS_WIN + bool nativeEvent(const QByteArray &eventType, void * message, long * result); #endif void done(int result); virtual void initializePage(int id); diff --git a/src/widgets/dialogs/qwizard_win.cpp b/src/widgets/dialogs/qwizard_win.cpp index 3efd8274bd..d60a47f2c2 100644 --- a/src/widgets/dialogs/qwizard_win.cpp +++ b/src/widgets/dialogs/qwizard_win.cpp @@ -399,12 +399,13 @@ bool QVistaHelper::winEvent(MSG* msg, long* result) *result = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam); break; } - case WM_NCCALCSIZE: { - NCCALCSIZE_PARAMS* lpncsp = (NCCALCSIZE_PARAMS*)msg->lParam; - *result = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam); - lpncsp->rgrc[0].top -= (vistaState() == VistaAero ? titleBarSize() : 0); - break; - } +// case WM_NCCALCSIZE: { #fixme: If the frame size is changed, it needs to be communicated to the QWindow. +// NCCALCSIZE_PARAMS* lpncsp = (NCCALCSIZE_PARAMS*)msg->lParam; +// *result = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam); +// lpncsp->rgrc[0].top -= (vistaState() == VistaAero ? titleBarSize() : 0); +// +// break; +// } default: retval = false; } @@ -480,8 +481,8 @@ bool QVistaHelper::handleWinEvent(MSG *message, long *result) if (wizard->wizardStyle() == QWizard::AeroStyle && vistaState() == VistaAero) { status = winEvent(message, result); if (message->message == WM_NCCALCSIZE) { - if (status) - collapseTopFrameStrut(); +// if (status) #fixme +// collapseTopFrameStrut(); } else if (message->message == WM_NCPAINT) { wizard->update(); } diff --git a/src/widgets/graphicsview/qgraphicswidget.h b/src/widgets/graphicsview/qgraphicswidget.h index c073de32ef..e0bb591231 100644 --- a/src/widgets/graphicsview/qgraphicswidget.h +++ b/src/widgets/graphicsview/qgraphicswidget.h @@ -211,17 +211,13 @@ protected: virtual bool focusNextPrevChild(bool next); void focusOutEvent(QFocusEvent *event); virtual void hideEvent(QHideEvent *event); - //virtual bool macEvent(EventHandlerCallRef caller, EventRef event); //virtual int metric(PaintDeviceMetric m ) const; virtual void moveEvent(QGraphicsSceneMoveEvent *event); virtual void polishEvent(); - //virtual bool qwsEvent(QWSEvent *event); //void resetInputContext (); virtual void resizeEvent(QGraphicsSceneResizeEvent *event); virtual void showEvent(QShowEvent *event); //virtual void tabletEvent(QTabletEvent *event); - //virtual bool winEvent(MSG *message, long *result); - //virtual bool x11Event(XEvent *event); virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event); virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); virtual void grabMouseEvent(QEvent *event); diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index af3941c231..4402b497ad 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -8963,111 +8963,36 @@ void QWidget::hideEvent(QHideEvent *) { } -/* - \fn QWidget::x11Event(MSG *) - - This special event handler can be reimplemented in a subclass to receive - native X11 events. - - In your reimplementation of this function, if you want to stop Qt from - handling the event, return true. If you return false, this native event - is passed back to Qt, which translates it into a Qt event and sends it to - the widget. - - \note Events are only delivered to this event handler if the widget is - native. - - \warning This function is not portable. - - \sa QApplication::x11EventFilter(), QWidget::winId() -*/ - - -#if defined(Q_WS_MAC) - /*! - \fn bool QWidget::macEvent(EventHandlerCallRef caller, EventRef event) - This special event handler can be reimplemented in a subclass to - receive native Macintosh events. - - The parameters are a bit different depending if Qt is build against Carbon - or Cocoa. In Carbon, \a caller and \a event are the corresponding - EventHandlerCallRef and EventRef that correspond to the Carbon event - handlers that are installed. In Cocoa, \a caller is always 0 and the - EventRef is the EventRef generated from the NSEvent. + receive native platform events identified by \a eventType + which are passed in the \a message parameter. In your reimplementation of this function, if you want to stop the - event being handled by Qt, return true. If you return false, this - native event is passed back to Qt, which translates the event into - a Qt event and sends it to the widget. + event being handled by Qt, return true and set \a result. + If you return false, this native event is passed back to Qt, + which translates the event into a Qt event and sends it to the widget. - \warning This function is not portable. + \note Events are only delivered to this event handler if the widget is + has a native Window handle. - \warning This function was not called inside of Qt until Qt 4.4. - If you need compatibility with earlier versions of Qt, consider QApplication::macEventFilter() instead. + \note This function superseedes the event filter functions + x11Event(), winEvent() and macEvent() of Qt 4. - \sa QApplication::macEventFilter() + \table + \header \i Platform \i Event Type Identifier \i Message Type \i Result Type + \row \i Windows \i "windows_generic_MSG" \i MSG * \i LRESULT + \endtable */ -bool QWidget::macEvent(EventHandlerCallRef, EventRef) -{ - return false; -} - -#endif -#if defined(Q_WS_WIN) - -/*! - This special event handler can be reimplemented in a subclass to - receive native Windows events which are passed in the \a message - parameter. - - In your reimplementation of this function, if you want to stop the - event being handled by Qt, return true and set \a result to the value - that the window procedure should return. If you return false, this - native event is passed back to Qt, which translates the event into - a Qt event and sends it to the widget. - - \warning This function is not portable. - - \sa QApplication::winEventFilter() -*/ -bool QWidget::winEvent(MSG *message, long *result) +bool QWidget::nativeEvent(const QByteArray &eventType, void *message, long *result) { + Q_UNUSED(eventType); Q_UNUSED(message); Q_UNUSED(result); return false; } -#endif -#if defined(Q_WS_X11) - -/*! - \fn bool QWidget::x11Event(XEvent *event) - - This special event handler can be reimplemented in a subclass to receive - native X11 events passed in the \a event parameter. - - In your reimplementation of this function, if you want to stop Qt from - handling the event, return true. If you return false, this native event - is passed back to Qt, which translates it into a Qt event and sends it to - the widget. - - \note Events are only delivered to this event handler if the widget is - native. - - \warning This function is not portable. - - \sa QApplication::x11EventFilter(), QWidget::winId() -*/ -bool QWidget::x11Event(XEvent *) -{ - return false; -} - -#endif - /*! Ensures that the widget has been polished by QStyle (i.e., has a proper font and palette). diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h index f21b2118a4..f24941d856 100644 --- a/src/widgets/kernel/qwidget.h +++ b/src/widgets/kernel/qwidget.h @@ -660,19 +660,7 @@ protected: virtual void showEvent(QShowEvent *); virtual void hideEvent(QHideEvent *); - -#if defined(Q_WS_MAC) - virtual bool macEvent(EventHandlerCallRef, EventRef); -#endif -#if defined(Q_WS_WIN) - virtual bool winEvent(MSG *message, long *result); -#endif -#if defined(Q_WS_X11) - virtual bool x11Event(XEvent *); -#endif -#if defined(Q_WS_QWS) - virtual bool qwsEvent(QWSEvent *); -#endif + virtual bool nativeEvent(const QByteArray &eventType, void *message, long *result); // Misc. protected functions virtual void changeEvent(QEvent *); diff --git a/src/widgets/kernel/qwidgetwindow_qpa.cpp b/src/widgets/kernel/qwidgetwindow_qpa.cpp index e546df755d..e7ba4853a0 100644 --- a/src/widgets/kernel/qwidgetwindow_qpa.cpp +++ b/src/widgets/kernel/qwidgetwindow_qpa.cpp @@ -431,4 +431,9 @@ void QWidgetWindow::handleWindowStateChangedEvent(QWindowStateChangeEvent *event QGuiApplication::sendSpontaneousEvent(m_widget, &widgetEvent); } +bool QWidgetWindow::nativeEvent(const QByteArray &eventType, void *message, long *result) +{ + return m_widget->nativeEvent(eventType, message, result); +} + QT_END_NAMESPACE diff --git a/src/widgets/kernel/qwidgetwindow_qpa_p.h b/src/widgets/kernel/qwidgetwindow_qpa_p.h index d7fdb5d4de..1e8813fddc 100644 --- a/src/widgets/kernel/qwidgetwindow_qpa_p.h +++ b/src/widgets/kernel/qwidgetwindow_qpa_p.h @@ -79,6 +79,7 @@ protected: void handleDragEvent(QEvent *); void handleExposeEvent(QExposeEvent *); void handleWindowStateChangedEvent(QWindowStateChangeEvent *event); + bool nativeEvent(const QByteArray &eventType, void *message, long *result); private: void updateGeometry(); -- cgit v1.2.3