Add native event filters to Windows, forward to Widgets.

Use prototypically for qwizard_win.cpp.

Change-Id: I075e81ae1bc3d62d9f27e51c73c800ffd71cbcd6
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
This commit is contained in:
Friedemann Kleint 2012-01-27 14:09:36 +01:00 committed by Qt by Nokia
parent b3a978d661
commit 870f19f44b
15 changed files with 95 additions and 128 deletions

View File

@ -571,6 +571,11 @@ bool QGuiApplication::compressEvent(QEvent *event, QObject *receiver, QPostEvent
return QCoreApplication::compressEvent(event, receiver, postedEvents); 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) void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e)
{ {
switch(e->type) { switch(e->type) {

View File

@ -135,6 +135,8 @@ public:
static Qt::DropAction processDrag(QWindow *w, QMimeData *dropData, const QPoint &p); static Qt::DropAction processDrag(QWindow *w, QMimeData *dropData, const QPoint &p);
static Qt::DropAction processDrop(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) static inline Qt::Alignment visualAlignment(Qt::LayoutDirection direction, Qt::Alignment alignment)
{ {
if (!(alignment & Qt::AlignHorizontal_Mask)) if (!(alignment & Qt::AlignHorizontal_Mask))

View File

@ -1035,6 +1035,14 @@ void QWindow::touchEvent(QTouchEvent *ev)
ev->ignore(); 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 \fn QPoint QWindow::mapToGlobal(const QPoint &pos) const

View File

@ -288,6 +288,7 @@ protected:
virtual void wheelEvent(QWheelEvent *); virtual void wheelEvent(QWheelEvent *);
#endif #endif
virtual void touchEvent(QTouchEvent *); virtual void touchEvent(QTouchEvent *);
virtual bool nativeEvent(const QByteArray &eventType, void *message, long *result);
QWindow(QWindowPrivate &dd, QWindow *parent); QWindow(QWindowPrivate &dd, QWindow *parent);

View File

@ -60,6 +60,17 @@ QMutex QWindowSystemInterfacePrivate::queueMutex;
extern QPointer<QWindow> qt_last_mouse_receiver; extern QPointer<QWindow> 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) void QWindowSystemInterface::handleEnterEvent(QWindow *tlw)
{ {
@ -379,4 +390,17 @@ Qt::DropAction QWindowSystemInterface::handleDrop(QWindow *w, QMimeData *dropDat
return QGuiApplicationPrivate::processDrop(w, dropData, p); 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 QT_END_NAMESPACE

View File

@ -120,6 +120,8 @@ public:
static Qt::DropAction handleDrag(QWindow *w, QMimeData *dropData, const QPoint &p); static Qt::DropAction handleDrag(QWindow *w, QMimeData *dropData, const QPoint &p);
static Qt::DropAction handleDrop(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 // Changes to the screen
static void handleScreenOrientationChange(QScreen *screen, Qt::ScreenOrientation newOrientation); static void handleScreenOrientationChange(QScreen *screen, Qt::ScreenOrientation newOrientation);
static void handleScreenGeometryChange(QScreen *screen, const QRect &newGeometry); static void handleScreenGeometryChange(QScreen *screen, const QRect &newGeometry);

View File

@ -241,6 +241,7 @@ struct QWindowsContextPrivate {
QWindowsScreenManager m_screenManager; QWindowsScreenManager m_screenManager;
QSharedPointer<QWindowCreationContext> m_creationContext; QSharedPointer<QWindowCreationContext> m_creationContext;
const HRESULT m_oleInitializeResult; const HRESULT m_oleInitializeResult;
const QByteArray m_eventType;
EventFilter m_eventFilters[EventFilterTypeCount]; EventFilter m_eventFilters[EventFilterTypeCount];
}; };
@ -248,7 +249,8 @@ QWindowsContextPrivate::QWindowsContextPrivate() :
m_systemInfo(0), m_systemInfo(0),
m_displayContext(GetDC(0)), m_displayContext(GetDC(0)),
m_defaultDPI(GetDeviceCaps(m_displayContext,LOGPIXELSY)), m_defaultDPI(GetDeviceCaps(m_displayContext,LOGPIXELSY)),
m_oleInitializeResult(OleInitialize(NULL)) m_oleInitializeResult(OleInitialize(NULL)),
m_eventType(QByteArrayLiteral("windows_generic_MSG"))
{ {
QWindowsContext::user32dll.init(); QWindowsContext::user32dll.init();
QWindowsContext::shell32dll.init(); QWindowsContext::shell32dll.init();
@ -633,7 +635,7 @@ QByteArray QWindowsContext::comErrorString(HRESULT hr)
QWindowsContext::EventFilter QWindowsContext::setEventFilter(const QByteArray &eventType, EventFilter filter) QWindowsContext::EventFilter QWindowsContext::setEventFilter(const QByteArray &eventType, EventFilter filter)
{ {
int eventFilterType = -1; int eventFilterType = -1;
if (eventType == QByteArrayLiteral("windows_generic_MSG")) if (eventType == d->m_eventType)
eventFilterType = QWindowsContextPrivate::GenericWindowsEventFilter; eventFilterType = QWindowsContextPrivate::GenericWindowsEventFilter;
if (eventFilterType < 0) { if (eventFilterType < 0) {
qWarning("%s: Attempt to set unsupported event filter '%s'.", 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.x = GET_X_LPARAM(lParam);
msg.pt.y = GET_Y_LPARAM(lParam); msg.pt.y = GET_Y_LPARAM(lParam);
long filterResult = 0;
if (d->m_eventFilters[QWindowsContextPrivate::GenericWindowsEventFilter]) { if (d->m_eventFilters[QWindowsContextPrivate::GenericWindowsEventFilter]) {
long filterResult = 0;
if (d->m_eventFilters[QWindowsContextPrivate::GenericWindowsEventFilter](&msg, &filterResult)) { if (d->m_eventFilters[QWindowsContextPrivate::GenericWindowsEventFilter](&msg, &filterResult)) {
*result = LRESULT(filterResult); *result = LRESULT(filterResult);
return true; return true;
@ -734,6 +736,12 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
return false; return false;
} }
filterResult = 0;
if (QWindowSystemInterface::handleNativeEvent(platformWindow->window(), d->m_eventType, &msg, &filterResult)) {
*result = LRESULT(filterResult);
return true;
}
switch (et) { switch (et) {
case QtWindows::KeyDownEvent: case QtWindows::KeyDownEvent:
case QtWindows::KeyEvent: case QtWindows::KeyEvent:

View File

@ -3205,16 +3205,17 @@ void QWizard::paintEvent(QPaintEvent * event)
#endif #endif
} }
#if defined(Q_WS_WIN) #if defined(Q_OS_WIN)
/*! /*!
\reimp \reimp
*/ */
bool QWizard::winEvent(MSG *message, long *result) bool QWizard::nativeEvent(const QByteArray &eventType, void *message, long *result)
{ {
#if !defined(QT_NO_STYLE_WINDOWSVISTA) #if !defined(QT_NO_STYLE_WINDOWSVISTA)
Q_D(QWizard); Q_D(QWizard);
if (d->isVistaThemeEnabled()) { if (d->isVistaThemeEnabled() && eventType == QByteArrayLiteral("windows_generic_MSG")) {
const bool winEventResult = d->vistaHelper->handleWinEvent(message, result); MSG *windowsMessage = static_cast<MSG *>(message);
const bool winEventResult = d->vistaHelper->handleWinEvent(windowsMessage, result);
if (QVistaHelper::vistaState() != d->vistaState) { if (QVistaHelper::vistaState() != d->vistaState) {
d->vistaState = QVistaHelper::vistaState(); d->vistaState = QVistaHelper::vistaState();
d->vistaStateChanged = true; d->vistaStateChanged = true;
@ -3222,10 +3223,10 @@ bool QWizard::winEvent(MSG *message, long *result)
} }
return winEventResult; return winEventResult;
} else { } else {
return QDialog::winEvent(message, result); return QDialog::nativeEvent(eventType, message, result);
} }
#else #else
return QDialog::winEvent(message, result); return QDialog::nativeEvent(eventType, message, result);
#endif #endif
} }
#endif #endif

View File

@ -189,8 +189,8 @@ protected:
bool event(QEvent *event); bool event(QEvent *event);
void resizeEvent(QResizeEvent *event); void resizeEvent(QResizeEvent *event);
void paintEvent(QPaintEvent *event); void paintEvent(QPaintEvent *event);
#if defined(Q_WS_WIN) #ifdef Q_OS_WIN
bool winEvent(MSG * message, long * result); bool nativeEvent(const QByteArray &eventType, void * message, long * result);
#endif #endif
void done(int result); void done(int result);
virtual void initializePage(int id); virtual void initializePage(int id);

View File

@ -399,12 +399,13 @@ bool QVistaHelper::winEvent(MSG* msg, long* result)
*result = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam); *result = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
break; break;
} }
case WM_NCCALCSIZE: { // 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; // NCCALCSIZE_PARAMS* lpncsp = (NCCALCSIZE_PARAMS*)msg->lParam;
*result = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam); // *result = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
lpncsp->rgrc[0].top -= (vistaState() == VistaAero ? titleBarSize() : 0); // lpncsp->rgrc[0].top -= (vistaState() == VistaAero ? titleBarSize() : 0);
break; //
} // break;
// }
default: default:
retval = false; retval = false;
} }
@ -480,8 +481,8 @@ bool QVistaHelper::handleWinEvent(MSG *message, long *result)
if (wizard->wizardStyle() == QWizard::AeroStyle && vistaState() == VistaAero) { if (wizard->wizardStyle() == QWizard::AeroStyle && vistaState() == VistaAero) {
status = winEvent(message, result); status = winEvent(message, result);
if (message->message == WM_NCCALCSIZE) { if (message->message == WM_NCCALCSIZE) {
if (status) // if (status) #fixme
collapseTopFrameStrut(); // collapseTopFrameStrut();
} else if (message->message == WM_NCPAINT) { } else if (message->message == WM_NCPAINT) {
wizard->update(); wizard->update();
} }

View File

@ -211,17 +211,13 @@ protected:
virtual bool focusNextPrevChild(bool next); virtual bool focusNextPrevChild(bool next);
void focusOutEvent(QFocusEvent *event); void focusOutEvent(QFocusEvent *event);
virtual void hideEvent(QHideEvent *event); virtual void hideEvent(QHideEvent *event);
//virtual bool macEvent(EventHandlerCallRef caller, EventRef event);
//virtual int metric(PaintDeviceMetric m ) const; //virtual int metric(PaintDeviceMetric m ) const;
virtual void moveEvent(QGraphicsSceneMoveEvent *event); virtual void moveEvent(QGraphicsSceneMoveEvent *event);
virtual void polishEvent(); virtual void polishEvent();
//virtual bool qwsEvent(QWSEvent *event);
//void resetInputContext (); //void resetInputContext ();
virtual void resizeEvent(QGraphicsSceneResizeEvent *event); virtual void resizeEvent(QGraphicsSceneResizeEvent *event);
virtual void showEvent(QShowEvent *event); virtual void showEvent(QShowEvent *event);
//virtual void tabletEvent(QTabletEvent *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 hoverMoveEvent(QGraphicsSceneHoverEvent *event);
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
virtual void grabMouseEvent(QEvent *event); virtual void grabMouseEvent(QEvent *event);

View File

@ -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 platform events identified by \a eventType
which are passed in the \a message parameter.
This special event handler can be reimplemented in a subclass to receive In your reimplementation of this function, if you want to stop the
native X11 events. event being handled by Qt, return true and set \a result.
If you return false, this native event is passed back to Qt,
In your reimplementation of this function, if you want to stop Qt from which translates the event into a Qt event and sends it to the widget.
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 \note Events are only delivered to this event handler if the widget is
native. has a native Window handle.
\warning This function is not portable. \note This function superseedes the event filter functions
x11Event(), winEvent() and macEvent() of Qt 4.
\sa QApplication::x11EventFilter(), QWidget::winId() \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::nativeEvent(const QByteArray &eventType, void *message, long *result)
#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.
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.
\warning This function is not portable.
\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.
\sa QApplication::macEventFilter()
*/
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)
{ {
Q_UNUSED(eventType);
Q_UNUSED(message); Q_UNUSED(message);
Q_UNUSED(result); Q_UNUSED(result);
return false; 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 Ensures that the widget has been polished by QStyle (i.e., has a
proper font and palette). proper font and palette).

View File

@ -660,19 +660,7 @@ protected:
virtual void showEvent(QShowEvent *); virtual void showEvent(QShowEvent *);
virtual void hideEvent(QHideEvent *); virtual void hideEvent(QHideEvent *);
virtual bool nativeEvent(const QByteArray &eventType, void *message, long *result);
#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
// Misc. protected functions // Misc. protected functions
virtual void changeEvent(QEvent *); virtual void changeEvent(QEvent *);

View File

@ -431,4 +431,9 @@ void QWidgetWindow::handleWindowStateChangedEvent(QWindowStateChangeEvent *event
QGuiApplication::sendSpontaneousEvent(m_widget, &widgetEvent); 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 QT_END_NAMESPACE

View File

@ -79,6 +79,7 @@ protected:
void handleDragEvent(QEvent *); void handleDragEvent(QEvent *);
void handleExposeEvent(QExposeEvent *); void handleExposeEvent(QExposeEvent *);
void handleWindowStateChangedEvent(QWindowStateChangeEvent *event); void handleWindowStateChangedEvent(QWindowStateChangeEvent *event);
bool nativeEvent(const QByteArray &eventType, void *message, long *result);
private: private:
void updateGeometry(); void updateGeometry();