summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mcompositemanager.cpp15
-rw-r--r--src/mcompositescene.cpp44
-rw-r--r--src/mtexturepixmapitem_p.cpp7
-rw-r--r--src/mwindowpropertycache.cpp10
-rw-r--r--src/mwindowpropertycache.h2
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();