diff options
author | Max Waterman <david.waterman@nokia.com> | 2010-07-14 08:06:28 +0300 |
---|---|---|
committer | Dominik Kapusta <dominik.kapusta@teleca.com> | 2010-08-03 15:40:28 +0200 |
commit | 6e3d8a5cbe4053057845d1d0cb3a531e3fc44370 (patch) | |
tree | 4d789f340190629f344418bf847fec45615f16fd | |
parent | 9a8e7b55f6d1f973e94bab1feae25b3397231d35 (diff) |
Fixes: NB#172283 - There should be proper animation when launching a child application window via task chaining
RevBy: Tomas, Daniel
Details:
Does the framework-side changes required to trigger the compositor to do the transition animation.
Also moved the framework-side code for the task switcher view stacking into the same place.
-rw-r--r-- | examples/chaining/chainingexampleapp1/.gitignore | 1 | ||||
-rw-r--r-- | examples/chaining/chainingexampleapp2/.gitignore | 4 | ||||
-rw-r--r-- | examples/chaining/chainingexampleapp2/imageviewer.cpp | 1 | ||||
-rw-r--r-- | examples/chaining/chainingexampleinterface/.gitignore | 4 | ||||
-rw-r--r-- | src/corelib/core/mcomponentdata.cpp | 27 | ||||
-rw-r--r-- | src/corelib/core/mcomponentdata.h | 16 | ||||
-rw-r--r-- | src/corelib/core/mcomponentdata_p.h | 5 | ||||
-rw-r--r-- | src/corelib/widgets/mapplicationwindow.cpp | 35 | ||||
-rw-r--r-- | src/corelib/widgets/mapplicationwindow_p.h | 7 | ||||
-rw-r--r-- | src/corelib/widgets/mwindow.cpp | 4 | ||||
-rw-r--r-- | src/corelib/widgets/mwindow_p.h | 2 | ||||
-rw-r--r-- | tools/m-servicefwgen.d/m-servicefwgen.cpp | 69 |
12 files changed, 103 insertions, 72 deletions
diff --git a/examples/chaining/chainingexampleapp1/.gitignore b/examples/chaining/chainingexampleapp1/.gitignore new file mode 100644 index 00000000..bdcd319e --- /dev/null +++ b/examples/chaining/chainingexampleapp1/.gitignore @@ -0,0 +1 @@ +chainingexampleapp1 diff --git a/examples/chaining/chainingexampleapp2/.gitignore b/examples/chaining/chainingexampleapp2/.gitignore new file mode 100644 index 00000000..cf6213e5 --- /dev/null +++ b/examples/chaining/chainingexampleapp2/.gitignore @@ -0,0 +1,4 @@ +chainingexampleapp2 +chainingexampleinterfaceadaptor.cpp +chainingexampleinterfaceadaptor.h +com.nokia.ChainingExampleInterface.xml diff --git a/examples/chaining/chainingexampleapp2/imageviewer.cpp b/examples/chaining/chainingexampleapp2/imageviewer.cpp index 95fc32b6..ef168a2f 100644 --- a/examples/chaining/chainingexampleapp2/imageviewer.cpp +++ b/examples/chaining/chainingexampleapp2/imageviewer.cpp @@ -20,7 +20,6 @@ ImageViewer::~ImageViewer() bool ImageViewer::showImage(const QString &uri, const QStringList &uriList) { - qDebug() << "MAXMAXMAX" << __PRETTY_FUNCTION__; Q_UNUSED( uri ); MApplicationWindow *mWin = new MApplicationWindow(); diff --git a/examples/chaining/chainingexampleinterface/.gitignore b/examples/chaining/chainingexampleinterface/.gitignore new file mode 100644 index 00000000..11f8ec2f --- /dev/null +++ b/examples/chaining/chainingexampleinterface/.gitignore @@ -0,0 +1,4 @@ +chainingexampleinterface.cpp +chainingexampleinterface.h +chainingexampleinterfaceproxy.cpp +chainingexampleinterfaceproxy.h diff --git a/src/corelib/core/mcomponentdata.cpp b/src/corelib/core/mcomponentdata.cpp index 164d1641..cd6237b8 100644 --- a/src/corelib/core/mcomponentdata.cpp +++ b/src/corelib/core/mcomponentdata.cpp @@ -446,7 +446,7 @@ void MComponentDataPrivate::init(int &argc, char **argv, const QString &appIdent q->setShowCursor(showCursor); } -void MComponentDataPrivate::parseArguments(int &argc, char **argv, +void MComponentDataPrivate::parseArguments(int &argc, char **argv, MTheme::ThemeService &themeService) // argc and argv (in and out): command line arguments, used ones are removed // themeService (out): value changed if theme service is defined in arguments @@ -683,7 +683,7 @@ void MComponentData::reinit(int &argc, char **argv, const QString &appIdentifier Q_D(MComponentData); MTheme::ThemeService themeService = MTheme::AnyTheme; - d->parseArguments(argc, argv, + d->parseArguments(argc, argv, themeService); if (d->service) { @@ -696,7 +696,7 @@ void MComponentData::reinit(int &argc, char **argv, const QString &appIdentifier QFileInfo fileInfo(argv[0]); d->appName = fileInfo.fileName(); } - + MLocale systemLocale; systemLocale.installTrCatalog(d->appName); MLocale::setDefault(systemLocale); @@ -1074,3 +1074,24 @@ bool MComponentData::isOrientationForced() } return gMComponentDataPrivate->isOrientationForced; } + +QStack<WId> MComponentDataPrivate::chainedWinIds; + +void MComponentData::pushChainedWindowId(const WId &parentWinId) +{ + MComponentDataPrivate::chainedWinIds.push(parentWinId); +} + +WId MComponentData::popChainedWindowId() +{ + WId retVal = MComponentDataPrivate::chainedWinIds.pop(); + + return retVal; +} + +bool MComponentData::chainedWindowIdStackIsEmpty() +{ + bool retVal = MComponentDataPrivate::chainedWinIds.isEmpty(); + + return retVal; +} diff --git a/src/corelib/core/mcomponentdata.h b/src/corelib/core/mcomponentdata.h index 26d06c6e..5e3e6fc6 100644 --- a/src/corelib/core/mcomponentdata.h +++ b/src/corelib/core/mcomponentdata.h @@ -174,6 +174,22 @@ public: static M::OrientationAngle forcedOrientationAngle(); static bool isOrientationForced(); + + /** + * Pushes a window id to the stack of chained window ids + * \param X11 window id of parent window + */ + static void pushChainedWindowId(const WId &parentWindowId); + + /** + * Pops a window id off the stack of chained window ids + */ + static WId popChainedWindowId(); + + /** + * Returns if the chained windiw id stack is empty + */ + static bool chainedWindowIdStackIsEmpty(); //! \internal_end Q_SIGNALS: diff --git a/src/corelib/core/mcomponentdata_p.h b/src/corelib/core/mcomponentdata_p.h index 6c52075a..db9847c3 100644 --- a/src/corelib/core/mcomponentdata_p.h +++ b/src/corelib/core/mcomponentdata_p.h @@ -21,6 +21,7 @@ #define MCOMPONENTDATA_P_H #include <QObject> +#include <QStack> #include <MLocale> #ifdef Q_WS_X11 #include <X11/Xlib.h> @@ -80,6 +81,10 @@ public: TestabilityInterface *testabilityInterface; #endif +#ifdef Q_WS_X11 + static QStack<WId> chainedWinIds; +#endif + protected: MComponentData *q_ptr; private: diff --git a/src/corelib/widgets/mapplicationwindow.cpp b/src/corelib/widgets/mapplicationwindow.cpp index 1d4da6ea..d3b99958 100644 --- a/src/corelib/widgets/mapplicationwindow.cpp +++ b/src/corelib/widgets/mapplicationwindow.cpp @@ -89,6 +89,8 @@ MApplicationWindowPrivate::MApplicationWindowPrivate() , menu(new MApplicationMenu) , isMenuOpen(false) , pageAreaMaximized(false) + , isChained(false) + , chainParentWinId(0) #ifdef HAVE_CONTEXTSUBSCRIBER , callStatusProperty("Phone.Call") #endif @@ -135,6 +137,12 @@ void MApplicationWindowPrivate::init() q, SLOT(_q_placeToolBar(M::Orientation))); #ifdef Q_WS_X11 + if ( !MComponentData::chainedWindowIdStackIsEmpty() ) { + chainParentWinId = MComponentData::popChainedWindowId(); + isChained = true; + + setWindowChainedProperty( chainParentWinId, q->winId() ); + } addMStatusBarOverlayProperty(); appendMApplicationWindowTypeProperty(); #endif @@ -186,6 +194,21 @@ void MApplicationWindowPrivate::init() q, SLOT(_q_inputPanelAreaChanged(const QRect &))); } +void MApplicationWindowPrivate::setWindowChainedProperty( const Window &parentWinId, const Window &childWinId ) +{ + Atom atomMInvokedBy = XInternAtom(QX11Info::display(), "_MEEGOTOUCH_WM_INVOKED_BY", False); + Display *display = QX11Info::display(); + + // for compositor page transition + XChangeProperty(display, childWinId, + atomMInvokedBy, XA_WINDOW, + 32, PropModeReplace, + (unsigned char *)&parentWinId, 1); + + // for task switcher view stacking + XSetTransientForHint(display, childWinId, parentWinId); +} + #ifdef Q_WS_X11 void MApplicationWindowPrivate::addMStatusBarOverlayProperty() { @@ -652,6 +675,7 @@ void MApplicationWindowPrivate::updateDockWidgetVisibility() void MApplicationWindowPrivate::sceneWindowAppearEvent(MSceneWindowEvent *event) { + Q_Q(MApplicationWindow); // Note that, when listening scene window state changed events, the actual state // of the scene window is not yet changed, and is needed to store separately // before call to _q_updatePageExposedContentRect(). @@ -661,6 +685,17 @@ void MApplicationWindowPrivate::sceneWindowAppearEvent(MSceneWindowEvent *event) switch (sceneWindow->windowType()) { case MSceneWindow::ApplicationPage: applicationPageAppearEvent(event); + + if ( isChained && sceneManager ) { + bool pageWindowIsFirstOne = sceneManager->pageHistory().isEmpty(); + if ( pageWindowIsFirstOne ) { + MApplicationPage *page = static_cast<MApplicationPage *>(sceneWindow); + if ( page ) { + page->setEscapeMode( MApplicationPageModel::EscapeManualBack ); + QObject::connect( page, SIGNAL( backButtonClicked() ), q, SLOT( close() ) ); + } + } + } break; case MSceneWindow::StatusBar: diff --git a/src/corelib/widgets/mapplicationwindow_p.h b/src/corelib/widgets/mapplicationwindow_p.h index 538690e9..58836951 100644 --- a/src/corelib/widgets/mapplicationwindow_p.h +++ b/src/corelib/widgets/mapplicationwindow_p.h @@ -66,6 +66,10 @@ public: QList<MSceneWindow *> componentsOnAutoHide; bool isMenuOpen; bool pageAreaMaximized; +#ifdef Q_WS_X11 + bool isChained; + WId chainParentWinId; +#endif #ifdef HAVE_CONTEXTSUBSCRIBER ContextProperty callStatusProperty; @@ -145,6 +149,9 @@ private: void initAutoHideComponentsTimer(); void removePageActions(); QAction* findPageCheckedAction() const; +#ifdef Q_WS_X11 + void setWindowChainedProperty( const WId &parentWinId, const WId &childWinId ); +#endif public: void _q_pageTitleChanged(MApplicationPage *, const QString &); void _q_actionUpdated(QActionEvent *e); diff --git a/src/corelib/widgets/mwindow.cpp b/src/corelib/widgets/mwindow.cpp index d0c24e3e..844ed5cb 100644 --- a/src/corelib/widgets/mwindow.cpp +++ b/src/corelib/widgets/mwindow.cpp @@ -289,7 +289,7 @@ void MWindowPrivate::appendVisibilityChangeMask() void MWindowPrivate::_q_onPixmapRequestsFinished() { Q_Q(MWindow); - + q->disconnect(MTheme::instance(), SIGNAL(pixmapRequestsFinished()), q, SLOT(_q_onPixmapRequestsFinished())); q->setVisible(true); @@ -1112,7 +1112,7 @@ void MWindow::setVisible(bool visible) // the performance. connect(MTheme::instance(), SIGNAL(pixmapRequestsFinished()), this, SLOT(_q_onPixmapRequestsFinished())); - return; + return; } else { if (windowState() != Qt::WindowMinimized && !MApplication::softwareRendering() && d->glWidget == 0) { d->initGLViewport(); diff --git a/src/corelib/widgets/mwindow_p.h b/src/corelib/widgets/mwindow_p.h index c37c66dc..58262b2d 100644 --- a/src/corelib/widgets/mwindow_p.h +++ b/src/corelib/widgets/mwindow_p.h @@ -57,7 +57,7 @@ public: qreal getX11Property(const char *propertyName) const; void setX11PrestartProperty(bool set); #endif - + void _q_onPixmapRequestsFinished(); QGLWidget *glWidget; diff --git a/tools/m-servicefwgen.d/m-servicefwgen.cpp b/tools/m-servicefwgen.d/m-servicefwgen.cpp index 93044fb2..90707360 100644 --- a/tools/m-servicefwgen.d/m-servicefwgen.cpp +++ b/tools/m-servicefwgen.d/m-servicefwgen.cpp @@ -820,7 +820,6 @@ void processAdaptorCppFile() QString previousLine; bool inChainTask = false; - bool needGoBackMethod = false; while (!inS.atEnd()) { QString line = inS.readLine(); @@ -846,9 +845,7 @@ void processAdaptorCppFile() if (w.needsMApplication() && line.contains(QRegExp("#include <QtCore/Q(Meta)?Object>"))) { outS << "\n" \ - "#include <MApplication>\n" \ - "#include <MApplicationPage>\n" \ - "#include <MApplicationWindow>\n" \ + "#include <MComponentData>\n" \ "#include <MDebug>\n" \ "\n" \ "#ifdef Q_WS_X11\n" \ @@ -857,45 +854,16 @@ void processAdaptorCppFile() "#endif // Q_WS_X11\n" \ "\n" + line + "\n"; - } else if (w.needsMApplication() && line.contains("QDBusAbstractAdaptor(parent)")) { - outS - << line + "," << endl - << " windowId(-1)" << endl; } else if (inChainTask) { line.remove(w.chainTag()); if (line == "{") { outS << line << endl - << " this->windowId = windowId;" << endl + << " MComponentData::pushChainedWindowId( windowId );" << endl << endl; } else if (line.contains("return") || line == "}") { // match end of function - need to add the connect *before* the return, if there is one - outS << -"\n"\ -" MApplicationWindow *appWindow = MApplication::activeApplicationWindow();\n"\ -" if (appWindow != 0) {\n"\ -"\n"\ -" MApplicationPage *currentPage = appWindow->currentPage();\n"\ -"\n"\ -" if ( currentPage != 0 ) {\n"\ -" currentPage->setEscapeMode( MApplicationPageModel::EscapeManualBack );\n"\ -" // connect to the back button - assumes the above method opens a\n"\ -" // new window and so the window referred to below is already the top one\n"\ -" connect(currentPage, SIGNAL(backButtonClicked()),\n"\ -" this, SLOT(goBack()));\n"\ -" } else {\n"\ -" mDebug( __PRETTY_FUNCTION__ ) << \"No currentPage! - broken chain\";\n"\ -" }\n"\ -" } else {\n"\ -" mDebug( __PRETTY_FUNCTION__ ) << \"No activeApplicationWindow! - broken chain\";\n"\ -" }\n"\ -"\n"\ -"#ifdef Q_WS_X11\n"\ -" // update the X server\n"\ -" XSetTransientForHint(QX11Info::display(), appWindow->winId(), windowId);\n"\ -"#endif // Q_WS_X11\n"\ -"\n" -+ line + "\n"; inChainTask = false; + outS << line << endl; } else { outS << line << endl; } @@ -911,7 +879,6 @@ void processAdaptorCppFile() outS << line << endl; inChainTask = true; - needGoBackMethod = true; } else if (line.contains("This file was generated by")) { outS << w.generatedByComment() << endl; } else if (line.contains( "Command line was:")) { @@ -924,24 +891,6 @@ void processAdaptorCppFile() previousLine = line; } - if (needGoBackMethod) { - outS << -"void " + w.upperCamelAdaptorName() + "::goBack()\n"\ -"{\n" \ -" bool backServiceRegistered = ( windowId != -1 );\n"\ -" if ( backServiceRegistered ) {\n"\ -" // All we need to do is close the window as it has the WM_TRANSIENT_FOR set\n"\ -" // the compositor should bring out the parent window\n"\ -" MApplicationWindow *appWindow = MApplication::activeApplicationWindow();\n"\ -" if ( appWindow != 0 ) {\n"\ -" appWindow->close();\n"\ -" }\n"\ -" } else {\n"\ -" qWarning() << \"backService is not registered: not going back\";\n"\ -" }\n"\ -"}\n"; - } - if (w.hasNameSpace()) { outS << endl; outS << "}; // namespace" << endl; @@ -1001,17 +950,7 @@ void processAdaptorHeaderFile() } } - if (line.contains("Q_SIGNALS:")) { - if (hasChains) { - newAdaptorHeaderStream - << " void goBack();" << endl - << "" << endl - << "private:" << endl - << " int windowId;" << endl - << "" << endl; - } - newAdaptorHeaderStream << line << endl; - } else if (line.contains(QRegExp("chainTask=\\\\\"\\w+\\\\\"")) || line.contains(QRegExp("asyncTask=\\\\\"\\w+\\\\\""))) { // process comment - remember the backslashes are in the source too, hence so many of them + if (line.contains(QRegExp("chainTask=\\\\\"\\w+\\\\\"")) || line.contains(QRegExp("asyncTask=\\\\\"\\w+\\\\\""))) { // process comment - remember the backslashes are in the source too, hence so many of them // remove asyncTask attribute { QRegExp matchThis("asyncTask=\\\\\"\\w+\\\\\"\\s*"); |