29#include <wayland-server.h>
37static QRegion map_helper(
const QMatrix4x4 &matrix,
const QRegion ®ion)
40 for (
const QRect &rect : region) {
41 result += matrix.mapRect(QRectF(rect)).toAlignedRect();
67 pending->subsurface.above.append(child);
99 current->subsurface.below.removeAll(child);
100 current->subsurface.above.removeAll(child);
102 pending->subsurface.below.removeAll(child);
103 pending->subsurface.above.removeAll(child);
127 QList<SubSurfaceInterface *> *anchorList;
135 anchorList = &
pending->subsurface.above;
137 }
else if (anchorIndex =
pending->subsurface.above.indexOf(anchor->
subSurface()); anchorIndex != -1) {
138 anchorList = &
pending->subsurface.above;
139 }
else if (anchorIndex =
pending->subsurface.below.indexOf(anchor->
subSurface()); anchorIndex != -1) {
140 anchorList = &
pending->subsurface.below;
145 anchorList->insert(anchorIndex + 1,
subsurface);
146 pending->subsurfaceOrderChanged =
true;
154 QList<SubSurfaceInterface *> *anchorList;
162 anchorList = &
pending->subsurface.below;
163 anchorIndex =
pending->subsurface.below.count();
164 }
else if (anchorIndex =
pending->subsurface.above.indexOf(anchor->
subSurface()); anchorIndex != -1) {
165 anchorList = &
pending->subsurface.above;
166 }
else if (anchorIndex =
pending->subsurface.below.indexOf(anchor->
subSurface()); anchorIndex != -1) {
167 anchorList = &
pending->subsurface.below;
173 pending->subsurfaceOrderChanged =
true;
208 auto cleanUp = [
this]() {
210 QObject::disconnect(constrainsOneShotConnection);
211 constrainsOneShotConnection = QMetaObject::Connection();
212 QObject::disconnect(constrainsUnboundConnection);
213 constrainsUnboundConnection = QMetaObject::Connection();
225 constrainsUnboundConnection = QObject::connect(lock, &LockedPointerV1Interface::destroyed,
q, cleanUp);
236 auto cleanUp = [
this]() {
238 QObject::disconnect(constrainsOneShotConnection);
239 constrainsOneShotConnection = QMetaObject::Connection();
240 QObject::disconnect(constrainsUnboundConnection);
241 constrainsUnboundConnection = QMetaObject::Connection();
253 constrainsUnboundConnection = QObject::connect(confinement, &ConfinedPointerV1Interface::destroyed,
q, cleanUp);
281 wl_resource_destroy(resource->handle);
286 if (wl_resource_get_version(resource->handle) >= WL_SURFACE_OFFSET_SINCE_VERSION) {
287 if (x != 0 || y != 0) {
288 wl_resource_post_error(resource->handle, error_invalid_offset,
"wl_surface.attach offset must be 0");
292 pending->offset = QPoint(x, y);
300 pending->bufferDamage = QRegion();
303 pending->buffer = Display::bufferForResource(buffer);
308 pending->damage += QRect(x, y, width, height);
313 wl_resource *callbackResource = wl_resource_create(resource->client(),
314 &wl_callback_interface,
317 if (!callbackResource) {
318 wl_resource_post_no_memory(resource->handle);
322 wl_resource_set_implementation(callbackResource,
nullptr,
nullptr, [](wl_resource *resource) {
323 wl_list_remove(wl_resource_get_link(resource));
326 wl_list_insert(
pending->frameCallbacks.prev, wl_resource_get_link(callbackResource));
350 subsurface.transaction = std::make_unique<Transaction>();
359 if (surfacePrivate->subsurface.transaction) {
360 transaction->merge(surfacePrivate->subsurface.transaction.get());
361 surfacePrivate->subsurface.transaction.reset();
366 if (surfacePrivate->subsurface.transaction) {
367 transaction->merge(surfacePrivate->subsurface.transaction.get());
368 surfacePrivate->subsurface.transaction.reset();
382 if (transform < 0 || transform > WL_OUTPUT_TRANSFORM_FLIPPED_270) {
383 wl_resource_post_error(resource->handle, error_invalid_transform,
"buffer transform must be a valid transform (%d specified)", transform);
387 pending->bufferTransformIsSet =
true;
393 wl_resource_post_error(resource->handle, error_invalid_scale,
"buffer scale must be at least one (%d specified)", scale);
397 pending->bufferScaleIsSet =
true;
402 pending->bufferDamage += QRect(x, y, width, height);
407 pending->offset = QPoint(x, y);
411 : QObject(compositor)
418 d->pendingScaleOverride = d->client->scaleOverride();
419 d->scaleOverride = d->pendingScaleOverride;
421 d->pendingScaleOverride = d->client->scaleOverride();
441 return wl_resource_get_id(
resource());
451 return d->resource()->handle;
456 return d->compositor;
465 wl_resource_for_each_safe (
resource, tmp, &d->current->frameCallbacks) {
466 wl_callback_send_done(
resource, msec);
473 if (output && (!d->primaryOutput || d->primaryOutput->handle() != output)) {
476 return std::move(d->current->presentationFeedback);
481 return !wl_list_empty(&d->current->frameCallbacks);
486 if (!
current->viewport.sourceGeometry.isValid()) {
491 const QRectF box(
current->viewport.sourceGeometry.x() *
current->bufferScale,
494 current->viewport.sourceGeometry.height() *
current->bufferScale);
496 return current->bufferTransform.map(box, bounds);
506 wl_resource *resource;
510 wl_resource_destroy(resource);
529 if (
viewport.destinationSizeIsSet) {
595 const bool opaqueRegionChanged = next->
opaqueIsSet;
598 const bool blurChanged = next->
blurIsSet;
602 const bool visibilityChanged = bufferChanged && bool(
current->buffer) != bool(next->
buffer);
619 if (
current->viewport.destinationSize.isValid()) {
621 }
else if (
current->viewport.sourceGeometry.isValid()) {
627 const QRectF surfaceRect(QPoint(0, 0),
surfaceSize);
630 if (!
current->buffer->hasAlphaChannel()) {
636 QMatrix4x4 scaleOverrideMatrix;
652 if (opaqueRegionChanged) {
658 if (transformChanged) {
661 if (visibilityChanged) {
679 if (contrastChanged) {
685 if (subsurfaceOrderChanged) {
688 if (colorDescriptionChanged) {
691 if (presentationModeHintChanged) {
697 const QRect bufferRect = QRect(QPoint(0, 0),
current->buffer->size());
700 .intersected(bufferRect);
731 if (
mapped == effectiveMapped) {
745 surfacePrivate->updateEffectiveMapped();
749 surfacePrivate->updateEffectiveMapped();
756 const qreal x = position.x();
757 const qreal y = position.y();
764 return contains(position) &&
inputRegion.contains(QPoint(std::floor(position.x()), std::floor(position.y())));
769 if (region.isEmpty()) {
774 const qreal xScale = sourceBox.width() /
surfaceSize.width();
775 const qreal yScale = sourceBox.height() /
surfaceSize.height();
778 for (QRectF rect : region) {
779 result +=
current->bufferTransform.map(QRectF(rect.x() * xScale, rect.y() * yScale, rect.width() * xScale, rect.height() * yScale), sourceBox.size()).translated(
bufferSourceBox.topLeft()).toAlignedRect();
786 return d->bufferDamage;
791 return d->opaqueRegion;
796 return d->inputRegion;
801 return d->bufferSourceBox;
806 return d->current->bufferTransform;
811 return d->bufferRef.buffer();
816 return d->current->offset / d->scaleOverride;
821 if (
auto surfacePrivate = resource_cast<SurfaceInterfacePrivate *>(native)) {
822 return surfacePrivate->q;
837 return d->current->subsurface.below;
842 return d->current->subsurface.above;
847 return d->subsurface.handle;
852 return d->surfaceSize;
857 QRectF rect(QPoint(0, 0),
size());
873 return d->current->shadow;
878 return d->current->blur;
883 return d->current->contrast;
888 return d->current->slide;
903 QList<OutputInterface *> removedOutputs = d->outputs;
904 for (
auto it =
outputs.constBegin(), end =
outputs.constEnd(); it != end; ++it) {
906 removedOutputs.removeOne(o);
908 for (
auto it = removedOutputs.constBegin(), end = removedOutputs.constEnd(); it != end; ++it) {
909 const auto resources = (*it)->clientResources(
client()->
client());
910 for (wl_resource *outputResource : resources) {
911 d->send_leave(outputResource);
913 disconnect(d->outputDestroyedConnections.take(*it));
914 disconnect(d->outputBoundConnections.take(*it));
916 QList<OutputInterface *> addedOutputsOutputs =
outputs;
917 for (
auto it = d->outputs.constBegin(), end = d->outputs.constEnd(); it != end; ++it) {
919 addedOutputsOutputs.removeOne(o);
921 for (
auto it = addedOutputsOutputs.constBegin(), end = addedOutputsOutputs.constEnd(); it != end; ++it) {
923 const auto resources = o->clientResources(
client()->
client());
924 for (wl_resource *outputResource : resources) {
925 d->send_enter(outputResource);
930 setOutputs(outputs, d->primaryOutput);
934 Q_ASSERT(!d->outputBoundConnections.contains(o));
939 d->send_enter(outputResource);
944 d->primaryOutput = primaryOutput;
945 for (
auto child : std::as_const(d->current->subsurface.below)) {
946 child->surface()->setOutputs(
outputs, primaryOutput);
948 for (
auto child : std::as_const(d->current->subsurface.above)) {
949 child->surface()->setOutputs(
outputs, primaryOutput);
959 for (
auto it = d->current->subsurface.above.crbegin(); it != d->current->subsurface.above.crend(); ++it) {
968 if (d->contains(position)) {
972 for (
auto it = d->current->subsurface.below.crbegin(); it != d->current->subsurface.below.crend(); ++it) {
990 for (
auto it = d->current->subsurface.above.crbegin(); it != d->current->subsurface.above.crend(); ++it) {
992 auto surface = current->
surface();
993 if (
auto s = surface->inputSurfaceAt(position - current->
position())) {
999 if (d->inputContains(position)) {
1003 for (
auto it = d->current->subsurface.below.crbegin(); it != d->current->subsurface.below.crend(); ++it) {
1005 auto surface = current->
surface();
1006 if (
auto s = surface->inputSurfaceAt(position - current->
position())) {
1016 return d->lockedPointer;
1021 return d->confinedPointer;
1026 return !d->idleInhibitors.isEmpty();
1031 return d->dmabufFeedbackV1.get();
1036 return d->current->contentType;
1041 QPointF local = point;
1045 if (surface ==
this) {
1050 if (Q_UNLIKELY(!subsurface)) {
1063 return d->bufferSize;
1068 return d->scaleOverride;
1073 return QPoint(point.x() * d->scaleOverride, point.y() * d->scaleOverride);
1078 return QPointF(point.x() * d->scaleOverride, point.y() * d->scaleOverride);
1083 return d->current->presentationHint;
1088 return d->current->colorDescription;
1093 d->preferredColorDescription = descr;
1094 if (d->frogColorManagement) {
1095 d->frogColorManagement->setPreferredColorDescription(descr);
1097 if (d->xxColorSurface) {
1098 d->xxColorSurface->setPreferredColorDescription(descr);
1100 for (
auto child : std::as_const(d->current->subsurface.below)) {
1101 child->surface()->setPreferredColorDescription(descr);
1103 for (
auto child : std::as_const(d->current->subsurface.above)) {
1104 child->surface()->setPreferredColorDescription(descr);
1110 if (scale == d->preferredBufferScale) {
1113 d->preferredBufferScale = scale;
1115 if (d->fractionalScaleExtension) {
1116 d->fractionalScaleExtension->setPreferredScale(scale);
1118 if (d->resource()->version() >= WL_SURFACE_PREFERRED_BUFFER_SCALE_SINCE_VERSION) {
1119 d->send_preferred_buffer_scale(std::ceil(scale));
1122 for (
auto child : std::as_const(d->current->subsurface.below)) {
1123 child->surface()->setPreferredBufferScale(scale);
1125 for (
auto child : std::as_const(d->current->subsurface.above)) {
1126 child->surface()->setPreferredBufferScale(scale);
1132 if (transform == d->preferredBufferTransform) {
1135 d->preferredBufferTransform = transform;
1137 if (d->resource()->version() >= WL_SURFACE_PREFERRED_BUFFER_TRANSFORM_SINCE_VERSION) {
1138 d->send_preferred_buffer_transform(uint32_t(transform.
kind()));
1141 for (
auto child : std::as_const(d->current->subsurface.below)) {
1142 child->surface()->setPreferredBufferTransform(transform);
1144 for (
auto child : std::as_const(d->current->subsurface.above)) {
1145 child->surface()->setPreferredBufferTransform(transform);
1151 return d->firstTransaction;
1156 d->firstTransaction = transaction;
1161 return d->lastTransaction;
1166 d->lastTransaction = transaction;
1174 subsurface->surface()->traverseTree(callback);
1177 subsurface->surface()->traverseTree(callback);
1183#include "moc_surface.cpp"
Represents the Resource for the org_kde_kwin_blur interface.
Convenient Class which represents a wl_client.
wl_resource * getResource(quint32 id) const
wl_client * client() const
void scaleOverrideChanged()
Display * display() const
LifeTime lifeTime() const
Represents the Resource for the org_kde_kwin_contrast interface.
ClientConnection * getConnection(wl_client *client)
virtual QSize size() const =0
LifeTime lifeTime() const
void bound(ClientConnection *client, wl_resource *boundResource)
static RegionInterface * get(wl_resource *native)
SurfaceInterface * parentSurface() const
SurfaceInterface * surface() const
Resource representing a wl_surface.
SlideInterface * slideOnShowHide() const
std::unique_ptr< PresentationFeedback > takePresentationFeedback(Output *output)
const ColorDescription & colorDescription() const
SurfaceInterface * surfaceAt(const QPointF &position)
ClientConnection * client() const
void damaged(const QRegion &)
PresentationModeHint presentationModeHint() const
static SurfaceInterface * get(wl_resource *native)
ContentType contentType() const
void childSubSurfacesChanged()
void inhibitsIdleChanged()
void setPreferredBufferScale(qreal scale)
void stateApplied(quint32 serial)
QRectF bufferSourceBox() const
QRegion bufferDamage() const
BlurInterface * blur() const
void setPreferredBufferTransform(OutputTransform transform)
void inputChanged(const QRegion &)
void aboutToBeDestroyed()
void childSubSurfaceRemoved(SubSurfaceInterface *subSurface)
void traverseTree(std::function< void(SurfaceInterface *surface)> callback)
void slideOnShowHideChanged()
void pointerConstraintsChanged()
QPointF mapToChild(SurfaceInterface *child, const QPointF &point) const
void setLastTransaction(Transaction *transaction)
OutputTransform bufferTransform() const
GraphicsBuffer * buffer() const
QPoint toSurfaceLocal(const QPoint &point) const
SurfaceRole * role() const
ShadowInterface * shadow() const
QList< OutputInterface * > outputs() const
void bufferTransformChanged(KWin::OutputTransform)
void setFirstTransaction(Transaction *transaction)
SurfaceInterface(CompositorInterface *compositor, wl_resource *resource)
ContrastInterface * contrast() const
SubSurfaceInterface * subSurface() const
void presentationModeHintChanged()
wl_resource * resource() const
void opaqueChanged(const QRegion &)
void childSubSurfaceAdded(SubSurfaceInterface *subSurface)
QList< SubSurfaceInterface * > above() const
LinuxDmaBufV1Feedback * dmabufFeedbackV1() const
~SurfaceInterface() override
Transaction * firstTransaction() const
void frameRendered(quint32 msec)
ConfinedPointerV1Interface * confinedPointer() const
CompositorInterface * compositor() const
void setOutputs(const QList< OutputInterface * > &outputs, OutputInterface *primaryOutput)
QList< SubSurfaceInterface * > below() const
void colorDescriptionChanged()
QRectF boundingRect() const
void setPreferredColorDescription(const ColorDescription &descr)
bool inhibitsIdle() const
void bufferSourceBoxChanged()
LockedPointerV1Interface * lockedPointer() const
qreal scaleOverride() const
SurfaceInterface * inputSurfaceAt(const QPointF &position)
void setRole(SurfaceRole *role)
bool hasFrameCallbacks() const
Transaction * lastTransaction() const
QRectF computeBufferSourceBox() const
void surface_commit(Resource *resource) override
void setContrast(const QPointer< ContrastInterface > &contrast)
void installIdleInhibitor(IdleInhibitorV1Interface *inhibitor)
void removeIdleInhibitor(IdleInhibitorV1Interface *inhibitor)
void surface_set_input_region(Resource *resource, struct ::wl_resource *region) override
void setBlur(const QPointer< BlurInterface > &blur)
void surface_set_buffer_scale(Resource *resource, int32_t scale) override
bool raiseChild(SubSurfaceInterface *subsurface, SurfaceInterface *anchor)
ConfinedPointerV1Interface * confinedPointer
QList< OutputInterface * > outputs
std::unique_ptr< Transaction > transaction
bool contains(const QPointF &position) const
void surface_destroy(Resource *resource) override
std::unique_ptr< SurfaceState > current
void surface_frame(Resource *resource, uint32_t callback) override
std::optional< qreal > preferredBufferScale
void setShadow(const QPointer< ShadowInterface > &shadow)
void removeChild(SubSurfaceInterface *subsurface)
bool computeEffectiveMapped() const
std::unique_ptr< SurfaceState > pending
void surface_damage(Resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) override
void surface_destroy_resource(Resource *resource) override
void updateEffectiveMapped()
static SurfaceInterfacePrivate * get(SurfaceInterface *surface)
QRegion mapToBuffer(const QRegion ®ion) const
void installPointerConstraint(LockedPointerV1Interface *lock)
bool inputContains(const QPointF &position) const
GraphicsBufferRef bufferRef
void surface_damage_buffer(Resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) override
void surface_attach(Resource *resource, struct ::wl_resource *buffer, int32_t x, int32_t y) override
LockedPointerV1Interface * lockedPointer
QList< IdleInhibitorV1Interface * > idleInhibitors
SurfaceInterfacePrivate(SurfaceInterface *q)
QPointer< OutputInterface > primaryOutput
void addChild(SubSurfaceInterface *subsurface)
void surface_set_buffer_transform(Resource *resource, int32_t transform) override
void surface_set_opaque_region(Resource *resource, struct ::wl_resource *region) override
qreal pendingScaleOverride
struct KWin::SurfaceInterfacePrivate::@30 subsurface
Transaction * firstTransaction
void surface_offset(Resource *resource, int32_t x, int32_t y) override
void applyState(SurfaceState *next)
bool lowerChild(SubSurfaceInterface *subsurface, SurfaceInterface *anchor)
std::optional< OutputTransform > preferredBufferTransform
void setSlide(const QPointer< SlideInterface > &slide)
std::optional< ColorDescription > preferredColorDescription
SurfaceRole(const QByteArray &name)
Transaction * next(SurfaceInterface *surface) const
KWIN_EXPORT QRect infiniteRegion()
bool destinationSizeIsSet
QPointer< ContrastInterface > contrast
struct KWin::SurfaceState::@29 viewport
void mergeInto(SurfaceState *target)
bool colorDescriptionIsSet
QPointer< SlideInterface > slide
OutputTransform bufferTransform
bool presentationModeHintIsSet
PresentationModeHint presentationHint
struct KWin::SurfaceState::@28 subsurface
QPointer< ShadowInterface > shadow
QPointer< BlurInterface > blur
QList< SubSurfaceInterface * > below
ColorDescription colorDescription
bool bufferTransformIsSet
bool subsurfacePositionChanged
QPointer< GraphicsBuffer > buffer
std::unique_ptr< PresentationTimeFeedback > presentationFeedback
bool subsurfaceOrderChanged
QList< SubSurfaceInterface * > above