Changeset View
Standalone View
plugins/scenes/qpainter/scene_qpainter.cpp
Show First 20 Lines • Show All 281 Lines • ▼ Show 20 Line(s) | 277 | if (!opaque) { | |||
---|---|---|---|---|---|
282 | tempPainter.save(); | 282 | tempPainter.save(); | ||
283 | tempPainter.translate(toplevel->frameGeometry().topLeft() - toplevel->visibleRect().topLeft()); | 283 | tempPainter.translate(toplevel->frameGeometry().topLeft() - toplevel->visibleRect().topLeft()); | ||
284 | painter = &tempPainter; | 284 | painter = &tempPainter; | ||
285 | } | 285 | } | ||
286 | renderShadow(painter); | 286 | renderShadow(painter); | ||
287 | renderWindowDecorations(painter); | 287 | renderWindowDecorations(painter); | ||
288 | 288 | | |||
289 | // render content | 289 | // render content | ||
290 | QRect source; | 290 | QRectF source; | ||
291 | QRect target; | 291 | QRectF target; | ||
292 | QRectF viewportRectangle; | ||||
293 | if (toplevel->surface()) { | ||||
294 | viewportRectangle = toplevel->surface()->sourceRectangle(); | ||||
295 | } | ||||
292 | if (toplevel->isClient()) { | 296 | if (toplevel->isClient()) { | ||
293 | // special case for XWayland windows | 297 | // special case for XWayland windows | ||
298 | if (viewportRectangle.isValid()) { | ||||
299 | source = viewportRectangle; | ||||
300 | source.translate(toplevel->clientPos()); | ||||
301 | } else { | ||||
294 | source = QRect(toplevel->clientPos(), toplevel->clientSize()); | 302 | source = QRect(toplevel->clientPos(), toplevel->clientSize()); | ||
303 | } | ||||
davidedmundson: This will crash on X and internal clients. | |||||
QPainter compositing is Wayland only and for internal clients Toplevel::isClient() returns false. The only danger to crash could come from an XWayland window without a surface but with damage. If I remember the XWayland code correctly this can't happen though. Damage is always sent through the surface We can add a guard of course but since QPainter backend is more our "experimentation field" than our workhorse I would go without precautionary guards. I can add a comment to the code though to explain the rational. romangg: QPainter compositing is Wayland only and for internal clients `Toplevel::isClient()` returns… | |||||
295 | target = source; | 304 | target = source; | ||
296 | } else { | 305 | } else { | ||
306 | if (viewportRectangle.isValid()) { | ||||
307 | const qreal imageScale = toplevel->bufferScale(); | ||||
308 | source = QRectF(viewportRectangle.topLeft() * imageScale, | ||||
309 | viewportRectangle.bottomRight() * imageScale); | ||||
310 | } else { | ||||
297 | source = pixmap->image().rect(); | 311 | source = pixmap->image().rect(); | ||
In the GL case you implement a crop if we have a sourceRect with a position and an invalid size davidedmundson: In the GL case you implement a crop if we have a sourceRect with a position and an invalid size | |||||
In case the source rect is of invalid size there might still be a destination size being specified. That means there is still a difference between vertex positions and texture coordinates what both need to be set correctly in the GL case. In QPainter we don't deal with texture coordinates so it simplifies to only painting from the image to the buffer geometry. romangg: In case the source rect is of invalid size there might still be a destination size being… | |||||
312 | } | ||||
I missed this call though, which crashes indeed for internal clients. Thanks. romangg: I missed this call though, which crashes indeed for internal clients. Thanks. | |||||
298 | target = toplevel->bufferGeometry().translated(-pos()); | 313 | target = toplevel->bufferGeometry().translated(-pos()); | ||
299 | } | 314 | } | ||
300 | painter->drawImage(target, pixmap->image(), source); | 315 | painter->drawImage(target, pixmap->image(), source); | ||
301 | 316 | | |||
302 | // render subsurfaces | 317 | // render subsurfaces | ||
303 | const auto &children = pixmap->children(); | 318 | const auto &children = pixmap->children(); | ||
304 | for (auto pixmap : children) { | 319 | for (auto pixmap : children) { | ||
305 | if (pixmap->subSurface().isNull() || pixmap->subSurface()->surface().isNull() || !pixmap->subSurface()->surface()->isMapped()) { | 320 | if (pixmap->subSurface().isNull() || pixmap->subSurface()->surface().isNull() || !pixmap->subSurface()->surface()->isMapped()) { | ||
▲ Show 20 Lines • Show All 598 Lines • Show Last 20 Lines |
This will crash on X and internal clients.