summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mcompositemanager.cpp34
-rw-r--r--src/mcompositewindow.cpp37
-rw-r--r--src/mcompositewindow.h15
-rw-r--r--src/mtexturepixmapitem_egl.cpp6
-rw-r--r--src/mtexturepixmapitem_glx.cpp6
-rw-r--r--src/mtexturepixmapitem_p.cpp19
-rw-r--r--src/mtexturepixmapitem_p.h5
-rw-r--r--src/mwindowpropertycache.cpp3
-rw-r--r--src/mwindowpropertycache.h18
9 files changed, 96 insertions, 47 deletions
diff --git a/src/mcompositemanager.cpp b/src/mcompositemanager.cpp
index 0bde2e1..d43f5ab 100644
--- a/src/mcompositemanager.cpp
+++ b/src/mcompositemanager.cpp
@@ -347,15 +347,18 @@ public:
return d;
}
- void requestMap(Window window)
+ void requestMap(MWindowPropertyCache *window)
{
if (!((MCompositeManager *) qApp)->isCompositing()
// if something is already queueing, add to the queue, otherwise
// the mapping order goes wrong
|| !map_requests.isEmpty())
map_requests.push_back(window);
- else
- XMapWindow(QX11Info::display(), window);
+ else {
+ // create the damage object before mapping to get 'em all
+ window->damageTracking(true);
+ XMapWindow(QX11Info::display(), window->winId());
+ }
}
public slots:
@@ -363,13 +366,15 @@ public slots:
{
while (!map_requests.isEmpty()) {
// first come first served
- Window w = map_requests.takeFirst();
- XMapWindow(QX11Info::display(), w);
+ MWindowPropertyCache *w = map_requests.takeFirst();
+ // create the damage object before mapping to get 'em all
+ w->damageTracking(true);
+ XMapWindow(QX11Info::display(), w->winId());
}
}
private:
- QList<Window> map_requests;
+ QList<MWindowPropertyCache*> map_requests;
explicit MapRequesterPrivate(QObject* parent = 0)
:QObject(parent)
{}
@@ -836,8 +841,11 @@ void MCompositeManagerPrivate::damageEvent(XDamageNotifyEvent *e)
XFixesDestroyRegion(QX11Info::display(), r);
MCompositeWindow *item = COMPOSITE_WINDOW(e->drawable);
- if (item && rects)
+ if (item && rects) {
item->updateWindowPixmap(rects, num);
+ if (item->waitingForDamage())
+ item->damageReceived(false);
+ }
if (rects)
XFree(rects);
@@ -1418,7 +1426,7 @@ void MCompositeManagerPrivate::mapRequestEvent(XMapRequestEvent *e)
if (needDecoration(e->window, pc)) {
if (MDecoratorFrame::instance()->decoratorItem()) {
enableCompositing();
- MapRequesterPrivate::instance()->requestMap(e->window);
+ MapRequesterPrivate::instance()->requestMap(pc);
// initially visualize decorator item so selective compositing
// checks won't disable compositing
MDecoratorFrame::instance()->decoratorItem()->setVisible(true);
@@ -1464,7 +1472,7 @@ void MCompositeManagerPrivate::mapRequestEvent(XMapRequestEvent *e)
XReparentWindow(QX11Info::display(), e->window,
frame->windowArea(), 0, 0);
setWindowState(e->window, NormalState);
- MapRequesterPrivate::instance()->requestMap(e->window);
+ MapRequesterPrivate::instance()->requestMap(pc);
frame->show();
XSync(QX11Info::display(), False);
@@ -1475,7 +1483,7 @@ void MCompositeManagerPrivate::mapRequestEvent(XMapRequestEvent *e)
setWindowState(e->window, IconicState);
else
setWindowState(e->window, NormalState);
- MapRequesterPrivate::instance()->requestMap(e->window);
+ MapRequesterPrivate::instance()->requestMap(pc);
}
}
@@ -2076,9 +2084,11 @@ void MCompositeManagerPrivate::mapEvent(XMapEvent *e)
// TODO: don't show the animation if the window is not stacked on top
const XWMHints &h = pc->getWMHints();
if ((!(h.flags & StateHint) || h.initial_state != IconicState)
- && !pc->isInputOnly())
+ && !pc->isInputOnly()) {
+ // remapped/prestarted apps should also have startup animation
+ item->setNewlyMapped(true);
item->showWindow();
- else {
+ } else {
item->setVisible(true);
item->setNewlyMapped(false);
}
diff --git a/src/mcompositewindow.cpp b/src/mcompositewindow.cpp
index 0252485..59c9a2f 100644
--- a/src/mcompositewindow.cpp
+++ b/src/mcompositewindow.cpp
@@ -53,6 +53,7 @@ MCompositeWindow::MCompositeWindow(Qt::HANDLE window,
is_transitioning(false),
pinging_enabled(false),
dimmed_effect(false),
+ waiting_for_damage(0),
win_id(window)
{
thumb_mode = false;
@@ -76,6 +77,10 @@ MCompositeWindow::MCompositeWindow(Qt::HANDLE window,
t_ping = new QTimer(this);
connect(t_ping, SIGNAL(timeout()), SLOT(pingTimeout()));
+
+ damage_timer = new QTimer(this);
+ damage_timer->setSingleShot(true);
+ connect(damage_timer, SIGNAL(timeout()), SLOT(damageTimeout()));
MCompAtoms* atoms = MCompAtoms::instance();
if (pc->windowType() == MCompAtoms::NORMAL)
@@ -321,11 +326,28 @@ void MCompositeWindow::showWindow()
// NB#180628 - some stupid apps are listening for visibilitynotifies.
// Well, all of the toolkit anyways
setWindowObscured(false);
- QTimer::singleShot(700, this, SLOT(q_fadeIn()));
+ // waiting for two damage events seems to work for Meegotouch apps
+ // at least, for the rest, there is a timeout
+ waiting_for_damage = 2;
+ damage_timer->start(500);
} else
q_fadeIn();
}
+void MCompositeWindow::damageTimeout()
+{
+ damageReceived(true);
+}
+
+void MCompositeWindow::damageReceived(bool timeout)
+{
+ if (timeout || (waiting_for_damage > 0 && !--waiting_for_damage)) {
+ damage_timer->stop();
+ waiting_for_damage = 0;
+ q_fadeIn();
+ }
+}
+
void MCompositeWindow::q_fadeIn()
{
endAnimation();
@@ -403,7 +425,10 @@ void MCompositeWindow::finalizeState()
iconify_state = NoIconifyState;
iconified_final = false;
show();
- QTimer::singleShot(200, this, SLOT(q_itemRestored()));
+ // no delay: window does not need to be repainted when restoring
+ // from the switcher (even then the animation should take long enough
+ // to allow it)
+ q_itemRestored();
}
window_status = Normal;
@@ -613,14 +638,6 @@ bool MCompositeWindow::hasTransitioningWindow()
return window_transitioning > 0;
}
-void MCompositeWindow::q_delayShow()
-{
- MCompositeWindow::setVisible(true);
- updateWindowPixmap();
- MCompositeManager *p = (MCompositeManager *) qApp;
- p->d->updateWinList();
-}
-
QVariant MCompositeWindow::itemChange(GraphicsItemChange change, const QVariant &value)
{
MCompositeManager *p = (MCompositeManager *) qApp;
diff --git a/src/mcompositewindow.h b/src/mcompositewindow.h
index 1efb022..add9df5 100644
--- a/src/mcompositewindow.h
+++ b/src/mcompositewindow.h
@@ -170,6 +170,11 @@ public:
void setUntransformed();
/*!
+ * True if this window is waiting for damage event before it can animate.
+ */
+ bool waitingForDamage() const { return waiting_for_damage > 0; }
+
+ /*!
* Returns how this window was iconified.
*/
IconifyState iconifyState() const;
@@ -326,6 +331,12 @@ public slots:
* effects
*/
void endAnimation();
+
+ /*!
+ * Called on first showing of a window when first damage event is received
+ * or on timeout.
+ */
+ void damageReceived(bool timeout);
private slots:
@@ -335,8 +346,8 @@ private slots:
void finalizeState();
void pingTimeout();
+ void damageTimeout();
void pingWindow();
- void q_delayShow();
void q_itemRestored();
void q_fadeIn();
@@ -394,6 +405,7 @@ private:
bool is_transitioning;
bool pinging_enabled;
bool dimmed_effect;
+ char waiting_for_damage;
static int window_transitioning;
@@ -403,6 +415,7 @@ private:
// Main ping timer
QTimer *t_ping;
+ QTimer *damage_timer;
Qt::HANDLE win_id;
friend class MTexturePixmapPrivate;
diff --git a/src/mtexturepixmapitem_egl.cpp b/src/mtexturepixmapitem_egl.cpp
index efa35dd..ac900b8 100644
--- a/src/mtexturepixmapitem_egl.cpp
+++ b/src/mtexturepixmapitem_egl.cpp
@@ -207,7 +207,8 @@ void MTexturePixmapItem::rebindPixmap()
void MTexturePixmapItem::enableDirectFbRendering()
{
- d->damageTracking(false);
+ if (d->item->propertyCache())
+ d->item->propertyCache()->damageTracking(false);
if (d->direct_fb_render && d->egl_image == EGL_NO_IMAGE_KHR)
return;
@@ -227,7 +228,8 @@ void MTexturePixmapItem::enableDirectFbRendering()
void MTexturePixmapItem::enableRedirectedRendering()
{
- d->damageTracking(true);
+ if (d->item->propertyCache())
+ d->item->propertyCache()->damageTracking(true);
if (!d->direct_fb_render && d->egl_image != EGL_NO_IMAGE_KHR)
return;
diff --git a/src/mtexturepixmapitem_glx.cpp b/src/mtexturepixmapitem_glx.cpp
index d826517..3ee0cac 100644
--- a/src/mtexturepixmapitem_glx.cpp
+++ b/src/mtexturepixmapitem_glx.cpp
@@ -198,7 +198,8 @@ void MTexturePixmapItem::rebindPixmap()
void MTexturePixmapItem::enableDirectFbRendering()
{
- d->damageTracking(false);
+ if (d->item->propertyCache())
+ d->item->propertyCache()->damageTracking(false);
if ((d->direct_fb_render || d->glpixmap == 0) && !d->custom_tfp)
return;
@@ -224,7 +225,8 @@ void MTexturePixmapItem::enableDirectFbRendering()
void MTexturePixmapItem::enableRedirectedRendering()
{
- d->damageTracking(true);
+ if (d->item->propertyCache())
+ d->item->propertyCache()->damageTracking(true);
if ((!d->direct_fb_render || d->glpixmap != 0) && !d->custom_tfp)
return;
diff --git a/src/mtexturepixmapitem_p.cpp b/src/mtexturepixmapitem_p.cpp
index 788d867..112a78a 100644
--- a/src/mtexturepixmapitem_p.cpp
+++ b/src/mtexturepixmapitem_p.cpp
@@ -338,33 +338,22 @@ MTexturePixmapPrivate::MTexturePixmapPrivate(Qt::HANDLE window, QGLWidget *w, MT
custom_tfp(false),
direct_fb_render(false),
angle(0),
- damage_object(0),
item(p)
{
- damageTracking(true);
+ if (item->propertyCache())
+ item->propertyCache()->damageTracking(true);
init();
}
MTexturePixmapPrivate::~MTexturePixmapPrivate()
{
- damageTracking(false);
+ if (item->propertyCache())
+ item->propertyCache()->damageTracking(false);
if (windowp)
XFreePixmap(QX11Info::display(), windowp);
}
-void MTexturePixmapPrivate::damageTracking(bool enabled)
-{
- if (damage_object) {
- XDamageDestroy(QX11Info::display(), damage_object);
- damage_object = NULL;
- }
-
- if (enabled && !damage_object && !item->propertyCache()->isInputOnly())
- damage_object = XDamageCreate(QX11Info::display(), window,
- XDamageReportNonEmpty);
-}
-
void MTexturePixmapPrivate::saveBackingStore(bool renew)
{
if ((item->propertyCache()->is_valid && !item->propertyCache()->isMapped())
diff --git a/src/mtexturepixmapitem_p.h b/src/mtexturepixmapitem_p.h
index 2adb0ad..75bf3b2 100644
--- a/src/mtexturepixmapitem_p.h
+++ b/src/mtexturepixmapitem_p.h
@@ -24,8 +24,7 @@
#include <QRect>
#include <QRegion>
#include <QPointer>
-
-#include <X11/extensions/Xdamage.h>
+#include <X11/Xlib.h>
#ifdef GLES2_VERSION
#include <EGL/egl.h>
@@ -64,7 +63,6 @@ public:
void drawTexture(const QTransform& transform, const QRectF& drawRect, qreal opacity);
void q_drawTexture(const QTransform& transform, const QRectF& drawRect, qreal opacity);
- void damageTracking(bool enabled);
void installEffect(MCompositeWindowShaderEffect* effect);
static GLuint installPixelShader(const QByteArray& code);
@@ -87,7 +85,6 @@ public:
QRegion damageRegion;
qreal angle;
- Damage damage_object;
MTexturePixmapItem *item;
QPointer<MCompositeWindowShaderEffect> current_effect;
diff --git a/src/mwindowpropertycache.cpp b/src/mwindowpropertycache.cpp
index 797a7c5..237d02f 100644
--- a/src/mwindowpropertycache.cpp
+++ b/src/mwindowpropertycache.cpp
@@ -58,7 +58,8 @@ MWindowPropertyCache::MWindowPropertyCache(Window w,
parent_window(RootWindow(QX11Info::display(), 0)),
being_mapped(false),
dont_iconify(false),
- xcb_real_geom(0)
+ xcb_real_geom(0),
+ damage_object(0)
{
memset(&req_geom, 0, sizeof(req_geom));
memset(&home_button_geom, 0, sizeof(home_button_geom));
diff --git a/src/mwindowpropertycache.h b/src/mwindowpropertycache.h
index 0b2aa7c..fda7e54 100644
--- a/src/mwindowpropertycache.h
+++ b/src/mwindowpropertycache.h
@@ -21,11 +21,13 @@
#define MWINDOWPROPERTYCACHE_H
#include <QRegion>
+#include <QX11Info>
#include <X11/Xutil.h>
#include <X11/Xlib-xcb.h>
#include <xcb/render.h>
#include <xcb/shape.h>
#include <X11/extensions/shape.h>
+#include <X11/extensions/Xdamage.h>
#include "mcompatoms_p.h"
/*!
@@ -223,6 +225,21 @@ public:
MWindowPropertyCache::xcb_conn = c;
}
+
+void damageTracking(bool enabled)
+{
+ if (damage_object && enabled)
+ return;
+ if (damage_object && !enabled) {
+ XDamageDestroy(QX11Info::display(), damage_object);
+ damage_object = 0;
+ }
+ else if (enabled && !damage_object && !isInputOnly())
+ damage_object = XDamageCreate(QX11Info::display(), window,
+ XDamageReportNonEmpty);
+}
+
+
signals:
void iconGeometryUpdated();
@@ -276,6 +293,7 @@ private:
QRegion shape_region;
static xcb_connection_t *xcb_conn;
+ Damage damage_object;
};
#endif