From 4a84b272459160780529f654e6aee3abf8569b51 Mon Sep 17 00:00:00 2001
From: axis <qt-info@nokia.com>
Date: Thu, 7 Jan 2010 16:01:58 +0100
Subject: Added a flag to avoid construction of application panes.

This is purely an optimization for fullscreen-only apps.

Task:     QTBUG-6098
RevBy:    Jason Barron
RevBy:    mread
AutoTest: Included
---
 src/corelib/global/qnamespace.h              |  1 +
 src/corelib/global/qnamespace.qdoc           |  6 ++
 src/gui/dialogs/qdialog.cpp                  |  9 ++-
 src/gui/kernel/qsoftkeymanager.cpp           |  3 +-
 src/gui/s60framework/qs60mainappui.cpp       | 12 +++-
 tests/auto/qapplication/heart.svg            | 55 +++++++++++++++++
 tests/auto/qapplication/test/test.pro        |  4 +-
 tests/auto/qapplication/tst_qapplication.cpp | 88 ++++++++++++++++++++++++++++
 8 files changed, 172 insertions(+), 6 deletions(-)
 create mode 100644 tests/auto/qapplication/heart.svg

diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index 0ee9cd2..c40308c 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -511,6 +511,7 @@ public:
         AA_MacPluginApplication = 5,
         AA_DontUseNativeMenuBar = 6,
         AA_MacDontSwapCtrlAndMeta = 7,
+        AA_S60DontConstructApplicationPanes = 8,
 
         // Add new attributes before this line
         AA_AttributeCount
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 70ca507..5a80d56 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -163,6 +163,12 @@
            Command+C on the keyboard regardless of the value set, though what is output for
            QKeySequence::toString(QKeySequence::PortableText) will be different).
 
+    \value AA_S60DontConstructApplicationPanes Stops Qt from initializing the S60 status
+           pane and softkey pane on Symbian. This is useful to save memory and reduce
+           startup time for applications that will run in fullscreen mode during their
+           whole lifetime. This attribute must be set before QApplication is
+           constructed.
+
     \omitvalue AA_AttributeCount
 */
 
diff --git a/src/gui/dialogs/qdialog.cpp b/src/gui/dialogs/qdialog.cpp
index ed2d676..d7653e5 100644
--- a/src/gui/dialogs/qdialog.cpp
+++ b/src/gui/dialogs/qdialog.cpp
@@ -888,7 +888,14 @@ bool QDialog::s60AdjustedPosition()
     if (doS60Positioning) {
         // naive way to deduce screen orientation
         if (S60->screenHeightInPixels > S60->screenWidthInPixels) {
-            p.setY(S60->screenHeightInPixels-height()-qt_TSize2QSize(S60->buttonGroupContainer()->Size()).height());
+            int cbaHeight;
+            const CEikButtonGroupContainer* bgContainer = S60->buttonGroupContainer();
+            if (!bgContainer) {
+                cbaHeight = 0;
+            } else {
+                cbaHeight = qt_TSize2QSize(bgContainer->Size()).height();
+            }
+            p.setY(S60->screenHeightInPixels-height()-cbaHeight);
             p.setX(0);
         } else {
             const int scrollbarWidth = style()->pixelMetric(QStyle::PM_ScrollBarExtent);
diff --git a/src/gui/kernel/qsoftkeymanager.cpp b/src/gui/kernel/qsoftkeymanager.cpp
index 0e98f39..b09ab8f 100644
--- a/src/gui/kernel/qsoftkeymanager.cpp
+++ b/src/gui/kernel/qsoftkeymanager.cpp
@@ -211,7 +211,8 @@ bool QSoftKeyManager::event(QEvent *e)
 void QSoftKeyManagerPrivate::updateSoftKeys_sys(const QList<QAction*> &softkeys)
 {
     // lets not update softkeys if s60 native dialog or menu is shown
-    if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog())
+    if (QApplication::testAttribute(Qt::AA_S60DontConstructApplicationPanes)
+            || CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog())
         return;
 
     CEikButtonGroupContainer* nativeContainer = S60->buttonGroupContainer();
diff --git a/src/gui/s60framework/qs60mainappui.cpp b/src/gui/s60framework/qs60mainappui.cpp
index 4c4c994..4813fb2 100644
--- a/src/gui/s60framework/qs60mainappui.cpp
+++ b/src/gui/s60framework/qs60mainappui.cpp
@@ -104,10 +104,16 @@ void QS60MainAppUi::ConstructL()
     // ENoAppResourceFile and ENonStandardResourceFile makes UI to work without
     // resource files in most SDKs. S60 3rd FP1 public seems to require resource file
     // even these flags are defined
-    BaseConstructL(CAknAppUi::EAknEnableSkin);
+    TInt flags = CAknAppUi::EAknEnableSkin;
+    if (QApplication::testAttribute(Qt::AA_S60DontConstructApplicationPanes)) {
+        flags |= CAknAppUi::ENoScreenFurniture | CAknAppUi::ENonStandardResourceFile;
+    }
+    BaseConstructL(flags);
 
-    CEikButtonGroupContainer* nativeContainer = Cba();
-    nativeContainer->SetCommandSetL(R_AVKON_SOFTKEYS_EMPTY_WITH_IDS);
+    if (!QApplication::testAttribute(Qt::AA_S60DontConstructApplicationPanes)) {
+        CEikButtonGroupContainer* nativeContainer = Cba();
+        nativeContainer->SetCommandSetL(R_AVKON_SOFTKEYS_EMPTY_WITH_IDS);
+    }
 }
 
 /*!
diff --git a/tests/auto/qapplication/heart.svg b/tests/auto/qapplication/heart.svg
new file mode 100644
index 0000000..8c982cd
--- /dev/null
+++ b/tests/auto/qapplication/heart.svg
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) --><svg viewBox="100 200 550 500" height="841.88976pt" id="svg1" inkscape:version="0.40+cvs" sodipodi:docbase="C:\Documents and Settings\Jon Phillips\My Documents\projects\clipart-project\submissions" sodipodi:docname="heart-left-highlight.svg" sodipodi:version="0.32" width="595.27559pt" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://web.resource.org/cc/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg">
+<metadata>
+<rdf:RDF xmlns:cc="http://web.resource.org/cc/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+<cc:Work rdf:about="">
+<dc:title>Heart Left-Highlight</dc:title>
+<dc:description>This is a normal valentines day heart.</dc:description>
+<dc:subject>
+<rdf:Bag>
+<rdf:li>holiday</rdf:li>
+<rdf:li>valentines</rdf:li>
+<rdf:li></rdf:li>
+<rdf:li>valentine</rdf:li>
+<rdf:li>hash(0x8a091c0)</rdf:li>
+<rdf:li>hash(0x8a0916c)</rdf:li>
+<rdf:li>signs_and_symbols</rdf:li>
+<rdf:li>hash(0x8a091f0)</rdf:li>
+<rdf:li>day</rdf:li>
+</rdf:Bag>
+</dc:subject>
+<dc:publisher>
+<cc:Agent rdf:about="http://www.openclipart.org">
+<dc:title>Jon Phillips</dc:title>
+</cc:Agent>
+</dc:publisher>
+<dc:creator>
+<cc:Agent>
+<dc:title>Jon Phillips</dc:title>
+</cc:Agent>
+</dc:creator>
+<dc:rights>
+<cc:Agent>
+<dc:title>Jon Phillips</dc:title>
+</cc:Agent>
+</dc:rights>
+<dc:date></dc:date>
+<dc:format>image/svg+xml</dc:format>
+<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+<cc:license rdf:resource="http://web.resource.org/cc/PublicDomain"/>
+<dc:language>en</dc:language>
+</cc:Work>
+<cc:License rdf:about="http://web.resource.org/cc/PublicDomain">
+<cc:permits rdf:resource="http://web.resource.org/cc/Reproduction"/>
+<cc:permits rdf:resource="http://web.resource.org/cc/Distribution"/>
+<cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks"/>
+</cc:License>
+</rdf:RDF>
+</metadata>
+<defs id="defs3"/>
+<sodipodi:namedview bordercolor="#666666" borderopacity="1.0" id="base" inkscape:current-layer="layer1" inkscape:cx="549.40674" inkscape:cy="596.00159" inkscape:document-units="px" inkscape:guide-bbox="true" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:window-height="615" inkscape:window-width="866" inkscape:window-x="88" inkscape:window-y="116" inkscape:zoom="0.35000000" pagecolor="#ffffff" showguides="true"/>
+<g id="layer1" inkscape:groupmode="layer" inkscape:label="Layer 1">
+<path d="M 263.41570,235.14588 C 197.17570,235.14588 143.41575,288.90587 143.41575,355.14588 C 143.41575,489.90139 279.34890,525.23318 371.97820,658.45392 C 459.55244,526.05056 600.54070,485.59932 600.54070,355.14588 C 600.54070,288.90588 546.78080,235.14587 480.54070,235.14588 C 432.49280,235.14588 391.13910,263.51631 371.97820,304.33338 C 352.81740,263.51630 311.46370,235.14587 263.41570,235.14588 z " id="path7" sodipodi:nodetypes="ccccccc" style="fill:#e60000;fill-opacity:1.0000000;stroke:#000000;stroke-width:18.700001;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"/>
+<path d="M 265.00000,253.59375 C 207.04033,253.59375 160.00000,300.63407 160.00000,358.59375 C 160.00000,476.50415 278.91857,507.43251 359.96875,624.00000 C 366.52868,614.08205 220.00000,478.47309 220.00000,378.59375 C 220.00000,320.63407 267.04033,273.59375 325.00000,273.59375 C 325.50453,273.59375 325.99718,273.64912 326.50000,273.65625 C 309.22436,261.07286 288.00557,253.59374 265.00000,253.59375 z " id="path220" sodipodi:nodetypes="ccccccc" style="fill:#e6e6e6;fill-opacity:0.64556962;stroke:none;stroke-width:18.700001;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"/>
+</g>
+</svg>
diff --git a/tests/auto/qapplication/test/test.pro b/tests/auto/qapplication/test/test.pro
index 7c3de3c..e68af26 100644
--- a/tests/auto/qapplication/test/test.pro
+++ b/tests/auto/qapplication/test/test.pro
@@ -16,7 +16,9 @@ symbian*: {
   additional.path = desktopsettingsaware
   someTest.sources = test.pro
   someTest.path = test
-  DEPLOYMENT = additional deploy someTest
+  windowIcon.sources = ../heart.svg
+  DEPLOYMENT = additional deploy someTest windowIcon
+  LIBS += -lcone -lavkon
 }
 
 win32 {
diff --git a/tests/auto/qapplication/tst_qapplication.cpp b/tests/auto/qapplication/tst_qapplication.cpp
index 5888866..ed614e15 100644
--- a/tests/auto/qapplication/tst_qapplication.cpp
+++ b/tests/auto/qapplication/tst_qapplication.cpp
@@ -53,6 +53,9 @@
 #ifdef Q_OS_WINCE
 #include <windows.h>
 #endif
+#ifdef Q_OS_SYMBIAN
+#include <aknenv.h>
+#endif
 
 //TESTED_CLASS=
 //TESTED_FILES=
@@ -138,6 +141,8 @@ private slots:
 
     void touchEventPropagation();
 
+    void symbianNoApplicationPanes();
+
     void symbianNeedForTraps();
     void symbianLeaveThroughMain();
 };
@@ -2036,6 +2041,89 @@ void tst_QApplication::touchEventPropagation()
     }
 }
 
+void tst_QApplication::symbianNoApplicationPanes()
+{
+#ifndef Q_OS_SYMBIAN
+    QSKIP("This is a Symbian only test", SkipAll);
+#else
+    QApplication::setAttribute(Qt::AA_S60DontConstructApplicationPanes);
+
+    // Run in a block so that QApplication is destroyed before resetting the attribute.
+    {
+        // Actually I wasn't able to get the forced orientation change to work properly,
+        // but I'll leave the code here for the future in case we manage to test that
+        // later. If someone knows how to force an orientation switch in an autotest, do
+        // feel free to fix this testcase.
+        int argc = 0;
+        QApplication app(argc, 0);
+        QWidget *w;
+
+        w = new QWidget;
+        w->show();
+        QT_TRAP_THROWING(static_cast<CAknAppUi *>(CCoeEnv::Static()->AppUi())
+                ->SetOrientationL(CAknAppUi::EAppUiOrientationLandscape));
+        app.processEvents();
+        delete w;
+
+        w = new QWidget;
+        w->show();
+        QT_TRAP_THROWING(static_cast<CAknAppUi *>(CCoeEnv::Static()->AppUi())
+                ->SetOrientationL(CAknAppUi::EAppUiOrientationPortrait));
+        app.processEvents();
+        delete w;
+
+        w = new QWidget;
+        w->showMaximized();
+        QT_TRAP_THROWING(static_cast<CAknAppUi *>(CCoeEnv::Static()->AppUi())
+                ->SetOrientationL(CAknAppUi::EAppUiOrientationLandscape));
+        app.processEvents();
+        delete w;
+
+        w = new QWidget;
+        w->showMaximized();
+        QT_TRAP_THROWING(static_cast<CAknAppUi *>(CCoeEnv::Static()->AppUi())
+                ->SetOrientationL(CAknAppUi::EAppUiOrientationPortrait));
+        app.processEvents();
+        delete w;
+
+        w = new QWidget;
+        w->showFullScreen();
+        QT_TRAP_THROWING(static_cast<CAknAppUi *>(CCoeEnv::Static()->AppUi())
+                ->SetOrientationL(CAknAppUi::EAppUiOrientationLandscape));
+        app.processEvents();
+        delete w;
+
+        w = new QWidget;
+        w->showFullScreen();
+        QT_TRAP_THROWING(static_cast<CAknAppUi *>(CCoeEnv::Static()->AppUi())
+                ->SetOrientationL(CAknAppUi::EAppUiOrientationPortrait));
+        app.processEvents();
+        delete w;
+
+        // These will have no effect, since there is no status pane, but they shouldn't
+        // crash either.
+        w = new QWidget;
+        w->show();
+        w->setWindowTitle("Testing title");
+        app.processEvents();
+        delete w;
+
+        w = new QWidget;
+        w->show();
+        w->setWindowIcon(QIcon(QPixmap("heart.svg")));
+        app.processEvents();
+        delete w;
+
+        QDesktopWidget desktop;
+        QCOMPARE(desktop.availableGeometry(), desktop.screenGeometry());
+    }
+
+    QApplication::setAttribute(Qt::AA_S60DontConstructApplicationPanes, false);
+
+    // No other error condition. Program will crash if unsuccessful.
+#endif
+}
+
 #ifdef Q_OS_SYMBIAN
 class CBaseDummy : public CBase
 {
-- 
cgit v0.12