diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mcompositemanager.cpp | 15 | ||||
-rw-r--r-- | src/mcompositescene.cpp | 44 | ||||
-rw-r--r-- | src/mtexturepixmapitem_p.cpp | 7 | ||||
-rw-r--r-- | src/mwindowpropertycache.cpp | 10 | ||||
-rw-r--r-- | src/mwindowpropertycache.h | 2 |
5 files changed, 51 insertions, 27 deletions
diff --git a/src/mcompositemanager.cpp b/src/mcompositemanager.cpp index 4901b4b..668407d 100644 --- a/src/mcompositemanager.cpp +++ b/src/mcompositemanager.cpp @@ -1818,7 +1818,12 @@ void MCompositeManagerPrivate::mapEvent(XMapEvent *e) else item->saveBackingStore(true); item->setVisible(true); - item->fadeIn(); + // 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) + item->fadeIn(); + else + item->setNewlyMapped(false); goto stack_and_return; } @@ -1836,10 +1841,14 @@ void MCompositeManagerPrivate::mapEvent(XMapEvent *e) qDebug() << "Composition overhead (new pixmap):" << overhead_measure.elapsed(); #endif - if (item->isAppWindow()) + const XWMHints &h = pc->getWMHints(); + if ((!(h.flags & StateHint) || h.initial_state != IconicState) + && item->isAppWindow()) item->fadeIn(); - else + else { item->setVisible(true); + item->setNewlyMapped(false); + } // the current decorated window got mapped if (e->window == MDecoratorFrame::instance()->managedWindow() && diff --git a/src/mcompositescene.cpp b/src/mcompositescene.cpp index 36cb017..a2a437c 100644 --- a/src/mcompositescene.cpp +++ b/src/mcompositescene.cpp @@ -98,21 +98,41 @@ void MCompositeScene::setupOverlay(Window window, const QRect &geom, void MCompositeScene::drawItems(QPainter *painter, int numItems, QGraphicsItem *items[], const QStyleOptionGraphicsItem options[], QWidget *widget) { - for (int i = 0; i < numItems; ++i) { - MCompositeWindow *window = (MCompositeWindow *) items[i]; + QRegion visible(sceneRect().toRect()); + QList<QGraphicsItem*> to_paint; + QList<QStyleOptionGraphicsItem> paint_opts; + // visibility is determined from top to bottom + for (int i = numItems - 1; i >= 0; --i) { + MCompositeWindow *cw = (MCompositeWindow *) items[i]; - // Redraw only textures which don't have opaque textures above it - if (((i < numItems - 1) - && (items[i+1]->sceneMatrix().mapRect(items[i]->boundingRect()) == - items[i]->boundingRect()) - && (!((MCompositeWindow *)items[i+1])->propertyCache()->hasAlpha()) - && (((MCompositeWindow *)items[i+1])->opacity() == 1.0)) - || window->isIconified()) - continue; + if (visible.isEmpty()) + // nothing below is visible anymore + break; + + // FIXME: this region is always the same as the window's shape, + // some transformations would be needed... + QRegion r(cw->sceneMatrix().map(cw->propertyCache()->shapeRegion())); + // transitioning window can be smaller than shapeRegion(), so paint + // all transitioning windows + if (cw->isWindowTransitioning() || visible.intersects(r)) { + to_paint.prepend(cw); + paint_opts.prepend(options[i]); + } + + // subtract opaque regions + if (!cw->isWindowTransitioning() + && !cw->propertyCache()->hasAlpha() && cw->opacity() == 1.0) + visible -= r; + } + // paint from bottom to top so that blending works + while (!to_paint.isEmpty()) { + // TODO: paint only the intersected region (glScissor?) + MCompositeWindow *cw = (MCompositeWindow*)to_paint.takeFirst(); painter->save(); - painter->setMatrix(items[i]->sceneMatrix(), true); - items[i]->paint(painter, &options[i], widget); + painter->setMatrix(cw->sceneMatrix(), true); + QStyleOptionGraphicsItem opts = paint_opts.takeFirst(); + cw->paint(painter, &opts, widget); painter->restore(); } } diff --git a/src/mtexturepixmapitem_p.cpp b/src/mtexturepixmapitem_p.cpp index 223b442..4343a82 100644 --- a/src/mtexturepixmapitem_p.cpp +++ b/src/mtexturepixmapitem_p.cpp @@ -255,12 +255,7 @@ void MTexturePixmapPrivate::damageTracking(bool enabled) void MTexturePixmapPrivate::saveBackingStore(bool renew) { - XWindowAttributes a; - if (!XGetWindowAttributes(QX11Info::display(), item->window(), &a)) { - qWarning("%s: invalid window 0x%lx", __func__, item->window()); - return; - } - if (a.map_state != IsViewable) + if (item->propertyCache()->is_valid && !item->propertyCache()->isMapped()) return; if (windowp) diff --git a/src/mwindowpropertycache.cpp b/src/mwindowpropertycache.cpp index a11f82c..764d896 100644 --- a/src/mwindowpropertycache.cpp +++ b/src/mwindowpropertycache.cpp @@ -218,19 +218,19 @@ bool MWindowPropertyCache::hasAlpha() return has_alpha ? true : false; } -const QRegion MWindowPropertyCache::shapeRegion() +const QRegion &MWindowPropertyCache::shapeRegion() { if (shape_rects_valid) { if (shape_region.isEmpty()) - return QRegion(realGeometry()); - else - return shape_region; + shape_region = QRegion(realGeometry()); + return shape_region; } xcb_shape_get_rectangles_reply_t *r; r = xcb_shape_get_rectangles_reply(xcb_conn, xcb_shape_rects_cookie, 0); if (!r) { shape_rects_valid = true; - return QRegion(realGeometry()); + shape_region = QRegion(realGeometry()); + return shape_region; } xcb_rectangle_iterator_t i; i = xcb_shape_get_rectangles_rectangles_iterator(r); diff --git a/src/mwindowpropertycache.h b/src/mwindowpropertycache.h index 5f049a0..e75a5d0 100644 --- a/src/mwindowpropertycache.h +++ b/src/mwindowpropertycache.h @@ -80,7 +80,7 @@ public: } return real_geom; } - const QRegion shapeRegion(); + const QRegion &shapeRegion(); void shapeRefresh() { if (!shape_rects_valid) shapeRegion(); |