Introduce a Toplevel::clientContentPos() -> QPoint

This describes an additional offset for the client content. On X11
our client content position matches with the window - the window
decoration is part of the overall content coordinate system.

On Wayland the content is an own texture starting at 0/0. Thus a
mapping to texture coordinates will be required when server side
decorations are provided. The new information is used in the scene's
to adjust the rendering and generating of quads.
This commit is contained in:
Martin Gräßlin 2015-12-08 10:11:26 +01:00
parent 5f90fa5cfd
commit 827486ff36
8 changed files with 29 additions and 8 deletions

View file

@ -78,6 +78,7 @@ void Deleted::copyToDeleted(Toplevel* c)
desk = c->desktop();
activityList = c->activities();
contentsRect = QRect(c->clientPos(), c->clientSize());
m_contentPos = c->clientContentPos();
transparent_rect = c->transparentRect();
m_layer = c->layer();
m_frame = c->frameId();

View file

@ -49,6 +49,9 @@ public:
virtual QStringList activities() const;
virtual QPoint clientPos() const;
virtual QSize clientSize() const;
QPoint clientContentPos() const override {
return m_contentPos;
}
virtual QRect transparentRect() const;
virtual bool isDeleted() const;
virtual xcb_window_t frameId() const override;
@ -93,6 +96,7 @@ private:
int desk;
QStringList activityList;
QRect contentsRect; // for clientPos()/clientSize()
QPoint m_contentPos;
QRect transparent_rect;
xcb_window_t m_frame;

View file

@ -827,7 +827,7 @@ WindowQuadList Scene::Window::buildQuads(bool force) const
QRegion center = toplevel->transparentRect();
QRegion decoration = (client && true ?
QRegion(client->decorationRect()) : shape()) - center;
ret = makeQuads(WindowQuadContents, contents);
ret = makeQuads(WindowQuadContents, contents, client->clientContentPos());
QRect rects[4];
bool isShadedClient = false;
@ -910,16 +910,16 @@ WindowQuadList Scene::Window::makeDecorationQuads(const QRect *rects, const QReg
return list;
}
WindowQuadList Scene::Window::makeQuads(WindowQuadType type, const QRegion& reg) const
WindowQuadList Scene::Window::makeQuads(WindowQuadType type, const QRegion& reg, const QPoint &textureOffset) const
{
WindowQuadList ret;
foreach (const QRect & r, reg.rects()) {
WindowQuad quad(type);
// TODO asi mam spatne pravy dolni roh - bud tady, nebo v jinych castech
quad[ 0 ] = WindowVertex(r.x(), r.y(), r.x(), r.y());
quad[ 1 ] = WindowVertex(r.x() + r.width(), r.y(), r.x() + r.width(), r.y());
quad[ 2 ] = WindowVertex(r.x() + r.width(), r.y() + r.height(), r.x() + r.width(), r.y() + r.height());
quad[ 3 ] = WindowVertex(r.x(), r.y() + r.height(), r.x(), r.y() + r.height());
quad[ 0 ] = WindowVertex(r.x(), r.y(), r.x() + textureOffset.x(), r.y() + textureOffset.y());
quad[ 1 ] = WindowVertex(r.x() + r.width(), r.y(), r.x() + r.width() + textureOffset.x(), r.y() + textureOffset.y());
quad[ 2 ] = WindowVertex(r.x() + r.width(), r.y() + r.height(), r.x() + r.width() + textureOffset.x(), r.y() + r.height() + textureOffset.y());
quad[ 3 ] = WindowVertex(r.x(), r.y() + r.height(), r.x() + textureOffset.x(), r.y() + r.height() + textureOffset.y());
ret.append(quad);
}
return ret;

View file

@ -275,7 +275,7 @@ public:
void referencePreviousPixmap();
void unreferencePreviousPixmap();
protected:
WindowQuadList makeQuads(WindowQuadType type, const QRegion& reg) const;
WindowQuadList makeQuads(WindowQuadType type, const QRegion& reg, const QPoint &textureOffset = QPoint(0, 0)) const;
WindowQuadList makeDecorationQuads(const QRect *rects, const QRegion &region) const;
/**
* @brief Returns the WindowPixmap for this Window.

View file

@ -280,7 +280,7 @@ void SceneQPainter::Window::performPaint(int mask, QRegion region, WindowPaintDa
renderWindowDecorations(painter);
// render content
const QRect src = QRect(toplevel->clientPos(), toplevel->clientSize());
const QRect src = QRect(toplevel->clientPos() + toplevel->clientContentPos(), toplevel->clientSize());
painter->drawImage(toplevel->clientPos(), pixmap->image(), src);
if (!opaque) {

View file

@ -200,6 +200,11 @@ QPoint ShellClient::clientPos() const
return QPoint(0, 0);
}
QPoint ShellClient::clientContentPos() const
{
return -1 * clientPos();
}
QSize ShellClient::clientSize() const
{
// TODO: connect for changes

View file

@ -44,6 +44,7 @@ public:
QStringList activities() const override;
QPoint clientPos() const override;
QPoint clientContentPos() const override;
QSize clientSize() const override;
QRect transparentRect() const override;
bool shouldUnredirect() const override;

View file

@ -226,6 +226,11 @@ public:
bool isOnActiveScreen() const;
int screen() const; // the screen where the center is
virtual QPoint clientPos() const = 0; // inside of geometry()
/**
* Describes how the client's content maps to the window geometry including the frame.
* The default implementation is a 1:1 mapping meaning the frame is part of the content.
**/
virtual QPoint clientContentPos() const;
virtual QSize clientSize() const = 0;
virtual QRect visibleRect() const; // the area the window occupies on the screen
virtual QRect decorationRect() const; // rect including the decoration shadows
@ -774,6 +779,11 @@ inline const QSharedPointer<QOpenGLFramebufferObject> &Toplevel::internalFramebu
return m_internalFBO;
}
inline QPoint Toplevel::clientContentPos() const
{
return QPoint(0, 0);
}
template <class T, class U>
inline T *Toplevel::findInList(const QList<T*> &list, std::function<bool (const U*)> func)
{