Add support for opaque and input region to Surface
Implemented on both Client and Server side.
This commit is contained in:
parent
7fce72b7d1
commit
5debfb6832
4 changed files with 157 additions and 10 deletions
|
@ -24,6 +24,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "../../src/client/compositor.h"
|
||||
#include "../../src/client/connection_thread.h"
|
||||
#include "../../src/client/surface.h"
|
||||
#include "../../src/client/region.h"
|
||||
#include "../../src/client/registry.h"
|
||||
#include "../../src/client/shm_pool.h"
|
||||
#include "../../src/server/buffer_interface.h"
|
||||
|
@ -46,6 +47,8 @@ private Q_SLOTS:
|
|||
void testDamage();
|
||||
void testFrameCallback();
|
||||
void testAttachBuffer();
|
||||
void testOpaque();
|
||||
void testInput();
|
||||
void testDestroy();
|
||||
|
||||
private:
|
||||
|
@ -344,6 +347,122 @@ void TestWaylandSurface::testAttachBuffer()
|
|||
buffer->unref();
|
||||
}
|
||||
|
||||
void TestWaylandSurface::testOpaque()
|
||||
{
|
||||
using namespace KWayland::Client;
|
||||
using namespace KWayland::Server;
|
||||
QSignalSpy serverSurfaceCreated(m_compositorInterface, SIGNAL(surfaceCreated(KWayland::Server::SurfaceInterface*)));
|
||||
QVERIFY(serverSurfaceCreated.isValid());
|
||||
Surface *s = m_compositor->createSurface();
|
||||
QVERIFY(serverSurfaceCreated.wait());
|
||||
SurfaceInterface *serverSurface = serverSurfaceCreated.first().first().value<KWayland::Server::SurfaceInterface*>();
|
||||
QVERIFY(serverSurface);
|
||||
QSignalSpy opaqueRegionChangedSpy(serverSurface, SIGNAL(opaqueChanged(QRegion)));
|
||||
QVERIFY(opaqueRegionChangedSpy.isValid());
|
||||
|
||||
// by default there should be an empty opaque region
|
||||
QCOMPARE(serverSurface->opaque(), QRegion());
|
||||
|
||||
// let's install an opaque region
|
||||
s->setOpaqueRegion(m_compositor->createRegion(QRegion(0, 10, 20, 30)).get());
|
||||
// the region should only be applied after the surface got commited
|
||||
wl_display_flush(m_connection->display());
|
||||
QCoreApplication::processEvents();
|
||||
QCOMPARE(serverSurface->opaque(), QRegion());
|
||||
QCOMPARE(opaqueRegionChangedSpy.count(), 0);
|
||||
|
||||
// so let's commit to get the new region
|
||||
s->commit(Surface::CommitFlag::None);
|
||||
QVERIFY(opaqueRegionChangedSpy.wait());
|
||||
QCOMPARE(opaqueRegionChangedSpy.count(), 1);
|
||||
QCOMPARE(opaqueRegionChangedSpy.last().first().value<QRegion>(), QRegion(0, 10, 20, 30));
|
||||
QCOMPARE(serverSurface->opaque(), QRegion(0, 10, 20, 30));
|
||||
|
||||
// committing without setting a new region shouldn't change
|
||||
s->commit(Surface::CommitFlag::None);
|
||||
wl_display_flush(m_connection->display());
|
||||
QCoreApplication::processEvents();
|
||||
QCOMPARE(opaqueRegionChangedSpy.count(), 1);
|
||||
QCOMPARE(serverSurface->opaque(), QRegion(0, 10, 20, 30));
|
||||
|
||||
// let's change the opaque region
|
||||
s->setOpaqueRegion(m_compositor->createRegion(QRegion(10, 20, 30, 40)).get());
|
||||
s->commit(Surface::CommitFlag::None);
|
||||
QVERIFY(opaqueRegionChangedSpy.wait());
|
||||
QCOMPARE(opaqueRegionChangedSpy.count(), 2);
|
||||
QCOMPARE(opaqueRegionChangedSpy.last().first().value<QRegion>(), QRegion(10, 20, 30, 40));
|
||||
QCOMPARE(serverSurface->opaque(), QRegion(10, 20, 30, 40));
|
||||
|
||||
// and let's go back to an empty region
|
||||
s->setOpaqueRegion();
|
||||
s->commit(Surface::CommitFlag::None);
|
||||
QVERIFY(opaqueRegionChangedSpy.wait());
|
||||
QCOMPARE(opaqueRegionChangedSpy.count(), 3);
|
||||
QCOMPARE(opaqueRegionChangedSpy.last().first().value<QRegion>(), QRegion());
|
||||
QCOMPARE(serverSurface->opaque(), QRegion());
|
||||
}
|
||||
|
||||
void TestWaylandSurface::testInput()
|
||||
{
|
||||
using namespace KWayland::Client;
|
||||
using namespace KWayland::Server;
|
||||
QSignalSpy serverSurfaceCreated(m_compositorInterface, SIGNAL(surfaceCreated(KWayland::Server::SurfaceInterface*)));
|
||||
QVERIFY(serverSurfaceCreated.isValid());
|
||||
Surface *s = m_compositor->createSurface();
|
||||
QVERIFY(serverSurfaceCreated.wait());
|
||||
SurfaceInterface *serverSurface = serverSurfaceCreated.first().first().value<KWayland::Server::SurfaceInterface*>();
|
||||
QVERIFY(serverSurface);
|
||||
QSignalSpy inputRegionChangedSpy(serverSurface, SIGNAL(inputChanged(QRegion)));
|
||||
QVERIFY(inputRegionChangedSpy.isValid());
|
||||
|
||||
// by default there should be an empty == infinite input region
|
||||
QCOMPARE(serverSurface->input(), QRegion());
|
||||
QCOMPARE(serverSurface->inputIsInfitine(), true);
|
||||
|
||||
// let's install an input region
|
||||
s->setInputRegion(m_compositor->createRegion(QRegion(0, 10, 20, 30)).get());
|
||||
// the region should only be applied after the surface got commited
|
||||
wl_display_flush(m_connection->display());
|
||||
QCoreApplication::processEvents();
|
||||
QCOMPARE(serverSurface->input(), QRegion());
|
||||
QCOMPARE(serverSurface->inputIsInfitine(), true);
|
||||
QCOMPARE(inputRegionChangedSpy.count(), 0);
|
||||
|
||||
// so let's commit to get the new region
|
||||
s->commit(Surface::CommitFlag::None);
|
||||
QVERIFY(inputRegionChangedSpy.wait());
|
||||
QCOMPARE(inputRegionChangedSpy.count(), 1);
|
||||
QCOMPARE(inputRegionChangedSpy.last().first().value<QRegion>(), QRegion(0, 10, 20, 30));
|
||||
QCOMPARE(serverSurface->input(), QRegion(0, 10, 20, 30));
|
||||
QCOMPARE(serverSurface->inputIsInfitine(), false);
|
||||
|
||||
// committing without setting a new region shouldn't change
|
||||
s->commit(Surface::CommitFlag::None);
|
||||
wl_display_flush(m_connection->display());
|
||||
QCoreApplication::processEvents();
|
||||
QCOMPARE(inputRegionChangedSpy.count(), 1);
|
||||
QCOMPARE(serverSurface->input(), QRegion(0, 10, 20, 30));
|
||||
QCOMPARE(serverSurface->inputIsInfitine(), false);
|
||||
|
||||
// let's change the input region
|
||||
s->setInputRegion(m_compositor->createRegion(QRegion(10, 20, 30, 40)).get());
|
||||
s->commit(Surface::CommitFlag::None);
|
||||
QVERIFY(inputRegionChangedSpy.wait());
|
||||
QCOMPARE(inputRegionChangedSpy.count(), 2);
|
||||
QCOMPARE(inputRegionChangedSpy.last().first().value<QRegion>(), QRegion(10, 20, 30, 40));
|
||||
QCOMPARE(serverSurface->input(), QRegion(10, 20, 30, 40));
|
||||
QCOMPARE(serverSurface->inputIsInfitine(), false);
|
||||
|
||||
// and let's go back to an empty region
|
||||
s->setInputRegion();
|
||||
s->commit(Surface::CommitFlag::None);
|
||||
QVERIFY(inputRegionChangedSpy.wait());
|
||||
QCOMPARE(inputRegionChangedSpy.count(), 3);
|
||||
QCOMPARE(inputRegionChangedSpy.last().first().value<QRegion>(), QRegion());
|
||||
QCOMPARE(serverSurface->input(), QRegion());
|
||||
QCOMPARE(serverSurface->inputIsInfitine(), true);
|
||||
}
|
||||
|
||||
void TestWaylandSurface::testDestroy()
|
||||
{
|
||||
using namespace KWayland::Client;
|
||||
|
|
|
@ -21,6 +21,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "surface_interface_p.h"
|
||||
#include "buffer_interface.h"
|
||||
#include "compositor_interface.h"
|
||||
#include "region_interface.h"
|
||||
#include "subcompositor_interface.h"
|
||||
#include "subsurface_interface_p.h"
|
||||
// Wayland
|
||||
|
@ -217,8 +218,8 @@ void SurfaceInterface::Private::commit()
|
|||
for (wl_resource *c : current.callbacks) {
|
||||
wl_resource_destroy(c);
|
||||
}
|
||||
const bool opaqueRegionChanged = current.opaque != pending.opaque;
|
||||
const bool inputRegionChanged = current.input != pending.input;
|
||||
const bool opaqueRegionChanged = pending.opaqueIsSet;
|
||||
const bool inputRegionChanged = pending.inputIsSet;
|
||||
const bool scaleFactorChanged = current.scale != pending.scale;
|
||||
const bool transformFactorChanged = current.transform != pending.transform;
|
||||
if (current.buffer) {
|
||||
|
@ -231,6 +232,9 @@ void SurfaceInterface::Private::commit()
|
|||
current = pending;
|
||||
pending = State{};
|
||||
pending.children = current.children;
|
||||
pending.input = current.input;
|
||||
pending.inputIsInfinite = current.inputIsInfinite;
|
||||
pending.opaque = current.opaque;
|
||||
// commit all subSurfaces to apply position changes
|
||||
for (auto it = current.children.constBegin(); it != current.children.constEnd(); ++it) {
|
||||
if (!(*it)) {
|
||||
|
@ -325,18 +329,31 @@ void SurfaceInterface::Private::frameCallaback(wl_client *client, wl_resource *r
|
|||
|
||||
void SurfaceInterface::Private::opaqueRegionCallback(wl_client *client, wl_resource *resource, wl_resource *region)
|
||||
{
|
||||
Q_UNUSED(client)
|
||||
Q_UNUSED(resource)
|
||||
Q_UNUSED(region)
|
||||
// TODO: implement me
|
||||
auto s = cast(resource);
|
||||
Q_ASSERT(client == s->client);
|
||||
auto r = RegionInterface::get(region);
|
||||
s->setOpaque(r ? r->region() : QRegion());
|
||||
}
|
||||
|
||||
void SurfaceInterface::Private::setOpaque(const QRegion ®ion)
|
||||
{
|
||||
pending.opaqueIsSet = true;
|
||||
pending.opaque = region;
|
||||
}
|
||||
|
||||
void SurfaceInterface::Private::inputRegionCallback(wl_client *client, wl_resource *resource, wl_resource *region)
|
||||
{
|
||||
Q_UNUSED(client)
|
||||
Q_UNUSED(resource)
|
||||
Q_UNUSED(region)
|
||||
// TODO: implement me
|
||||
auto s = cast(resource);
|
||||
Q_ASSERT(client == s->client);
|
||||
auto r = RegionInterface::get(region);
|
||||
s->setInput(r ? r->region() : QRegion(), !r);
|
||||
}
|
||||
|
||||
void SurfaceInterface::Private::setInput(const QRegion ®ion, bool isInfinite)
|
||||
{
|
||||
pending.inputIsSet = true;
|
||||
pending.inputIsInfinite = isInfinite;
|
||||
pending.input = region;
|
||||
}
|
||||
|
||||
void SurfaceInterface::Private::commitCallback(wl_client *client, wl_resource *resource)
|
||||
|
@ -382,6 +399,11 @@ QRegion SurfaceInterface::input() const
|
|||
return d->current.input;
|
||||
}
|
||||
|
||||
bool SurfaceInterface::inputIsInfitine() const
|
||||
{
|
||||
return d->current.inputIsInfinite;
|
||||
}
|
||||
|
||||
qint32 SurfaceInterface::scale() const
|
||||
{
|
||||
return d->current.scale;
|
||||
|
|
|
@ -57,6 +57,7 @@ public:
|
|||
QRegion damage() const;
|
||||
QRegion opaque() const;
|
||||
QRegion input() const;
|
||||
bool inputIsInfitine() const;
|
||||
qint32 scale() const;
|
||||
OutputInterface::Transform transform() const;
|
||||
BufferInterface *buffer();
|
||||
|
|
|
@ -36,6 +36,9 @@ public:
|
|||
QRegion damage = QRegion();
|
||||
QRegion opaque = QRegion();
|
||||
QRegion input = QRegion();
|
||||
bool inputIsSet = false;
|
||||
bool opaqueIsSet = false;
|
||||
bool inputIsInfinite = true;
|
||||
qint32 scale = 1;
|
||||
OutputInterface::Transform transform = OutputInterface::Transform::Normal;
|
||||
QList<wl_resource*> callbacks = QList<wl_resource*>();
|
||||
|
@ -71,6 +74,8 @@ private:
|
|||
void setTransform(OutputInterface::Transform transform);
|
||||
void addFrameCallback(uint32_t callback);
|
||||
void attachBuffer(wl_resource *buffer, const QPoint &offset);
|
||||
void setOpaque(const QRegion ®ion);
|
||||
void setInput(const QRegion ®ion, bool isInfinite);
|
||||
|
||||
static Private *cast(wl_resource *r);
|
||||
|
||||
|
|
Loading…
Reference in a new issue