src/gui/kernel/qapplication_s60.cpp
branchRCL_3
changeset 4 3b1da2848fc7
parent 3 41300fa6a67c
child 5 d3bac044e0f0
--- a/src/gui/kernel/qapplication_s60.cpp	Tue Feb 02 00:43:10 2010 +0200
+++ b/src/gui/kernel/qapplication_s60.cpp	Fri Feb 19 23:40:16 2010 +0200
@@ -1,6 +1,6 @@
 /****************************************************************************
 **
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 ** Contact: Nokia Corporation (qt-info@nokia.com)
 **
@@ -807,6 +807,15 @@
 
 void QSymbianControl::Draw(const TRect& controlRect) const
 {
+    // Set flag to avoid calling DrawNow in window surface
+    QWExtra *extra = qwidget->d_func()->extraData();
+    if (extra && !extra->inExpose) {
+        extra->inExpose = true;
+        QRect exposeRect = qt_TRect2QRect(controlRect);
+        qwidget->d_func()->syncBackingStore(exposeRect);
+        extra->inExpose = false;
+    }
+
     QWindowSurface *surface = qwidget->windowSurface();
     QPaintEngine *engine = surface ? surface->paintDevice()->paintEngine() : NULL;
 
@@ -855,8 +864,6 @@
         default:
             Q_ASSERT(false);
         }
-    } else {
-        surface->flush(qwidget, QRegion(qt_TRect2QRect(backingStoreRect)), QPoint());
     }
 
     if (sendNativePaintEvents) {
@@ -930,7 +937,7 @@
 
 void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */)
 {
-    if (m_ignoreFocusChanged)
+    if (m_ignoreFocusChanged || (qwidget->windowType() & Qt::WindowType_Mask) == Qt::Desktop)
         return;
 
     // Popups never get focused, but still receive the FocusChanged when they are hidden.
@@ -1521,6 +1528,12 @@
         qt_S60Beep->Play();
 }
 
+static inline bool callSymbianEventFilters(const QSymbianEvent *event)
+{
+    long unused;
+    return qApp->filterEvent(const_cast<QSymbianEvent *>(event), &unused);
+}
+
 /*!
     \warning This function is only available on Symbian.
     \since 4.6
@@ -1537,6 +1550,9 @@
 
     QScopedLoopLevelCounter counter(d->threadData);
 
+    if (d->eventDispatcher->filterEvent(const_cast<QSymbianEvent *>(event)))
+        return 1;
+
     QWidget *w = qApp ? qApp->focusWidget() : 0;
     if (w) {
         QInputContext *ic = w->inputContext();
@@ -1549,29 +1565,34 @@
 
     switch (event->type()) {
     case QSymbianEvent::WindowServerEvent:
-        return d->symbianProcessWsEvent(event->windowServerEvent());
+        return d->symbianProcessWsEvent(event);
     case QSymbianEvent::CommandEvent:
-        return d->symbianHandleCommand(event->command());
+        return d->symbianHandleCommand(event);
     case QSymbianEvent::ResourceChangeEvent:
-        return d->symbianResourceChange(event->resourceChangeType());
+        return d->symbianResourceChange(event);
     default:
         return -1;
     }
 }
 
-int QApplicationPrivate::symbianProcessWsEvent(const TWsEvent *event)
+int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent)
 {
     // Qt event handling. Handle some events regardless of if the handle is in our
     // widget map or not.
+    const TWsEvent *event = symbianEvent->windowServerEvent();
     CCoeControl* control = reinterpret_cast<CCoeControl*>(event->Handle());
     const bool controlInMap = QWidgetPrivate::mapper && QWidgetPrivate::mapper->contains(control);
     switch (event->Type()) {
     case EEventPointerEnter:
-        if (controlInMap)
+        if (controlInMap) {
+            callSymbianEventFilters(symbianEvent);
             return 1; // Qt::Enter will be generated in HandlePointerL
+        }
         break;
     case EEventPointerExit:
         if (controlInMap) {
+            if (callSymbianEventFilters(symbianEvent))
+                return 1;
             if (S60) {
                 // mouseEvent outside our window, send leave event to last focused widget
                 QMouseEvent mEvent(QEvent::Leave, S60->lastPointerEventPos, S60->lastCursorPos,
@@ -1584,6 +1605,8 @@
         }
         break;
     case EEventScreenDeviceChanged:
+        if (callSymbianEventFilters(symbianEvent))
+            return 1;
         if (S60)
             S60->updateScreenSize();
         if (qt_desktopWidget) {
@@ -1596,6 +1619,8 @@
         return 0; // Propagate to CONE
     case EEventWindowVisibilityChanged:
         if (controlInMap) {
+            if (callSymbianEventFilters(symbianEvent))
+                return 1;
             const TWsVisibilityChangedEvent *visChangedEvent = event->VisibilityChanged();
             QWidget *w = QWidgetPrivate::mapper->value(control);
             if (!w->d_func()->maybeTopData())
@@ -1616,6 +1641,8 @@
         }
         break;
     case EEventFocusGained:
+        if (callSymbianEventFilters(symbianEvent))
+            return 1;
 #ifndef QT_NO_CURSOR
         //re-enable mouse interaction
         if (S60->mouseInteractionEnabled) {
@@ -1629,6 +1656,8 @@
 #endif
         break;
     case EEventFocusLost:
+        if (callSymbianEventFilters(symbianEvent))
+            return 1;
 #ifndef QT_NO_CURSOR
         //disable mouse as may be moving to application that does not support it
         if (S60->mouseInteractionEnabled) {
@@ -1680,11 +1709,16 @@
 
   \sa s60EventFilter(), s60ProcessEvent()
 */
-int QApplicationPrivate::symbianHandleCommand(int command)
+int QApplicationPrivate::symbianHandleCommand(const QSymbianEvent *symbianEvent)
 {
     Q_Q(QApplication);
     int ret = 0;
 
+    if (callSymbianEventFilters(symbianEvent))
+        return 1;
+
+    int command = symbianEvent->command();
+
     switch (command) {
 #ifdef Q_WS_S60
     case EAknSoftkeyExit: {
@@ -1724,14 +1758,18 @@
   Currently, KEikDynamicLayoutVariantSwitch and
   KAknsMessageSkinChange are handled.
  */
-int QApplicationPrivate::symbianResourceChange(int type)
+int QApplicationPrivate::symbianResourceChange(const QSymbianEvent *symbianEvent)
 {
     int ret = 0;
 
+    int type = symbianEvent->resourceChangeType();
+
     switch (type) {
 #ifdef Q_WS_S60
     case KEikDynamicLayoutVariantSwitch:
         {
+        if (callSymbianEventFilters(symbianEvent))
+            return 1;
         if (S60)
             S60->updateScreenSize();
 
@@ -1756,6 +1794,8 @@
 
 #ifndef QT_NO_STYLE_S60
     case KAknsMessageSkinChange:
+        if (callSymbianEventFilters(symbianEvent))
+            return 1;
         if (QS60Style *s60Style = qobject_cast<QS60Style*>(QApplication::style())) {
             s60Style->d_func()->handleSkinChange();
             ret = 1;