diff options
-rw-r--r-- | src/mcompositemanager.cpp | 34 | ||||
-rw-r--r-- | src/mcompositewindow.cpp | 37 | ||||
-rw-r--r-- | src/mcompositewindow.h | 15 | ||||
-rw-r--r-- | src/mtexturepixmapitem_egl.cpp | 6 | ||||
-rw-r--r-- | src/mtexturepixmapitem_glx.cpp | 6 | ||||
-rw-r--r-- | src/mtexturepixmapitem_p.cpp | 19 | ||||
-rw-r--r-- | src/mtexturepixmapitem_p.h | 5 | ||||
-rw-r--r-- | src/mwindowpropertycache.cpp | 3 | ||||
-rw-r--r-- | src/mwindowpropertycache.h | 18 |
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 |