From f1b134bc57584c64e9703683d2c3bc6c46264d19 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Mon, 14 Sep 2009 14:23:06 +0200 Subject: Implement synthetic enter/leave events for QWS. QWS uses alien widgets too, so we need the same logic as the other platforms. Reviewed-by: bnilsen --- src/gui/kernel/qapplication.cpp | 18 ++++++++++++++---- src/gui/kernel/qapplication_p.h | 5 ++++- src/gui/kernel/qapplication_qws.cpp | 3 +++ src/gui/kernel/qwidget.cpp | 12 ++++++++---- tests/auto/qwidget/tst_qwidget.cpp | 5 +++-- 5 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 300e519..a19e022 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -469,12 +469,18 @@ QWidget *QApplicationPrivate::oldEditFocus = 0; bool qt_tabletChokeMouse = false; static bool force_reverse = false; -static inline bool isAlien(QWidget *widget) +inline bool QApplicationPrivate::isAlien(QWidget *widget) { if (!widget) return false; -#ifdef Q_WS_MAC // Fake alien behavior on the Mac :) +#if defined(Q_WS_MAC) // Fake alien behavior on the Mac :) return !widget->isWindow() && widget->window()->testAttribute(Qt::WA_DontShowOnScreen); +#elif defined(Q_WS_QWS) + return !widget->isWindow() +# ifdef Q_BACKINGSTORE_SUBSURFACES + && !(widget->d_func()->maybeTopData() && widget->d_func()->maybeTopData()->windowSurface) +# endif + ; #else return !widget->internalWinId(); #endif @@ -2974,7 +2980,7 @@ bool QApplicationPrivate::sendMouseEvent(QWidget *receiver, QMouseEvent *event, return result; } -#if defined(Q_WS_WIN) || defined(Q_WS_X11) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_QWS) /* This function should only be called when the widget changes visibility, i.e. when the \a widget is shown, hidden or deleted. This function does nothing @@ -2986,9 +2992,13 @@ extern QWidget *qt_button_down; void QApplicationPrivate::sendSyntheticEnterLeave(QWidget *widget) { #ifndef QT_NO_CURSOR +#ifdef Q_WS_QWS + if (!widget || widget->isWindow()) + return; +#else if (!widget || widget->internalWinId() || widget->isWindow()) return; - +#endif const bool widgetInShow = widget->isVisible() && !widget->data->in_destructor; if (!widgetInShow && widget != qt_last_mouse_receiver) return; // Widget was not under the cursor when it was hidden/deleted. diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index c027763..c33eb1a 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -513,7 +513,7 @@ public: #ifdef Q_OS_SYMBIAN static TUint resolveS60ScanCode(TInt scanCode, TUint keysym); #endif -#if defined(Q_WS_WIN) || defined(Q_WS_X11) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) void sendSyntheticEnterLeave(QWidget *widget); #endif @@ -586,6 +586,9 @@ private: Qt::FocusPolicy focusPolicy, Qt::FocusReason focusReason); static bool shouldSetFocus(QWidget *w, Qt::FocusPolicy policy); + + + static bool isAlien(QWidget *); }; Q_GUI_EXPORT void qt_translateRawTouchEvent(QWidget *window, diff --git a/src/gui/kernel/qapplication_qws.cpp b/src/gui/kernel/qapplication_qws.cpp index e6bfd28..e9284f7 100644 --- a/src/gui/kernel/qapplication_qws.cpp +++ b/src/gui/kernel/qapplication_qws.cpp @@ -430,6 +430,7 @@ static QWidget *popupOfPopupButtonFocus = 0; static bool popupCloseDownMode = false; static bool popupGrabOk; static QPointer *mouseInWidget = 0; +QPointer qt_last_mouse_receiver = 0; static bool sm_blockUserInput = false; // session management @@ -3523,10 +3524,12 @@ bool QETWidget::translateMouseEvent(const QWSMouseEvent *event, int prevstate) if (widget != (*mouseInWidget)) { QApplicationPrivate::dispatchEnterLeave(widget, *mouseInWidget); (*mouseInWidget) = widget; + qt_last_mouse_receiver = widget; } QApplication::sendSpontaneousEvent(widget, &e); if (leaveAfterRelease && !QWidget::mouseGrabber()) { *mouseInWidget = QApplication::widgetAt(globalPos); + qt_last_mouse_receiver = *mouseInWidget; QApplicationPrivate::dispatchEnterLeave(*mouseInWidget, leaveAfterRelease); leaveAfterRelease = 0; } diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index fd44d78..fd89cb9 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -1442,9 +1442,13 @@ QWidget::~QWidget() } } -#if defined(Q_WS_WIN) || defined(Q_WS_X11) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) else if (!internalWinId() && isVisible()) { qApp->d_func()->sendSyntheticEnterLeave(this); +#ifdef Q_WS_QWS + } else if (isVisible()) { + qApp->d_func()->sendSyntheticEnterLeave(this); +#endif } #endif @@ -7181,7 +7185,7 @@ void QWidgetPrivate::hide_helper() // next bit tries to move the focus if the focus widget is now // hidden. if (wasVisible) { -#if defined(Q_WS_WIN) || defined(Q_WS_X11) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) qApp->d_func()->sendSyntheticEnterLeave(q); #endif @@ -7313,7 +7317,7 @@ void QWidget::setVisible(bool visible) d->show_helper(); -#if defined(Q_WS_WIN) || defined(Q_WS_X11) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) qApp->d_func()->sendSyntheticEnterLeave(this); #endif } @@ -7428,7 +7432,7 @@ void QWidgetPrivate::hideChildren(bool spontaneous) widget->d_func()->hide_sys(); } } -#if defined(Q_WS_WIN) || defined(Q_WS_X11) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) qApp->d_func()->sendSyntheticEnterLeave(widget); #endif #ifndef QT_NO_ACCESSIBILITY diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index 47cd860..86caddb 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -350,7 +350,7 @@ private slots: void setClearAndResizeMask(); void maskedUpdate(); -#if defined(Q_WS_WIN) || defined(Q_WS_X11) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_QWS) void syntheticEnterLeave(); #endif void windowFlags(); @@ -8990,7 +8990,7 @@ void tst_QWidget::maskedUpdate() QCOMPARE(grandChild.paintedRegion, QRegion(grandChild.rect())); // Full update. } -#if defined(Q_WS_X11) || defined(Q_WS_WIN) +#if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_WS_QWS) void tst_QWidget::syntheticEnterLeave() { class MyWidget : public QWidget @@ -9275,6 +9275,7 @@ void tst_QWidget::rectOutsideCoordinatesLimit_task144779() #ifdef Q_WS_X11 qt_x11_wait_for_window_manager(&main); #endif + QCursor::setPos(main.pos()); //get the cursor out of the picture QTest::qWait(100); QPixmap pixmap = QPixmap::grabWindow(main.winId()); -- cgit v0.12