From a3c755e358596238dc7fc1c284328a6226c2ed3a Mon Sep 17 00:00:00 2001 From: Janne Anttila Date: Thu, 7 Oct 2010 12:41:03 +0300 Subject: Removed the need for S60main.rsc resource file in Symbian. Qt upgrade was failing since the s60main.rsc is being locked by S60 application framework. And when installer detects that old version of Qt has already been installed it first tries to uninstall the old one and then install the new one. The uninstallion failed since the file was locked by the running Qt application. It should be noted that this patch fixes the Qt upgradibility only for Qt versions where patch is included. I.e. the versions before 4.7.2 need a different mechanism to be upgradable. This different mechanism is based on partial upgrade SIS packages as described in QT-4052. Task-number: QT-3471 Reviewed-by: Axis --- src/gui/kernel/qt_s60_p.h | 9 ++++++++- src/gui/kernel/qwidget_s60.cpp | 25 ++++++++++++++++++++++--- src/gui/s60framework/qs60mainapplication.cpp | 5 ----- src/gui/s60framework/qs60mainappui.cpp | 28 ++++++++++++++-------------- src/gui/s60framework/s60framework.pri | 18 ------------------ src/s60installs/s60installs.pro | 17 ++++------------- src/s60main/s60main.rsg | 3 --- 7 files changed, 48 insertions(+), 57 deletions(-) delete mode 100644 src/s60main/s60main.rsg diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index 7fd2baa..93f64f6 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -142,6 +142,7 @@ public: int avkonComponentsSupportTransparency : 1; int menuBeingConstructed : 1; QApplication::QS60MainApplicationFactory s60ApplicationFactory; // typedef'ed pointer type + static CEikButtonGroupContainer *cba; enum ScanCodeState { Unpressed, @@ -162,6 +163,7 @@ public: static inline CAknTitlePane* titlePane(); static inline CAknContextPane* contextPane(); static inline CEikButtonGroupContainer* buttonGroupContainer(); + static inline void setButtonGroupContainer(CEikButtonGroupContainer* newCba); static void setStatusPaneAndButtonGroupVisibility(bool statusPaneVisible, bool buttonGroupVisible); #endif static void controlVisibilityChanged(CCoeControl *control, bool visible); @@ -383,7 +385,12 @@ inline CAknContextPane* QS60Data::contextPane() inline CEikButtonGroupContainer* QS60Data::buttonGroupContainer() { - return CEikonEnv::Static()->AppUiFactory()->Cba(); + return QS60Data::cba; +} + +inline void QS60Data::setButtonGroupContainer(CEikButtonGroupContainer *newCba) +{ + QS60Data::cba = newCba; } #endif // Q_WS_S60 diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 4109ed8..49d2ffc 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -69,6 +69,7 @@ extern bool qt_nograb(); QWidget *QWidgetPrivate::mouseGrabber = 0; QWidget *QWidgetPrivate::keyboardGrabber = 0; +CEikButtonGroupContainer *QS60Data::cba = 0; static bool isEqual(const QList& a, const QList& b) { @@ -494,9 +495,27 @@ void QWidgetPrivate::show_sys() // Create the status pane and CBA here CEikAppUi *ui = static_cast(S60->appUi()); MEikAppUiFactory *factory = CEikonEnv::Static()->AppUiFactory(); - TRAP_IGNORE(factory->ReadAppInfoResourceL(0, ui)); - if (S60->buttonGroupContainer()) - S60->buttonGroupContainer()->SetCommandSetL(R_AVKON_SOFTKEYS_EMPTY_WITH_IDS); + + QT_TRAP_THROWING( + factory->CreateResourceIndependentFurnitureL(ui); + + TRect boundingRect = static_cast(S60->appUi())->ClientRect(); + + CEikButtonGroupContainer *cba = CEikButtonGroupContainer::NewL(CEikButtonGroupContainer::ECba, + CEikButtonGroupContainer::EHorizontal,ui,R_AVKON_SOFTKEYS_EMPTY_WITH_IDS); + + CEikButtonGroupContainer *oldCba = CEikonEnv::Static()->AppUiFactory()->SwapButtonGroup(cba); + Q_ASSERT(!oldCba); + S60->setButtonGroupContainer(cba); + + CEikMenuBar *menuBar = new(ELeave) CEikMenuBar; + menuBar->ConstructL(ui, 0, R_AVKON_MENUPANE_EMPTY); + menuBar->SetMenuType(CEikMenuBar::EMenuOptions); + S60->appUi()->AddToStackL(menuBar,ECoeStackPriorityMenu,ECoeStackFlagRefusesFocus); + + CEikMenuBar *oldMenu = CEikonEnv::Static()->AppUiFactory()->SwapMenuBar(menuBar); + Q_ASSERT(!oldMenu); + ) if (S60->statusPane()) { // Use QDesktopWidget as the status pane observer to proxy for the AppUi. diff --git a/src/gui/s60framework/qs60mainapplication.cpp b/src/gui/s60framework/qs60mainapplication.cpp index 5d4c54e..74432af 100644 --- a/src/gui/s60framework/qs60mainapplication.cpp +++ b/src/gui/s60framework/qs60mainapplication.cpp @@ -58,7 +58,6 @@ CApaApplication *newS60Application() return new QS60MainApplication; } -_LIT(KQtWrapperResourceFile, "\\resource\\apps\\s60main" QT_LIBINFIX_UNICODE L".rsc"); /*! \class QS60MainApplication @@ -129,10 +128,6 @@ TUid QS60MainApplication::AppDllUid() const */ TFileName QS60MainApplication::ResourceFileName() const { - TFindFile finder(iCoeEnv->FsSession()); - TInt err = finder.FindByDir(KQtWrapperResourceFile, KNullDesC); - if (err == KErrNone) - return finder.File(); return KNullDesC(); } diff --git a/src/gui/s60framework/qs60mainappui.cpp b/src/gui/s60framework/qs60mainappui.cpp index ea9dbb3..92b3b55 100644 --- a/src/gui/s60framework/qs60mainappui.cpp +++ b/src/gui/s60framework/qs60mainappui.cpp @@ -50,16 +50,6 @@ #endif #include #include -#ifdef Q_WS_S60 -# if defined(QT_LIBINFIX_UNQUOTED) -// Two level macro needed for proper expansion of libinfix -# define QT_S60MAIN_RSG_2(x) -# define QT_S60MAIN_RSG(x) QT_S60MAIN_RSG_2(x) -# include QT_S60MAIN_RSG(QT_LIBINFIX_UNQUOTED) -# else -# include -# endif -#endif #include "qs60mainappui.h" #include @@ -125,8 +115,8 @@ void QS60MainAppUi::ConstructL() #ifdef Q_WS_S60 flags |= CAknAppUi::EAknEnableSkin; // After 5th Edition S60, native side supports animated wallpapers. - // However, there is no support for that feature on Qt side, so indicate to - // native UI framework that this application will not support background animations. + // However, there is no support for that feature on Qt side, so indicate to + // native UI framework that this application will not support background animations. if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) flags |= KAknDisableAnimationBackground; #endif @@ -244,7 +234,7 @@ void QS60MainAppUi::DynInitMenuBarL(TInt /* resourceId */, CEikMenuBar * /* menu void QS60MainAppUi::DynInitMenuPaneL(TInt resourceId, CEikMenuPane *menuPane) { #ifdef Q_WS_S60 - if (resourceId == R_QT_WRAPPERAPP_MENU) { + if (resourceId == R_AVKON_MENUPANE_EMPTY) { if (menuPane->NumberOfItemsInPane() <= 1) QT_TRYCATCH_LEAVING(qt_symbian_show_toplevel(menuPane)); @@ -274,7 +264,17 @@ void QS60MainAppUi::RestoreMenuL(CCoeControl *menuWindow, TInt resourceId, TMenu DynInitMenuPaneL(resourceId, (CEikMenuPane*)menuWindow); else DynInitMenuBarL(resourceId, (CEikMenuBar*)menuWindow); - } else + } else if(resourceId == R_AVKON_MENUPANE_EMPTY) { + CEikMenuBarTitle *title = new(ELeave) CEikMenuBarTitle; + CleanupStack::PushL(title); + + title->iData.iMenuPaneResourceId = R_AVKON_MENUPANE_EMPTY; + title->iTitleFlags = 0; + + S60->menuBar()->TitleArray()->AddTitleL(title); + CleanupStack::Pop( title ); + } + else #endif { QS60MainAppUiBase::RestoreMenuL(menuWindow, resourceId, menuType); diff --git a/src/gui/s60framework/s60framework.pri b/src/gui/s60framework/s60framework.pri index edbacc0..19525b7 100644 --- a/src/gui/s60framework/s60framework.pri +++ b/src/gui/s60framework/s60framework.pri @@ -1,21 +1,3 @@ -contains(QT_CONFIG, s60) { -# This block serves the minimalistic resource file for S60 3.1 platforms. -# Note there is no way to ifdef S60 version in mmp file, that is why the resource -# file is always compiled for WINSCW - - minimalAppResource31 = \ - "SOURCEPATH s60framework" \ - "START RESOURCE s60main.rss" \ - "TARGET s60main$${QT_LIBINFIX}" \ - "HEADER" \ - "TARGETPATH /resource/apps" \ - "END" - - MMP_RULES += minimalAppResource31 - - SYMBIAN_RESOURCES += s60framework/s60main.rss -} - SOURCES += s60framework/qs60mainapplication.cpp \ s60framework/qs60mainappui.cpp \ s60framework/qs60maindocument.cpp diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro index 1f622c0..c73ed06 100644 --- a/src/s60installs/s60installs.pro +++ b/src/s60installs/s60installs.pro @@ -11,10 +11,10 @@ symbian: { isEmpty(QT_LIBINFIX) { TARGET.UID3 = 0x2001E61C - + # Sqlite3 is expected to be already found on phone if infixed configuration is built. # It is also expected that devices newer than those based on S60 5.0 all have sqlite3.dll. - contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) { + contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) { BLD_INF_RULES.prj_exports += \ "sqlite3.sis /epoc32/data/qt/sis/sqlite3.sis" \ "sqlite3_selfsigned.sis /epoc32/data/qt/sis/sqlite3_selfsigned.sis" @@ -35,15 +35,6 @@ symbian: { } VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION} - symbian-abld|symbian-sbsv2 { - qtresources.sources = $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/s60main$${QT_LIBINFIX}.rsc - } else { - qtresources.sources = $$QMAKE_LIBDIR_QT/s60main$${QT_LIBINFIX}.rsc - DESTDIR = $$QMAKE_LIBDIR_QT - } - qtresources.path = c:$$APP_RESOURCE_DIR - DEPLOYMENT += qtresources - qtlibraries.sources = \ $$QMAKE_LIBDIR_QT/QtCore$${QT_LIBINFIX}.dll \ $$QMAKE_LIBDIR_QT/QtXml$${QT_LIBINFIX}.dll \ @@ -109,9 +100,9 @@ symbian: { qtlibraries.pkg_prerules = vendorinfo qtlibraries.pkg_prerules += "; Dependencies of Qt libraries" - + # It is expected that Symbian^3 and newer phones will have sufficiently new OpenC already installed - contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) { + contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) { qtlibraries.pkg_prerules += "(0x20013851), 1, 5, 1, {\"PIPS Installer\"}" contains(QT_CONFIG, openssl) | contains(QT_CONFIG, openssl-linked) { qtlibraries.pkg_prerules += "(0x200110CB), 1, 5, 1, {\"Open C LIBSSL Common\"}" diff --git a/src/s60main/s60main.rsg b/src/s60main/s60main.rsg deleted file mode 100644 index 8cdf3ba..0000000 --- a/src/s60main/s60main.rsg +++ /dev/null @@ -1,3 +0,0 @@ -#define R_DEFAULT_DOCUMENT_NAME 0x55567002 -#define R_QT_WRAPPERAPP_MENUBAR 0x55567004 -#define R_QT_WRAPPERAPP_MENU 0x55567005 -- cgit v0.12 From 7f875312dcc09a4b2dcc5030e813e921b1dc7ee4 Mon Sep 17 00:00:00 2001 From: Jason Barron Date: Thu, 7 Oct 2010 15:52:27 +0200 Subject: Fix crash when using Q_GLOBAL_STATIC(QWidget...) If Q_GLOBAL_STATIC is used with a QWidget (or subclass) then the destructor of QWidget will be executed after the destructor of QApplication. Since ~QApplication() destroys the S60 environment and the trap handler, we need to be sure that if QApplication is destroyed, we do not attempt to use anything from the S60 environment. This includes RWsSession and the trap handler. The fix is to avoid flushing the WSERV buffer if QApplication has been deleted already. Reviewed-by: axis --- src/gui/kernel/qwidget_s60.cpp | 3 ++- tests/auto/qapplication/tst_qapplication.cpp | 40 ++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 49d2ffc..9a451ce 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -1252,7 +1252,8 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows) // At this point the backing store should already be destroyed // so we flush the command buffer to ensure that the freeing of // those resources and deleting the window can happen "atomically" - S60->wsSession().Flush(); + if (qApp) + S60->wsSession().Flush(); } } diff --git a/tests/auto/qapplication/tst_qapplication.cpp b/tests/auto/qapplication/tst_qapplication.cpp index 91ae921..a198d7f 100644 --- a/tests/auto/qapplication/tst_qapplication.cpp +++ b/tests/auto/qapplication/tst_qapplication.cpp @@ -147,6 +147,10 @@ private slots: void symbianNeedForTraps(); void symbianLeaveThroughMain(); void qtbug_12673(); + + + + void globalStaticObjectDestruction(); // run this last }; class EventSpy : public QObject @@ -2257,6 +2261,42 @@ void tst_QApplication::qtbug_12673() #endif // Q_OS_SYMBIAN } +/* + This test is meant to ensure that certain objects (public & commonly used) + can safely be used in a Q_GLOBAL_STATIC such that their destructors are + executed *after* the destruction of QApplication. + */ +Q_GLOBAL_STATIC(QLocale, tst_qapp_locale); +Q_GLOBAL_STATIC(QProcess, tst_qapp_process); +Q_GLOBAL_STATIC(QFileSystemWatcher, tst_qapp_fileSystemWatcher); +Q_GLOBAL_STATIC(QSharedMemory, tst_qapp_sharedMemory); +Q_GLOBAL_STATIC(QElapsedTimer, tst_qapp_elapsedTimer); +Q_GLOBAL_STATIC(QMutex, tst_qapp_mutex); +Q_GLOBAL_STATIC(QWidget, tst_qapp_widget); +Q_GLOBAL_STATIC(QPixmap, tst_qapp_pixmap); +Q_GLOBAL_STATIC(QFont, tst_qapp_font); +Q_GLOBAL_STATIC(QRegion, tst_qapp_region); +Q_GLOBAL_STATIC(QFontDatabase, tst_qapp_fontDatabase); +Q_GLOBAL_STATIC(QCursor, tst_qapp_cursor); + +void tst_QApplication::globalStaticObjectDestruction() +{ + int argc = 1; + QApplication app(argc, &argv0, QApplication::GuiServer); + QVERIFY(tst_qapp_locale()); + QVERIFY(tst_qapp_process()); + QVERIFY(tst_qapp_fileSystemWatcher()); + QVERIFY(tst_qapp_sharedMemory()); + QVERIFY(tst_qapp_elapsedTimer()); + QVERIFY(tst_qapp_mutex()); + QVERIFY(tst_qapp_widget()); + QVERIFY(tst_qapp_pixmap()); + QVERIFY(tst_qapp_font()); + QVERIFY(tst_qapp_region()); + QVERIFY(tst_qapp_fontDatabase()); + QVERIFY(tst_qapp_cursor()); +} + //QTEST_APPLESS_MAIN(tst_QApplication) int main(int argc, char *argv[]) { -- cgit v0.12