summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKimmo Hämäläinen <kimmo.hamalainen@nokia.com>2010-11-18 13:33:44 +0200
committerAdam Endrodi <ext-adam.endrodi@nokia.com>2010-12-13 13:43:01 +0200
commit8fdc9bf05f8d3b4a62ad07461099e4d930019676 (patch)
treea40923202cd78db9246a3e288b66d84c145a243a
parentbacb3b4f9fda6067cd22c811a90dd078b212d5e3 (diff)
Implement new UI for application not responding
- MCompositeScene::drawItems(): don't clear the screen if there is no animation - don't ping window that is beneath an app window that does not support pinging - don't queue up more and more ping messages for hung windows
-rw-r--r--debian/control6
-rw-r--r--debian/mcompositor-l10n-engineering-english.install2
-rwxr-xr-xdebian/rules3
-rw-r--r--decorators/libdecorator/mabstractdecorator.cpp12
-rw-r--r--decorators/libdecorator/mabstractdecorator.h14
-rw-r--r--decorators/mdecorator/mdecoratorwindow.cpp152
-rw-r--r--decorators/mdecorator/mdecoratorwindow.h13
-rw-r--r--mcompositor.pro1
-rw-r--r--meegotouch_config.pri1
-rw-r--r--src/mcompositemanager.cpp22
-rw-r--r--src/mcompositemanager.h2
-rw-r--r--src/mcompositescene.cpp18
-rw-r--r--src/mcompositewindow.cpp35
-rw-r--r--src/mcompositewindow.h8
-rw-r--r--src/mdecoratorframe.cpp24
-rw-r--r--src/mdecoratorframe.h5
-rw-r--r--translations/recovery.ts27
-rw-r--r--translations/translations.pro7
18 files changed, 278 insertions, 74 deletions
diff --git a/debian/control b/debian/control
index 1de3753..fc66497 100644
--- a/debian/control
+++ b/debian/control
@@ -39,3 +39,9 @@ XB-Maemo-CI-Packages: mcompositor
XB-Maemo-CI-Stage: fast
Description: mcompositor functional testcases
.
+
+Package: mcompositor-l10n-engineering-english
+Section: devel
+Architecture: any
+Enhances: mcompositor
+Description: Engineering English translations for mcompositor
diff --git a/debian/mcompositor-l10n-engineering-english.install b/debian/mcompositor-l10n-engineering-english.install
new file mode 100644
index 0000000..c927b05
--- /dev/null
+++ b/debian/mcompositor-l10n-engineering-english.install
@@ -0,0 +1,2 @@
+usr/share/l10n/meegotouch/recovery.qm
+usr/share/doc/mcompositor-l10n-engineering-english/recovery.ts
diff --git a/debian/rules b/debian/rules
index 81d6ba9..e1868ea 100755
--- a/debian/rules
+++ b/debian/rules
@@ -89,7 +89,8 @@ install: build
#make $(PARALLEL_MAKEFLAGS) doc
#mkdir -p ${CURDIR}/debian/tmp/usr/share/doc/mcompositor/api
#cp -r doc/html/* ${CURDIR}/debian/tmp/usr/share/doc/mcompositor/api/
-
+ install -m 644 -D -p $(CURDIR)/translations/recovery.ts \
+ $(CURDIR)/debian/tmp/usr/share/doc/mcompositor-l10n-engineering-english/recovery.ts
# Build architecture-independent files here.
binary-indep: build install
diff --git a/decorators/libdecorator/mabstractdecorator.cpp b/decorators/libdecorator/mabstractdecorator.cpp
index c48422a..a150204 100644
--- a/decorators/libdecorator/mabstractdecorator.cpp
+++ b/decorators/libdecorator/mabstractdecorator.cpp
@@ -137,7 +137,19 @@ void MAbstractDecorator::setAvailableGeometry(const QRect& rect)
d->remote_compositor->invoke("MCompositeManager", "decoratorRectChanged", rect);
}
+void MAbstractDecorator::queryDialogAnswer(unsigned int w, bool a)
+{
+ Q_D(MAbstractDecorator);
+
+ d->remote_compositor->invoke("MCompositeManager", "queryDialogAnswer", w, a);
+}
+
void MAbstractDecorator::RemoteSetOnlyStatusbar(bool mode)
{
setOnlyStatusbar(mode);
}
+
+void MAbstractDecorator::RemoteShowQueryDialog(bool visible)
+{
+ showQueryDialog(visible);
+}
diff --git a/decorators/libdecorator/mabstractdecorator.h b/decorators/libdecorator/mabstractdecorator.h
index 789dc3f..923a2f0 100644
--- a/decorators/libdecorator/mabstractdecorator.h
+++ b/decorators/libdecorator/mabstractdecorator.h
@@ -52,6 +52,14 @@ public:
*/
void setAvailableGeometry(const QRect& rect);
+ /*!
+ * Informs the compositor what was the answer to the query dialog.
+ *
+ * \param window managed window that the answer concerns.
+ * \param yes_answer true if the answer was 'yes'.
+ */
+ void queryDialogAnswer(unsigned int window, bool yes_answer);
+
public slots:
/*!
@@ -72,6 +80,7 @@ public slots:
void RemoteSetAutoRotation(bool mode);
void RemoteSetClientGeometry(const QRect& rect);
void RemoteSetOnlyStatusbar(bool mode);
+ void RemoteShowQueryDialog(bool visible);
protected:
@@ -97,6 +106,11 @@ protected:
*/
virtual void setOnlyStatusbar(bool mode) = 0;
+ /*!
+ * Pure virtual function to show the "not responding" query dialog.
+ */
+ virtual void showQueryDialog(bool visible) = 0;
+
private:
Q_DECLARE_PRIVATE(MAbstractDecorator)
diff --git a/decorators/mdecorator/mdecoratorwindow.cpp b/decorators/mdecorator/mdecoratorwindow.cpp
index 1fbff89..9a7f01d 100644
--- a/decorators/mdecorator/mdecoratorwindow.cpp
+++ b/decorators/mdecorator/mdecoratorwindow.cpp
@@ -38,7 +38,8 @@
#include <X11/extensions/shape.h>
#include <mabstractdecorator.h>
-
+#include <mdesktopentry.h>
+#include <mbuttonmodel.h>
class MDecorator: public MAbstractDecorator
{
@@ -64,6 +65,7 @@ public:
XFree(p.value);
}
}
+ decorwindow->managedWindowChanged(window);
decorwindow->setInputRegion();
setAvailableGeometry(decorwindow->availableClientRect());
decorwindow->setWindowTitle(title);
@@ -73,6 +75,10 @@ protected:
virtual void activateEvent() {
}
+ virtual void showQueryDialog(bool visible) {
+ decorwindow->showQueryDialog(visible);
+ }
+
virtual void setAutoRotation(bool mode)
{
Q_UNUSED(mode)
@@ -104,8 +110,14 @@ static QRect windowRectFromGraphicsItem(const QGraphicsView &view,
#endif
MDecoratorWindow::MDecoratorWindow(QWidget *parent)
- : MWindow(parent)
+ : MWindow(parent),
+ messageBox(0),
+ managed_window(0)
{
+ locale.addTranslationPath(TRANSLATION_INSTALLDIR);
+ locale.installTrCatalog("recovery");
+ locale.setDefault(locale);
+
onlyStatusbarAtom = XInternAtom(QX11Info::display(),
"_MDECORATOR_ONLY_STATUSBAR", False);
managedWindowAtom = XInternAtom(QX11Info::display(),
@@ -123,6 +135,7 @@ MDecoratorWindow::MDecoratorWindow(QWidget *parent)
sceneManager()->appearSceneWindowNow(statusBar);
setOnlyStatusbar(false);
+ requested_only_statusbar = false;
d = new MDecorator(this);
connect(this, SIGNAL(homeClicked()), d, SLOT(minimize()));
@@ -132,6 +145,7 @@ MDecoratorWindow::MDecoratorWindow(QWidget *parent)
this,
SLOT(screenRotated(M::Orientation)));
+ setTranslucentBackground(true); // for translucent messageBox
setFocusPolicy(Qt::NoFocus);
setSceneSize();
setMDecoratorWindowProperty();
@@ -140,6 +154,25 @@ MDecoratorWindow::MDecoratorWindow(QWidget *parent)
setProperty("followsCurrentApplicationWindowOrientation", true);
}
+void MDecoratorWindow::yesButtonClicked()
+{
+ d->queryDialogAnswer(managed_window, true);
+ showQueryDialog(false);
+}
+
+void MDecoratorWindow::noButtonClicked()
+{
+ d->queryDialogAnswer(managed_window, false);
+ showQueryDialog(false);
+}
+
+void MDecoratorWindow::managedWindowChanged(Qt::HANDLE w)
+{
+ if (w != managed_window && messageBox)
+ showQueryDialog(false);
+ managed_window = w;
+}
+
void MDecoratorWindow::setWindowTitle(const QString& title)
{
navigationBar->setViewMenuDescription(title);
@@ -184,17 +217,61 @@ bool MDecoratorWindow::x11Event(XEvent *e)
return false;
}
-void MDecoratorWindow::setOnlyStatusbar(bool mode)
+void MDecoratorWindow::showQueryDialog(bool visible)
+{
+ if (visible && !messageBox) {
+ char name[100];
+ snprintf(name, 100, "window 0x%lx", managed_window);
+ XClassHint cls = {0, 0};
+ XGetClassHint(QX11Info::display(), managed_window, &cls);
+ if (cls.res_name) {
+ strncpy(name, cls.res_name, 100);
+ MDesktopEntry de(QString("/usr/share/applications/")
+ + name + ".desktop");
+ if (de.isValid() && !de.name().isEmpty())
+ strncpy(name, de.name().toAscii().data(), 100);
+ }
+ if (cls.res_class) XFree(cls.res_class);
+ if (cls.res_name) XFree(cls.res_name);
+
+ XSetTransientForHint(QX11Info::display(), winId(), managed_window);
+ requested_only_statusbar = only_statusbar;
+ setOnlyStatusbar(true, true);
+ messageBox = new MMessageBox(
+ qtTrId("qtn_reco_app_not_responding").replace("%1", name),
+ qtTrId("qtn_reco_close_app_question"),
+ M::NoStandardButton);
+ MButtonModel *yes = messageBox->addButton(qtTrId("qtn_comm_command_yes"),
+ M::AcceptRole);
+ MButtonModel *no = messageBox->addButton(qtTrId("qtn_comm_command_no"),
+ M::RejectRole);
+ connect(yes, SIGNAL(clicked()), this, SLOT(yesButtonClicked()));
+ connect(no, SIGNAL(clicked()), this, SLOT(noButtonClicked()));
+ sceneManager()->appearSceneWindowNow(messageBox);
+ } else if (!visible && messageBox) {
+ XSetTransientForHint(QX11Info::display(), winId(), None);
+ sceneManager()->disappearSceneWindowNow(messageBox);
+ delete messageBox;
+ messageBox = 0;
+ setOnlyStatusbar(requested_only_statusbar);
+ }
+ setInputRegion();
+ update();
+}
+
+void MDecoratorWindow::setOnlyStatusbar(bool mode, bool temporary)
{
if (mode) {
sceneManager()->disappearSceneWindowNow(navigationBar);
sceneManager()->disappearSceneWindowNow(homeButtonPanel);
sceneManager()->disappearSceneWindowNow(escapeButtonPanel);
- } else {
+ } else if (!messageBox) {
sceneManager()->appearSceneWindowNow(navigationBar);
sceneManager()->appearSceneWindowNow(homeButtonPanel);
sceneManager()->appearSceneWindowNow(escapeButtonPanel);
}
+ if (!temporary)
+ requested_only_statusbar = mode;
only_statusbar = mode;
}
@@ -246,34 +323,42 @@ void MDecoratorWindow::setInputRegion()
{
static XRectangle prev_rect = {0, 0, 0, 0};
QRegion region;
- QRect r_tmp(statusBar->geometry().toRect());
- region += statusBar->mapToScene(r_tmp).boundingRect().toRect();
- if (!only_statusbar) {
- r_tmp = QRect(navigationBar->geometry().toRect());
- region += navigationBar->mapToScene(r_tmp).boundingRect().toRect();
- r_tmp = QRect(homeButtonPanel->geometry().toRect());
- region += homeButtonPanel->mapToScene(r_tmp).boundingRect().toRect();
- r_tmp = QRect(escapeButtonPanel->geometry().toRect());
- region += escapeButtonPanel->mapToScene(r_tmp).boundingRect().toRect();
- }
-
const QRect fs(QApplication::desktop()->screenGeometry());
- decoratorRect = region.boundingRect();
- // crop it to fullscreen to work around a weird issue
- if (decoratorRect.width() > fs.width())
- decoratorRect.setWidth(fs.width());
- if (decoratorRect.height() > fs.height())
- decoratorRect.setHeight(fs.height());
-
- if (!only_statusbar && decoratorRect.width() > fs.width() / 2
- && decoratorRect.height() > fs.height() / 2) {
- // decorator is so big that it is probably in more than one part
- // (which is not yet supported)
- setOnlyStatusbar(true);
- r_tmp = statusBar->geometry().toRect();
- region = decoratorRect = statusBar->mapToScene(r_tmp).boundingRect().toRect();
+ XRectangle rect;
+ if (messageBox) {
+ region = decoratorRect = fs;
+ rect.x = fs.x();
+ rect.y = fs.y();
+ rect.width = fs.width();
+ rect.height = fs.height();
+ } else {
+ QRect r_tmp(statusBar->geometry().toRect());
+ region += statusBar->mapToScene(r_tmp).boundingRect().toRect();
+ if (!only_statusbar) {
+ r_tmp = QRect(navigationBar->geometry().toRect());
+ region += navigationBar->mapToScene(r_tmp).boundingRect().toRect();
+ r_tmp = QRect(homeButtonPanel->geometry().toRect());
+ region += homeButtonPanel->mapToScene(r_tmp).boundingRect().toRect();
+ r_tmp = QRect(escapeButtonPanel->geometry().toRect());
+ region += escapeButtonPanel->mapToScene(r_tmp).boundingRect().toRect();
+ }
+
+ decoratorRect = region.boundingRect();
+ // crop it to fullscreen to work around a weird issue
+ if (decoratorRect.width() > fs.width())
+ decoratorRect.setWidth(fs.width());
+ if (decoratorRect.height() > fs.height())
+ decoratorRect.setHeight(fs.height());
+
+ if (!only_statusbar && decoratorRect.width() > fs.width() / 2
+ && decoratorRect.height() > fs.height() / 2) {
+ // decorator is so big that it is probably in more than one part
+ // (which is not yet supported)
+ setOnlyStatusbar(true);
+ region = decoratorRect = statusBar->geometry().toRect();
+ }
+ rect = itemRectToScreenRect(decoratorRect);
}
- XRectangle rect = itemRectToScreenRect(decoratorRect);
if (memcmp(&prev_rect, &rect, sizeof(XRectangle))) {
Display *dpy = QX11Info::display();
XserverRegion shapeRegion = XFixesCreateRegion(dpy, &rect, 1);
@@ -284,13 +369,6 @@ void MDecoratorWindow::setInputRegion()
XSync(dpy, False);
prev_rect = rect;
}
-
- // selective compositing
- if (isVisible() && region.isEmpty()) {
- hide();
- } else if (!isVisible() && !region.isEmpty()) {
- show();
- }
}
void MDecoratorWindow::setSceneSize()
diff --git a/decorators/mdecorator/mdecoratorwindow.h b/decorators/mdecorator/mdecoratorwindow.h
index b17b1d9..d6cf589 100644
--- a/decorators/mdecorator/mdecoratorwindow.h
+++ b/decorators/mdecorator/mdecoratorwindow.h
@@ -23,7 +23,9 @@
#include <MHomeButtonPanel>
#include <MEscapeButtonPanel>
#include <MNavigationBar>
+#include <MMessageBox>
#include <mstatusbar.h>
+#include <mlocale.h>
#include <X11/Xlib.h>
#ifdef HAVE_SHAPECONST
@@ -48,7 +50,7 @@ public:
const QRect availableClientRect() const;
bool x11Event(XEvent *e);
void setWindowTitle(const QString& title);
- void setOnlyStatusbar(bool mode);
+ void setOnlyStatusbar(bool mode, bool temporary = false);
/*!
* \brief Sets the region of the window that can receive input events.
*
@@ -56,6 +58,8 @@ public:
* to the windows below.
*/
void setInputRegion();
+ void managedWindowChanged(Qt::HANDLE);
+ void showQueryDialog(bool visible);
protected:
virtual void closeEvent(QCloseEvent * event );
@@ -63,6 +67,8 @@ protected:
private slots:
void screenRotated(const M::Orientation &orientation);
+ void yesButtonClicked();
+ void noButtonClicked();
signals:
@@ -78,10 +84,13 @@ private:
MEscapeButtonPanel *escapeButtonPanel;
MNavigationBar *navigationBar;
MStatusBar *statusBar;
+ MMessageBox *messageBox;
+ Window managed_window;
QRect decoratorRect;
- bool only_statusbar;
+ bool only_statusbar, requested_only_statusbar;
Atom onlyStatusbarAtom, managedWindowAtom;
MDecorator *d;
+ MLocale locale;
Q_DISABLE_COPY(MDecoratorWindow);
};
diff --git a/mcompositor.pro b/mcompositor.pro
index f13a334..6909c1b 100644
--- a/mcompositor.pro
+++ b/mcompositor.pro
@@ -5,6 +5,7 @@ SUBDIRS = \
src \
mcompositor\
tests \
+ translations
src.depends=decorators
diff --git a/meegotouch_config.pri b/meegotouch_config.pri
index 5958dad..47edaee 100644
--- a/meegotouch_config.pri
+++ b/meegotouch_config.pri
@@ -32,6 +32,7 @@ contains(QT_CONFIG, opengles2) {
DEFINES += DESKTOP_VERSION
}
}
+DEFINES += TRANSLATION_INSTALLDIR=\\\"\"$$M_TRANSLATION_DIR\"\\\"
# Compositor components only
VERSION = 0.7.9
diff --git a/src/mcompositemanager.cpp b/src/mcompositemanager.cpp
index 45c42b0..5283554 100644
--- a/src/mcompositemanager.cpp
+++ b/src/mcompositemanager.cpp
@@ -1776,7 +1776,10 @@ void MCompositeManagerPrivate::pingTopmost()
cw->startPing();
found = true;
continue;
- }
+ } else if (!found && !saw_desktop && cw->isMapped()
+ && cw->isAppWindow(true))
+ // topmost app does not support pinging, don't ping things under it
+ found = true;
cw->stopPing();
}
}
@@ -2167,7 +2170,7 @@ void MCompositeManagerPrivate::checkStacking(bool force_visibility_check,
int home_i = stacking_list.indexOf(duihome);
for (int i = 0; i <= last_i; ++i) {
MCompositeWindow *cw = COMPOSITE_WINDOW(stacking_list.at(i));
- if (!cw || !cw->isMapped()) continue;
+ if (!cw || !cw->isMapped() || !cw->propertyCache()) continue;
if (device_state->displayOff()) {
cw->setWindowObscured(true);
// setVisible(false) is not needed because updates are frozen
@@ -2190,7 +2193,8 @@ void MCompositeManagerPrivate::checkStacking(bool force_visibility_check,
if (cw->window() != duihome)
cw->setVisible(false);
}
- if (!duihome || (duihome && i >= home_i))
+ if ((!duihome && !cw->propertyCache()->alwaysMapped())
+ || (duihome && i >= home_i))
setWindowState(cw->window(), NormalState);
}
}
@@ -2840,6 +2844,17 @@ void MCompositeManager::setWindowState(Window w, int state)
d->setWindowState(w, state);
}
+void MCompositeManager::queryDialogAnswer(unsigned int window, bool yes_answer)
+{
+ MCompositeWindow *cw = COMPOSITE_WINDOW(window);
+ if (!cw || !cw->propertyCache() || !cw->propertyCache()->isMapped())
+ return;
+ if (yes_answer)
+ d->closeHandler(cw);
+ else
+ cw->startDialogReappearTimer();
+}
+
void MCompositeManagerPrivate::setWindowDebugProperties(Window w)
{
#ifdef WINDOW_DEBUG
@@ -3529,6 +3544,7 @@ void MCompositeManagerPrivate::gotHungWindow(MCompositeWindow *w)
MDecoratorFrame::instance()->setManagedWindow(w, true);
MDecoratorFrame::instance()->setOnlyStatusbar(false);
MDecoratorFrame::instance()->setAutoRotation(true);
+ MDecoratorFrame::instance()->showQueryDialog(true);
dirtyStacking(false);
MDecoratorFrame::instance()->raise();
diff --git a/src/mcompositemanager.h b/src/mcompositemanager.h
index 748f104..e038aa2 100644
--- a/src/mcompositemanager.h
+++ b/src/mcompositemanager.h
@@ -158,6 +158,8 @@ public:
public slots:
void enableCompositing(bool forced = false);
void disableCompositing();
+ // called with the answer to mdecorator's dialog
+ void queryDialogAnswer(unsigned int window, bool yes_answer);
/*! Invoked remotely by MRmiClient to show a launch indicator
*
diff --git a/src/mcompositescene.cpp b/src/mcompositescene.cpp
index de35d80..56649d7 100644
--- a/src/mcompositescene.cpp
+++ b/src/mcompositescene.cpp
@@ -139,15 +139,17 @@ void MCompositeScene::drawItems(QPainter *painter, int numItems, QGraphicsItem *
// paint from bottom to top so that blending works
for (int i = size - 1; i >= 0; --i) {
int item_i = to_paint[i];
+ MCompositeWindow *cw = (MCompositeWindow*)items[item_i];
painter->save();
if (!desktop_painted) {
- // clear rubbish from the root window during startup when
- // desktop window does not exist and we show zoom animations
- glClearColor(0, 0, 0, 0);
- glClear(GL_COLOR_BUFFER_BIT);
+ if (cw->hasTransitioningWindow()) {
+ // clear rubbish from the root window during startup when
+ // desktop window does not exist and we show zoom animations
+ glClearColor(0, 0, 0, 0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
desktop_painted = true;
- if (((MCompositeWindow*)items[item_i])->
- propertyCache()->isDecorator()) {
+ if (cw->propertyCache()->isDecorator()) {
// don't paint decorator on top of plain black background
// (see NB#182860, NB#192454)
painter->restore();
@@ -155,8 +157,8 @@ void MCompositeScene::drawItems(QPainter *painter, int numItems, QGraphicsItem *
}
}
// TODO: paint only the intersected region (glScissor?)
- painter->setMatrix(items[item_i]->sceneMatrix(), true);
- items[item_i]->paint(painter, &options[item_i], widget);
+ painter->setMatrix(cw->sceneMatrix(), true);
+ cw->paint(painter, &options[item_i], widget);
painter->restore();
}
}
diff --git a/src/mcompositewindow.cpp b/src/mcompositewindow.cpp
index 799654f..e01814a 100644
--- a/src/mcompositewindow.cpp
+++ b/src/mcompositewindow.cpp
@@ -78,6 +78,8 @@ MCompositeWindow::MCompositeWindow(Qt::HANDLE window,
t_ping = new QTimer(this);
connect(t_ping, SIGNAL(timeout()), SLOT(pingTimeout()));
+ t_reappear = new QTimer(this);
+ connect(t_reappear, SIGNAL(timeout()), SLOT(reappearTimeout()));
damage_timer = new QTimer(this);
damage_timer->setSingleShot(true);
@@ -119,9 +121,9 @@ MCompositeWindow::~MCompositeWindow()
MCompositeManager *p = (MCompositeManager *) qApp;
p->d->removeWindow(window());
- if (window() && t_ping) {
+ if (window() && (t_ping || t_reappear)) {
stopPing();
- t_ping = 0;
+ t_ping = t_reappear = 0;
}
endAnimation();
@@ -561,6 +563,26 @@ void MCompositeWindow::stopPing()
pinging_enabled = false;
if (t_ping)
t_ping->stop();
+ if (t_reappear)
+ t_reappear->stop();
+}
+
+void MCompositeWindow::startDialogReappearTimer()
+{
+ if (!t_reappear || window_status != Hung)
+ return;
+ if (t_reappear->isActive())
+ t_reappear->stop();
+ t_reappear->setSingleShot(true);
+ t_reappear->setInterval(30 * 1000);
+ t_reappear->start();
+}
+
+void MCompositeWindow::reappearTimeout()
+{
+ if (window_status == Hung)
+ // show "application not responding" UI again
+ emit windowHung(this);
}
void MCompositeWindow::receivedPing(ulong serverTimeStamp)
@@ -571,14 +593,15 @@ void MCompositeWindow::receivedPing(ulong serverTimeStamp)
window_status = Normal;
if (blurred())
setBlurred(false);
+ if (t_reappear->isActive())
+ t_reappear->stop();
}
void MCompositeWindow::pingTimeout()
{
if (pinging_enabled && received_ping_timestamp < sent_ping_timestamp
- && window_status != Hung
+ && pc && pc->isMapped() && window_status != Hung
&& window_status != Minimizing && window_status != Closing) {
- setBlurred(true);
window_status = Hung;
emit windowHung(this);
}
@@ -589,6 +612,10 @@ void MCompositeWindow::pingTimeout()
void MCompositeWindow::pingWindow()
{
+ if (window_status == Hung)
+ // don't send a new ping before the window responds, otherwise we may
+ // queue up too many of them
+ return;
ulong t = QDateTime::currentDateTime().toTime_t();
sent_ping_timestamp = t;
Window w = window();
diff --git a/src/mcompositewindow.h b/src/mcompositewindow.h
index 2fc45be..ac45879 100644
--- a/src/mcompositewindow.h
+++ b/src/mcompositewindow.h
@@ -345,6 +345,11 @@ public slots:
* or on timeout.
*/
void damageReceived(bool timeout);
+
+ /*!
+ * Called to start a reappearance timer for the application hung dialog.
+ */
+ void startDialogReappearTimer();
private slots:
@@ -354,6 +359,7 @@ private slots:
void finalizeState();
void pingTimeout();
+ void reappearTimeout();
void damageTimeout();
void pingWindow();
void q_itemRestored();
@@ -420,7 +426,7 @@ private:
QPointF origPosition;
// Main ping timer
- QTimer *t_ping;
+ QTimer *t_ping, *t_reappear;
QTimer *damage_timer;
Qt::HANDLE win_id;
diff --git a/src/mdecoratorframe.cpp b/src/mdecoratorframe.cpp
index 7eaeffc..ad2ed19 100644
--- a/src/mdecoratorframe.cpp
+++ b/src/mdecoratorframe.cpp
@@ -104,13 +104,6 @@ void MDecoratorFrame::setManagedWindow(MCompositeWindow *cw,
client = cw;
qulonglong winid = client ? client->window() : 0;
- if (decorator_window) {
- long val = winid;
- Atom a = XInternAtom(QX11Info::display(),
- "_MDECORATOR_MANAGED_WINDOW", False);
- XChangeProperty(QX11Info::display(), decorator_window, a, XA_WINDOW,
- 32, PropModeReplace, (unsigned char *)&val, 1);
- }
if (!decorator_item)
return;
@@ -120,10 +113,8 @@ void MDecoratorFrame::setManagedWindow(MCompositeWindow *cw,
cw->propertyCache()->requestedGeometry());
remote_decorator->invoke("MAbstractDecorator",
"RemoteSetAutoRotation", false);
- /* FIXME: replaced with a window property due to reliability problems
remote_decorator->invoke("MAbstractDecorator",
"RemoteSetManagedWinId", winid);
- */
if (cw)
connect(cw, SIGNAL(destroyed()), SLOT(destroyClient()));
@@ -214,15 +205,12 @@ void MDecoratorFrame::setAutoRotation(bool mode)
void MDecoratorFrame::setOnlyStatusbar(bool mode)
{
- if (decorator_window) {
- long val = mode;
- Atom a = XInternAtom(QX11Info::display(),
- "_MDECORATOR_ONLY_STATUSBAR", False);
- XChangeProperty(QX11Info::display(), decorator_window, a, XA_CARDINAL,
- 32, PropModeReplace, (unsigned char *)&val, 1);
- }
- /* FIXME: replaced with a window property due to reliability problems
remote_decorator->invoke("MAbstractDecorator",
"RemoteSetOnlyStatusbar", mode);
- */
+}
+
+void MDecoratorFrame::showQueryDialog(bool visible)
+{
+ remote_decorator->invoke("MAbstractDecorator",
+ "RemoteShowQueryDialog", visible);
}
diff --git a/src/mdecoratorframe.h b/src/mdecoratorframe.h
index afb26e3..b8ef400 100644
--- a/src/mdecoratorframe.h
+++ b/src/mdecoratorframe.h
@@ -85,6 +85,11 @@ public:
void setOnlyStatusbar(bool mode);
/*!
+ * Show/hide the query dialog.
+ */
+ void showQueryDialog(bool visible);
+
+ /*!
* Sets the decorator window and maps that window if it is unmapped.
*/
void setDecoratorWindow(Qt::HANDLE window);
diff --git a/translations/recovery.ts b/translations/recovery.ts
new file mode 100644
index 0000000..35d42e5
--- /dev/null
+++ b/translations/recovery.ts
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<context>
+ <name></name>
+ <message id="qtn_reco_app_not_responding">
+ <location filename="../decorators/mdecorator/mdecoratorwindow.cpp" line="241"/>
+ <source></source>
+ <translation>%1 sucks</translation>
+ </message>
+ <message id="qtn_reco_close_app_question">
+ <location filename="../decorators/mdecorator/mdecoratorwindow.cpp" line="242"/>
+ <source></source>
+ <translation>Do you want to close it?</translation>
+ </message>
+ <message id="qtn_comm_command_yes">
+ <location filename="../decorators/mdecorator/mdecoratorwindow.cpp" line="244"/>
+ <source></source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message id="qtn_comm_command_no">
+ <location filename="../decorators/mdecorator/mdecoratorwindow.cpp" line="246"/>
+ <source></source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/translations/translations.pro b/translations/translations.pro
new file mode 100644
index 0000000..a0b5b3d
--- /dev/null
+++ b/translations/translations.pro
@@ -0,0 +1,7 @@
+LANGUAGES = # empty, means to build only engineering English
+SOURCEDIR = $$PWD/..
+CATALOGNAME = recovery
+TRANSLATIONDIR = $$PWD
+TRANSLATION_INSTALLDIR = $$M_TRANSLATION_DIR
+include($$[QT_INSTALL_DATA]/mkspecs/features/meegotouch_defines.prf)
+include($$[QT_INSTALL_DATA]/mkspecs/features/meegotouch_translations.prf)