Properly handle opaque regions for CSD X11 windows
Currently, we don't compute the clip region properly for some client- side decorated applications, for example gedit, due to mixing several separate coordinate spaces. This change ensures that the window pixmap shape and the opaque region are in the same coordinate space - the window pixmap coordinate. In order to simplify mapping regions from the window pixmap coordinates to the global screen coordinates, a new helper method was introduced in the WindowPixmap class - mapToGlobal().
This commit is contained in:
parent
c0da7faa6f
commit
2b241d3081
2 changed files with 34 additions and 7 deletions
24
scene.cpp
24
scene.cpp
|
@ -284,11 +284,17 @@ void Scene::paintSimpleScreen(int orig_mask, const QRegion ®ion)
|
||||||
if (!(client && client->decorationHasAlpha())) {
|
if (!(client && client->decorationHasAlpha())) {
|
||||||
data.clip = window->decorationShape().translated(window->pos());
|
data.clip = window->decorationShape().translated(window->pos());
|
||||||
}
|
}
|
||||||
data.clip |= window->clientShape().translated(window->pos() + window->bufferOffset());
|
const WindowPixmap *windowPixmap = window->windowPixmap<WindowPixmap>();
|
||||||
|
if (windowPixmap) {
|
||||||
|
data.clip |= windowPixmap->mapToGlobal(windowPixmap->shape());
|
||||||
|
}
|
||||||
} else if (toplevel->hasAlpha() && toplevel->opacity() == 1.0) {
|
} else if (toplevel->hasAlpha() && toplevel->opacity() == 1.0) {
|
||||||
const QRegion clientShape = window->clientShape().translated(window->pos() + window->bufferOffset());
|
const WindowPixmap *windowPixmap = window->windowPixmap<WindowPixmap>();
|
||||||
const QRegion opaqueShape = toplevel->opaqueRegion().translated(window->pos() + toplevel->clientPos());
|
if (windowPixmap) {
|
||||||
data.clip = clientShape & opaqueShape;
|
const QRegion shape = windowPixmap->mapToGlobal(windowPixmap->shape());
|
||||||
|
const QRegion opaque = windowPixmap->mapToGlobal(windowPixmap->opaque());
|
||||||
|
data.clip = shape & opaque;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
data.clip = QRegion();
|
data.clip = QRegion();
|
||||||
}
|
}
|
||||||
|
@ -1279,6 +1285,11 @@ QRegion WindowPixmap::shape() const
|
||||||
return m_window->clientShape();
|
return m_window->clientShape();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QRegion WindowPixmap::opaque() const
|
||||||
|
{
|
||||||
|
return toplevel()->opaqueRegion().translated(toplevel()->clientPos());
|
||||||
|
}
|
||||||
|
|
||||||
bool WindowPixmap::hasAlphaChannel() const
|
bool WindowPixmap::hasAlphaChannel() const
|
||||||
{
|
{
|
||||||
if (buffer())
|
if (buffer())
|
||||||
|
@ -1298,6 +1309,11 @@ QPointF WindowPixmap::mapToBuffer(const QPointF &point) const
|
||||||
return point * scale();
|
return point * scale();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QRegion WindowPixmap::mapToGlobal(const QRegion ®ion) const
|
||||||
|
{
|
||||||
|
return region.translated(m_window->pos() + framePosition());
|
||||||
|
}
|
||||||
|
|
||||||
//****************************************
|
//****************************************
|
||||||
// Scene::EffectFrame
|
// Scene::EffectFrame
|
||||||
//****************************************
|
//****************************************
|
||||||
|
|
17
scene.h
17
scene.h
|
@ -357,9 +357,6 @@ public:
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
|
||||||
WindowQuadList makeDecorationQuads(const QRect *rects, const QRegion ®ion, qreal textureScale = 1.0) const;
|
|
||||||
WindowQuadList makeContentsQuads() const;
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the WindowPixmap for this Window.
|
* @brief Returns the WindowPixmap for this Window.
|
||||||
*
|
*
|
||||||
|
@ -377,6 +374,10 @@ protected:
|
||||||
*/
|
*/
|
||||||
template<typename T> T *windowPixmap() const;
|
template<typename T> T *windowPixmap() const;
|
||||||
template<typename T> T *previousWindowPixmap() const;
|
template<typename T> T *previousWindowPixmap() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
WindowQuadList makeDecorationQuads(const QRect *rects, const QRegion ®ion, qreal textureScale = 1.0) const;
|
||||||
|
WindowQuadList makeContentsQuads() const;
|
||||||
/**
|
/**
|
||||||
* @brief Factory method to create a WindowPixmap.
|
* @brief Factory method to create a WindowPixmap.
|
||||||
*
|
*
|
||||||
|
@ -497,6 +498,12 @@ public:
|
||||||
* The upper left corner of the attached buffer corresponds to (0, 0).
|
* The upper left corner of the attached buffer corresponds to (0, 0).
|
||||||
*/
|
*/
|
||||||
QRegion shape() const;
|
QRegion shape() const;
|
||||||
|
/**
|
||||||
|
* Returns the region that specifies the opaque area inside the attached buffer.
|
||||||
|
*
|
||||||
|
* The upper left corner of the attached buffer corresponds to (0, 0).
|
||||||
|
*/
|
||||||
|
QRegion opaque() const;
|
||||||
/**
|
/**
|
||||||
* The geometry of the Client's content inside the pixmap. In case of a decorated Client the
|
* The geometry of the Client's content inside the pixmap. In case of a decorated Client the
|
||||||
* pixmap also contains the decoration which is not rendered into this pixmap, though. This
|
* pixmap also contains the decoration which is not rendered into this pixmap, though. This
|
||||||
|
@ -520,6 +527,10 @@ public:
|
||||||
* Maps the specified @a point from the window pixmap coordinates to the buffer pixel coordinates.
|
* Maps the specified @a point from the window pixmap coordinates to the buffer pixel coordinates.
|
||||||
*/
|
*/
|
||||||
QPointF mapToBuffer(const QPointF &point) const;
|
QPointF mapToBuffer(const QPointF &point) const;
|
||||||
|
/**
|
||||||
|
* Maps the specified @a region from the window pixmap coordinates to the global screen coordinates.
|
||||||
|
*/
|
||||||
|
QRegion mapToGlobal(const QRegion ®ion) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns the parent WindowPixmap in the sub-surface tree
|
* @returns the parent WindowPixmap in the sub-surface tree
|
||||||
|
|
Loading…
Reference in a new issue