2021-02-04 09:07:20 +00:00
|
|
|
/*
|
|
|
|
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
|
|
|
|
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
*/
|
|
|
|
|
2022-12-15 20:35:22 +00:00
|
|
|
#include "scene/surfaceitem_wayland.h"
|
2023-08-31 12:23:42 +00:00
|
|
|
#include "compositor.h"
|
2023-04-28 07:30:18 +00:00
|
|
|
#include "core/graphicsbuffer.h"
|
2022-12-17 17:54:43 +00:00
|
|
|
#include "core/renderbackend.h"
|
2023-09-13 05:52:59 +00:00
|
|
|
#include "wayland/subcompositor.h"
|
|
|
|
#include "wayland/surface.h"
|
2023-03-02 21:08:15 +00:00
|
|
|
#include "window.h"
|
2023-03-28 18:30:58 +00:00
|
|
|
#include "x11window.h"
|
2021-02-04 09:07:20 +00:00
|
|
|
|
|
|
|
namespace KWin
|
|
|
|
{
|
|
|
|
|
2023-09-13 17:59:29 +00:00
|
|
|
SurfaceItemWayland::SurfaceItemWayland(SurfaceInterface *surface, Scene *scene, Item *parent)
|
2022-12-18 12:30:40 +00:00
|
|
|
: SurfaceItem(scene, parent)
|
2021-02-04 09:07:20 +00:00
|
|
|
, m_surface(surface)
|
|
|
|
{
|
2023-09-13 17:59:29 +00:00
|
|
|
connect(surface, &SurfaceInterface::surfaceToBufferMatrixChanged,
|
2021-07-21 19:25:42 +00:00
|
|
|
this, &SurfaceItemWayland::handleSurfaceToBufferMatrixChanged);
|
2021-02-04 09:07:20 +00:00
|
|
|
|
2023-09-13 17:59:29 +00:00
|
|
|
connect(surface, &SurfaceInterface::sizeChanged,
|
2021-02-04 09:07:20 +00:00
|
|
|
this, &SurfaceItemWayland::handleSurfaceSizeChanged);
|
2023-09-13 17:59:29 +00:00
|
|
|
connect(surface, &SurfaceInterface::bufferSizeChanged,
|
2023-07-04 06:19:08 +00:00
|
|
|
this, &SurfaceItemWayland::handleBufferSizeChanged);
|
2023-09-13 17:59:29 +00:00
|
|
|
connect(surface, &SurfaceInterface::bufferSourceBoxChanged,
|
2023-07-26 08:55:34 +00:00
|
|
|
this, &SurfaceItemWayland::handleBufferSourceBoxChanged);
|
2023-09-13 17:59:29 +00:00
|
|
|
connect(surface, &SurfaceInterface::bufferTransformChanged,
|
2023-07-26 08:55:34 +00:00
|
|
|
this, &SurfaceItemWayland::handleBufferTransformChanged);
|
2021-02-04 09:07:20 +00:00
|
|
|
|
2023-09-13 17:59:29 +00:00
|
|
|
connect(surface, &SurfaceInterface::childSubSurfacesChanged,
|
2021-02-04 09:07:20 +00:00
|
|
|
this, &SurfaceItemWayland::handleChildSubSurfacesChanged);
|
2023-09-13 17:59:29 +00:00
|
|
|
connect(surface, &SurfaceInterface::committed,
|
2021-02-04 09:07:20 +00:00
|
|
|
this, &SurfaceItemWayland::handleSurfaceCommitted);
|
2023-09-13 17:59:29 +00:00
|
|
|
connect(surface, &SurfaceInterface::damaged,
|
2021-02-04 09:07:20 +00:00
|
|
|
this, &SurfaceItemWayland::addDamage);
|
2023-09-13 17:59:29 +00:00
|
|
|
connect(surface, &SurfaceInterface::childSubSurfaceRemoved,
|
2021-02-04 09:07:20 +00:00
|
|
|
this, &SurfaceItemWayland::handleChildSubSurfaceRemoved);
|
2023-10-18 08:34:31 +00:00
|
|
|
connect(surface, &SurfaceInterface::colorDescriptionChanged,
|
|
|
|
this, &SurfaceItemWayland::handleColorDescriptionChanged);
|
2021-02-04 09:07:20 +00:00
|
|
|
|
2023-09-13 17:59:29 +00:00
|
|
|
SubSurfaceInterface *subsurface = surface->subSurface();
|
2021-02-04 09:07:20 +00:00
|
|
|
if (subsurface) {
|
2023-09-13 17:59:29 +00:00
|
|
|
connect(surface, &SurfaceInterface::mapped,
|
2021-07-28 17:08:48 +00:00
|
|
|
this, &SurfaceItemWayland::handleSubSurfaceMappedChanged);
|
2023-09-13 17:59:29 +00:00
|
|
|
connect(surface, &SurfaceInterface::unmapped,
|
2021-07-28 17:08:48 +00:00
|
|
|
this, &SurfaceItemWayland::handleSubSurfaceMappedChanged);
|
2023-09-13 17:59:29 +00:00
|
|
|
connect(subsurface, &SubSurfaceInterface::positionChanged,
|
2021-02-04 09:07:20 +00:00
|
|
|
this, &SurfaceItemWayland::handleSubSurfacePositionChanged);
|
2021-07-28 17:08:48 +00:00
|
|
|
setVisible(surface->isMapped());
|
2021-02-04 09:07:20 +00:00
|
|
|
setPosition(subsurface->position());
|
|
|
|
}
|
|
|
|
|
2021-06-19 14:01:12 +00:00
|
|
|
handleChildSubSurfacesChanged();
|
2021-02-04 09:07:20 +00:00
|
|
|
setSize(surface->size());
|
2023-07-04 06:19:08 +00:00
|
|
|
setBufferTransform(surface->bufferTransform());
|
|
|
|
setBufferSourceBox(surface->bufferSourceBox());
|
|
|
|
setBufferSize(surface->bufferSize());
|
2021-07-21 19:25:42 +00:00
|
|
|
setSurfaceToBufferMatrix(surface->surfaceToBufferMatrix());
|
2023-10-30 17:17:35 +00:00
|
|
|
setColorDescription(surface->colorDescription());
|
2021-02-04 09:07:20 +00:00
|
|
|
}
|
|
|
|
|
2023-10-19 06:50:15 +00:00
|
|
|
QList<QRectF> SurfaceItemWayland::shape() const
|
2021-02-04 09:07:20 +00:00
|
|
|
{
|
2022-09-12 09:29:33 +00:00
|
|
|
return {rect()};
|
2021-02-04 09:07:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QRegion SurfaceItemWayland::opaque() const
|
|
|
|
{
|
|
|
|
if (m_surface) {
|
|
|
|
return m_surface->opaque();
|
|
|
|
}
|
|
|
|
return QRegion();
|
|
|
|
}
|
|
|
|
|
2023-09-13 17:59:29 +00:00
|
|
|
SurfaceInterface *SurfaceItemWayland::surface() const
|
2021-02-04 09:07:20 +00:00
|
|
|
{
|
|
|
|
return m_surface;
|
|
|
|
}
|
|
|
|
|
2021-07-21 19:25:42 +00:00
|
|
|
void SurfaceItemWayland::handleSurfaceToBufferMatrixChanged()
|
|
|
|
{
|
|
|
|
setSurfaceToBufferMatrix(m_surface->surfaceToBufferMatrix());
|
|
|
|
discardQuads();
|
|
|
|
discardPixmap();
|
|
|
|
}
|
|
|
|
|
2021-02-04 09:07:20 +00:00
|
|
|
void SurfaceItemWayland::handleSurfaceSizeChanged()
|
|
|
|
{
|
|
|
|
setSize(m_surface->size());
|
|
|
|
}
|
|
|
|
|
2023-07-04 06:19:08 +00:00
|
|
|
void SurfaceItemWayland::handleBufferSizeChanged()
|
|
|
|
{
|
|
|
|
setBufferSize(m_surface->bufferSize());
|
|
|
|
discardPixmap();
|
|
|
|
}
|
|
|
|
|
2023-07-26 08:55:34 +00:00
|
|
|
void SurfaceItemWayland::handleBufferSourceBoxChanged()
|
|
|
|
{
|
|
|
|
setBufferSourceBox(m_surface->bufferSourceBox());
|
|
|
|
}
|
|
|
|
|
|
|
|
void SurfaceItemWayland::handleBufferTransformChanged()
|
|
|
|
{
|
|
|
|
setBufferTransform(m_surface->bufferTransform());
|
|
|
|
}
|
|
|
|
|
2021-02-04 09:07:20 +00:00
|
|
|
void SurfaceItemWayland::handleSurfaceCommitted()
|
|
|
|
{
|
|
|
|
if (m_surface->hasFrameCallbacks()) {
|
2021-05-19 06:35:42 +00:00
|
|
|
scheduleFrame();
|
2021-02-04 09:07:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-13 17:59:29 +00:00
|
|
|
SurfaceItemWayland *SurfaceItemWayland::getOrCreateSubSurfaceItem(SubSurfaceInterface *child)
|
2021-02-04 09:07:20 +00:00
|
|
|
{
|
2023-08-10 16:31:43 +00:00
|
|
|
auto &item = m_subsurfaces[child];
|
2021-06-19 14:01:12 +00:00
|
|
|
if (!item) {
|
2023-08-10 16:31:43 +00:00
|
|
|
item = std::make_unique<SurfaceItemWayland>(child->surface(), scene());
|
2021-06-19 14:01:12 +00:00
|
|
|
item->setParentItem(this);
|
|
|
|
}
|
2023-08-10 16:31:43 +00:00
|
|
|
return item.get();
|
2021-02-04 09:07:20 +00:00
|
|
|
}
|
|
|
|
|
2023-09-13 17:59:29 +00:00
|
|
|
void SurfaceItemWayland::handleChildSubSurfaceRemoved(SubSurfaceInterface *child)
|
2021-02-04 09:07:20 +00:00
|
|
|
{
|
2023-08-10 16:31:43 +00:00
|
|
|
m_subsurfaces.erase(child);
|
2021-02-04 09:07:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SurfaceItemWayland::handleChildSubSurfacesChanged()
|
|
|
|
{
|
2023-09-13 17:59:29 +00:00
|
|
|
const QList<SubSurfaceInterface *> below = m_surface->below();
|
|
|
|
const QList<SubSurfaceInterface *> above = m_surface->above();
|
2021-06-19 12:59:07 +00:00
|
|
|
|
2021-06-19 14:01:12 +00:00
|
|
|
for (int i = 0; i < below.count(); ++i) {
|
|
|
|
SurfaceItemWayland *subsurfaceItem = getOrCreateSubSurfaceItem(below[i]);
|
|
|
|
subsurfaceItem->setZ(i - below.count());
|
2021-06-19 12:59:07 +00:00
|
|
|
}
|
2021-07-20 19:37:03 +00:00
|
|
|
|
2021-06-19 14:01:12 +00:00
|
|
|
for (int i = 0; i < above.count(); ++i) {
|
|
|
|
SurfaceItemWayland *subsurfaceItem = getOrCreateSubSurfaceItem(above[i]);
|
|
|
|
subsurfaceItem->setZ(i);
|
2021-02-04 09:07:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SurfaceItemWayland::handleSubSurfacePositionChanged()
|
|
|
|
{
|
|
|
|
setPosition(m_surface->subSurface()->position());
|
|
|
|
}
|
|
|
|
|
2021-07-28 17:08:48 +00:00
|
|
|
void SurfaceItemWayland::handleSubSurfaceMappedChanged()
|
|
|
|
{
|
|
|
|
setVisible(m_surface->isMapped());
|
|
|
|
}
|
|
|
|
|
2022-06-29 11:24:56 +00:00
|
|
|
std::unique_ptr<SurfacePixmap> SurfaceItemWayland::createPixmap()
|
2021-02-04 09:07:20 +00:00
|
|
|
{
|
2022-06-29 11:24:56 +00:00
|
|
|
return std::make_unique<SurfacePixmapWayland>(this);
|
2021-04-09 07:06:04 +00:00
|
|
|
}
|
|
|
|
|
2022-05-25 09:38:59 +00:00
|
|
|
ContentType SurfaceItemWayland::contentType() const
|
|
|
|
{
|
2023-10-18 08:34:31 +00:00
|
|
|
return m_surface ? m_surface->contentType() : ContentType::None;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SurfaceItemWayland::handleColorDescriptionChanged()
|
|
|
|
{
|
|
|
|
setColorDescription(m_surface->colorDescription());
|
2022-05-25 09:38:59 +00:00
|
|
|
}
|
|
|
|
|
2021-04-09 07:06:04 +00:00
|
|
|
SurfacePixmapWayland::SurfacePixmapWayland(SurfaceItemWayland *item, QObject *parent)
|
2022-12-17 17:54:43 +00:00
|
|
|
: SurfacePixmap(Compositor::self()->backend()->createSurfaceTextureWayland(this), parent)
|
2021-04-09 07:06:04 +00:00
|
|
|
, m_item(item)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void SurfacePixmapWayland::create()
|
|
|
|
{
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SurfacePixmapWayland::update()
|
|
|
|
{
|
2023-09-13 17:59:29 +00:00
|
|
|
SurfaceInterface *surface = m_item->surface();
|
2021-04-09 07:06:04 +00:00
|
|
|
if (surface) {
|
|
|
|
setBuffer(surface->buffer());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SurfacePixmapWayland::isValid() const
|
|
|
|
{
|
2023-08-04 11:13:21 +00:00
|
|
|
return m_bufferRef;
|
2021-02-04 09:07:20 +00:00
|
|
|
}
|
|
|
|
|
2023-03-28 18:30:58 +00:00
|
|
|
SurfaceItemXwayland::SurfaceItemXwayland(X11Window *window, Scene *scene, Item *parent)
|
2022-12-18 12:30:40 +00:00
|
|
|
: SurfaceItemWayland(window->surface(), scene, parent)
|
2022-12-14 14:52:10 +00:00
|
|
|
, m_window(window)
|
2021-02-04 09:07:20 +00:00
|
|
|
{
|
2023-06-01 18:57:33 +00:00
|
|
|
connect(window, &X11Window::shapeChanged, this, &SurfaceItemXwayland::discardQuads);
|
2021-02-04 09:07:20 +00:00
|
|
|
}
|
|
|
|
|
2023-10-19 06:50:15 +00:00
|
|
|
QList<QRectF> SurfaceItemXwayland::shape() const
|
2021-02-04 09:07:20 +00:00
|
|
|
{
|
2022-12-14 14:52:10 +00:00
|
|
|
const QRectF clipRect = rect() & m_window->clientGeometry().translated(-m_window->bufferGeometry().topLeft());
|
2023-10-19 06:50:15 +00:00
|
|
|
QList<QRectF> shape = m_window->shapeRegion();
|
2021-02-04 09:07:20 +00:00
|
|
|
|
2022-09-12 09:29:33 +00:00
|
|
|
// bounded to clipRect
|
|
|
|
for (QRectF &shapePart : shape) {
|
|
|
|
shapePart = shapePart.intersected(clipRect);
|
|
|
|
}
|
|
|
|
return shape;
|
2021-02-04 09:07:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace KWin
|
2023-07-05 06:30:14 +00:00
|
|
|
|
|
|
|
#include "moc_surfaceitem_wayland.cpp"
|