aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Waterman <david.waterman@nokia.com>2010-07-14 08:06:28 +0300
committerDominik Kapusta <dominik.kapusta@teleca.com>2010-08-03 15:40:28 +0200
commit6e3d8a5cbe4053057845d1d0cb3a531e3fc44370 (patch)
tree4d789f340190629f344418bf847fec45615f16fd
parent9a8e7b55f6d1f973e94bab1feae25b3397231d35 (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/.gitignore1
-rw-r--r--examples/chaining/chainingexampleapp2/.gitignore4
-rw-r--r--examples/chaining/chainingexampleapp2/imageviewer.cpp1
-rw-r--r--examples/chaining/chainingexampleinterface/.gitignore4
-rw-r--r--src/corelib/core/mcomponentdata.cpp27
-rw-r--r--src/corelib/core/mcomponentdata.h16
-rw-r--r--src/corelib/core/mcomponentdata_p.h5
-rw-r--r--src/corelib/widgets/mapplicationwindow.cpp35
-rw-r--r--src/corelib/widgets/mapplicationwindow_p.h7
-rw-r--r--src/corelib/widgets/mwindow.cpp4
-rw-r--r--src/corelib/widgets/mwindow_p.h2
-rw-r--r--tools/m-servicefwgen.d/m-servicefwgen.cpp69
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*");