src/gui/kernel/qapplication_s60.cpp
branchRCL_3
changeset 8 3f74d0d4af4c
parent 5 d3bac044e0f0
child 12 25a739ee40f4
--- a/src/gui/kernel/qapplication_s60.cpp	Mon Mar 15 12:43:09 2010 +0200
+++ b/src/gui/kernel/qapplication_s60.cpp	Thu Apr 08 14:19:33 2010 +0300
@@ -52,6 +52,7 @@
 #include "qstring.h"
 #include "qdebug.h"
 #include "qimage.h"
+#include "qcombobox.h"
 #include "private/qkeymapper_p.h"
 #include "private/qfont_p.h"
 #ifndef QT_NO_STYLE_S60
@@ -597,7 +598,9 @@
         TUint s60Keysym = QApplicationPrivate::resolveS60ScanCode(keyEvent.iScanCode,
                 keyEvent.iCode);
         int keyCode;
-        if (s60Keysym >= 0x20 && s60Keysym < ENonCharacterKeyBase) {
+        if (s60Keysym == EKeyNull){ //some key events have 0 in iCode, for them iScanCode should be used
+            keyCode = qt_keymapper_private()->mapS60ScanCodesToQt(keyEvent.iScanCode);
+        } else if (s60Keysym >= 0x20 && s60Keysym < ENonCharacterKeyBase) {
             // Normal characters keys.
             keyCode = s60Keysym;
         } else {
@@ -809,12 +812,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;
+    QWidget *window = qwidget->window();
+    Q_ASSERT(window);
+    QTLWExtra *topExtra = window->d_func()->maybeTopData();
+    Q_ASSERT(topExtra);
+    if (!topExtra->inExpose) {
+        topExtra->inExpose = true;
         QRect exposeRect = qt_TRect2QRect(controlRect);
         qwidget->d_func()->syncBackingStore(exposeRect);
-        extra->inExpose = false;
+        topExtra->inExpose = false;
     }
 
     QWindowSurface *surface = qwidget->windowSurface();
@@ -924,8 +930,8 @@
         cr.moveTopLeft(newPos);
         qwidget->data->crect = cr;
         QTLWExtra *top = qwidget->d_func()->maybeTopData();
-        if (top)
-            top->normalGeometry = cr;
+        if (top && (qwidget->windowState() & (~Qt::WindowActive)) == Qt::WindowNoState)
+            top->normalGeometry.moveTopLeft(newPos);
         if (qwidget->isVisible()) {
             QMoveEvent e(newPos, oldPos);
             qt_sendSpontaneousEvent(qwidget, &e);
@@ -960,15 +966,27 @@
         qwidget->d_func()->setWindowIcon_sys(true);
         qwidget->d_func()->setWindowTitle_sys(qwidget->windowTitle());
 #ifdef Q_WS_S60
-        // If widget is fullscreen, hide status pane and button container
-        // otherwise show them.
-        CEikStatusPane* statusPane = S60->statusPane();
-        CEikButtonGroupContainer* buttonGroup = S60->buttonGroupContainer();
-        bool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen;
-        if (statusPane && (bool)statusPane->IsVisible() == isFullscreen)
-            statusPane->MakeVisible(!isFullscreen);
-        if (buttonGroup && (bool)buttonGroup->IsVisible() == isFullscreen)
-            buttonGroup->MakeVisible(!isFullscreen);
+        // If widget is fullscreen/minimized, hide status pane and button container otherwise show them.
+        CEikStatusPane *statusPane = S60->statusPane();
+        CEikButtonGroupContainer *buttonGroup = S60->buttonGroupContainer();
+        TBool visible = !(qwidget->windowState() & (Qt::WindowFullScreen | Qt::WindowMinimized));
+        if (statusPane)
+            statusPane->MakeVisible(visible);
+        if (buttonGroup) {
+            // Visibility
+            const TBool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen;
+            const TBool cbaVisibilityHint = qwidget->windowFlags() & Qt::WindowSoftkeysVisibleHint;
+            buttonGroup->MakeVisible(visible || (isFullscreen && cbaVisibilityHint));
+
+            // Responsiviness
+            CEikCba *cba = static_cast<CEikCba *>( buttonGroup->ButtonGroup() ); // downcast from MEikButtonGroup
+            TUint cbaFlags = cba->ButtonGroupFlags();
+            if(qwidget->windowFlags() & Qt::WindowSoftkeysRespondHint)
+                cbaFlags |= EAknCBAFlagRespondWhenInvisible;
+            else
+                cbaFlags &= ~EAknCBAFlagRespondWhenInvisible;
+            cba->SetButtonGroupFlags(cbaFlags);
+        }
 #endif
     } else if (QApplication::activeWindow() == qwidget->window()) {
         if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog()) {
@@ -986,16 +1004,32 @@
     // else { We don't touch the active window unless we were explicitly activated or deactivated }
 }
 
+void QSymbianControl::handleClientAreaChange()
+{
+    const bool cbaVisibilityHint = qwidget->windowFlags() & Qt::WindowSoftkeysVisibleHint;
+    if (qwidget->isFullScreen() && !cbaVisibilityHint) {
+        SetExtentToWholeScreen();
+    } else if (qwidget->isMaximized() || (qwidget->isFullScreen() && cbaVisibilityHint)) {
+        TRect r = static_cast<CEikAppUi*>(S60->appUi())->ClientRect();
+        SetExtent(r.iTl, r.Size());
+    } else if (!qwidget->isMinimized()) { // Normal geometry
+        if (!qwidget->testAttribute(Qt::WA_Resized)) {
+            qwidget->adjustSize();
+            qwidget->setAttribute(Qt::WA_Resized, false); //not a user resize
+        }
+        if (!qwidget->testAttribute(Qt::WA_Moved) && qwidget->windowType() != Qt::Dialog) {
+            TRect r = static_cast<CEikAppUi*>(S60->appUi())->ClientRect();
+            SetPosition(r.iTl);
+            qwidget->setAttribute(Qt::WA_Moved, false); // not really an explicit position
+        }
+    }
+}
+
 void QSymbianControl::HandleResourceChange(int resourceType)
 {
     switch (resourceType) {
     case KInternalStatusPaneChange:
-        if (qwidget->isFullScreen()) {
-            SetExtentToWholeScreen();
-        } else if (qwidget->isMaximized()) {
-            TRect r = static_cast<CEikAppUi*>(S60->appUi())->ClientRect();
-            SetExtent(r.iTl, r.Size());
-        }
+        handleClientAreaChange();
         if (IsFocused() && IsVisible()) {
             qwidget->d_func()->setWindowIcon_sys(true);
             qwidget->d_func()->setWindowTitle_sys(qwidget->windowTitle());
@@ -1007,12 +1041,7 @@
 #ifdef Q_WS_S60
     case KEikDynamicLayoutVariantSwitch:
     {
-        if (qwidget->isFullScreen()) {
-            SetExtentToWholeScreen();
-        } else if (qwidget->isMaximized()) {
-            TRect r = static_cast<CEikAppUi*>(S60->appUi())->ClientRect();
-            SetExtent(r.iTl, r.Size());
-        }
+        handleClientAreaChange();
         break;
     }
 #endif
@@ -1144,6 +1173,10 @@
 #endif
         S60->wsSession().SetAutoFlush(ETrue);
 
+#ifdef Q_SYMBIAN_WINDOW_SIZE_CACHE
+    TRAP_IGNORE(S60->wsSession().EnableWindowSizeCacheL());
+#endif
+
     S60->updateScreenSize();
 
 
@@ -1221,7 +1254,7 @@
             S60->avkonComponentsSupportTransparency = (value==1) ? true : false;
         }
     }
-#endif    
+#endif
 
     if (touch) {
         QApplicationPrivate::navigationMode = Qt::NavigationModeNone;
@@ -1376,11 +1409,13 @@
 
 void QApplicationPrivate::openPopup(QWidget *popup)
 {
+    if (popup && qobject_cast<QComboBox *>(popup->parentWidget()))
+        static_cast<QSymbianControl *>(popup->effectiveWinId())->FadeBehindPopup(ETrue);
+
     if (!QApplicationPrivate::popupWidgets)
         QApplicationPrivate::popupWidgets = new QWidgetList;
     QApplicationPrivate::popupWidgets->append(popup);
 
-
     // Cancel focus widget pointer capture and long tap timer
     if (QApplication::focusWidget()) {
         static_cast<QSymbianControl*>(QApplication::focusWidget()->effectiveWinId())->CancelLongTapTimer();
@@ -1419,6 +1454,9 @@
 
 void QApplicationPrivate::closePopup(QWidget *popup)
 {
+    if (popup && qobject_cast<QComboBox *>(popup->parentWidget()))
+        static_cast<QSymbianControl *>(popup->effectiveWinId())->FadeBehindPopup(EFalse);
+
     if (!QApplicationPrivate::popupWidgets)
         return;
     QApplicationPrivate::popupWidgets->removeAll(popup);
@@ -1442,6 +1480,9 @@
         QWidget *fw = QApplicationPrivate::active_window ? QApplicationPrivate::active_window->focusWidget()
               : q_func()->focusWidget();
           if (fw) {
+              if(fw->window()->isModal()) // restore pointer capture for modal window
+                  fw->effectiveWinId()->SetPointerCapture(true);
+
               if (fw != q_func()->focusWidget()) {
                   fw->setFocus(Qt::PopupFocusReason);
               } else {
@@ -1647,9 +1688,9 @@
             if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::ENotVisible) {
                 delete w->d_func()->topData()->backingStore;
                 w->d_func()->topData()->backingStore = 0;
-                // :QTP:QT-2506:remove this when QT-2506 is fixed
-                if (S60)
-                    S60->wsSession().Flush();
+                // In order to ensure that any resources used by the window surface
+                // are immediately freed, we flush the WSERV command buffer.
+                S60->wsSession().Flush();
             } else if ((visChangedEvent->iFlags & TWsVisibilityChangedEvent::EPartiallyVisible)
                        && !w->d_func()->maybeBackingStore()) {
                 w->d_func()->topData()->backingStore = new QWidgetBackingStore(w);