wayland/surface: add the output a surface is on the most

This commit is contained in:
Xaver Hugl 2023-10-23 19:57:59 +02:00
parent b40e960ad7
commit 15d6d8c336
8 changed files with 33 additions and 13 deletions

View file

@ -865,7 +865,7 @@ void TestWaylandSurface::testOutput()
m_display->dispatchEvents();
// now enter it
serverSurface->setOutputs(QList<OutputInterface *>{serverOutput.get()});
serverSurface->setOutputs(QList<OutputInterface *>{serverOutput.get()}, serverOutput.get());
QCOMPARE(serverSurface->outputs(), QList<OutputInterface *>{serverOutput.get()});
QVERIFY(enteredSpy.wait());
QCOMPARE(enteredSpy.count(), 1);
@ -873,10 +873,10 @@ void TestWaylandSurface::testOutput()
QCOMPARE(s->outputs(), QList<KWayland::Client::Output *>{clientOutput.get()});
// adding to same should not trigger
serverSurface->setOutputs(QList<OutputInterface *>{serverOutput.get()});
serverSurface->setOutputs(QList<OutputInterface *>{serverOutput.get()}, serverOutput.get());
// leave again
serverSurface->setOutputs(QList<OutputInterface *>());
serverSurface->setOutputs(QList<OutputInterface *>(), nullptr);
QCOMPARE(serverSurface->outputs(), QList<OutputInterface *>());
QVERIFY(leftSpy.wait());
QCOMPARE(enteredSpy.count(), 1);
@ -885,10 +885,10 @@ void TestWaylandSurface::testOutput()
QCOMPARE(s->outputs(), QList<KWayland::Client::Output *>());
// leave again should not trigger
serverSurface->setOutputs(QList<OutputInterface *>());
serverSurface->setOutputs(QList<OutputInterface *>(), nullptr);
// and enter again, just to verify
serverSurface->setOutputs(QList<OutputInterface *>{serverOutput.get()});
serverSurface->setOutputs(QList<OutputInterface *>{serverOutput.get()}, serverOutput.get());
QCOMPARE(serverSurface->outputs(), QList<OutputInterface *>{serverOutput.get()});
QVERIFY(enteredSpy.wait());
QCOMPARE(enteredSpy.count(), 2);

View file

@ -920,7 +920,8 @@ void CursorImage::updateCursorOutputs(const QPointF &pos)
auto cursorSurface = m_serverCursor.surface->surface();
if (cursorSurface) {
const QRectF cursorGeometry(pos - m_currentSource->hotspot(), m_currentSource->size());
cursorSurface->setOutputs(waylandServer()->display()->outputsIntersecting(cursorGeometry.toAlignedRect()));
cursorSurface->setOutputs(waylandServer()->display()->outputsIntersecting(cursorGeometry.toAlignedRect()),
waylandServer()->display()->largestIntersectingOutput(cursorGeometry.toAlignedRect()));
}
}
}

View file

@ -172,6 +172,21 @@ QList<OutputInterface *> Display::outputsIntersecting(const QRect &rect) const
return outputs;
}
OutputInterface *Display::largestIntersectingOutput(const QRect &rect) const
{
OutputInterface *returnOutput = nullptr;
uint64_t biggestArea = 0;
for (auto *output : std::as_const(d->outputs)) {
const QRect intersect = output->handle()->geometry().intersected(rect);
const uint64_t area = intersect.width() * intersect.height();
if (area > biggestArea) {
biggestArea = area;
returnOutput = output;
}
}
return returnOutput;
}
QList<SeatInterface *> Display::seats() const
{
return d->seats;

View file

@ -102,6 +102,7 @@ public:
QList<OutputDeviceV2Interface *> outputDevices() const;
QList<OutputInterface *> outputs() const;
QList<OutputInterface *> outputsIntersecting(const QRect &rect) const;
OutputInterface *largestIntersectingOutput(const QRect &rect) const;
/**
* Gets the ClientConnection for the given @p client.

View file

@ -75,7 +75,7 @@ void SurfaceInterfacePrivate::addChild(SubSurfaceInterface *child)
});
}
child->surface()->setOutputs(outputs);
child->surface()->setOutputs(outputs, primaryOutput);
if (preferredBufferScale.has_value()) {
child->surface()->setPreferredBufferScale(preferredBufferScale.value());
}
@ -947,7 +947,7 @@ QList<OutputInterface *> SurfaceInterface::outputs() const
return d->outputs;
}
void SurfaceInterface::setOutputs(const QList<OutputInterface *> &outputs)
void SurfaceInterface::setOutputs(const QList<OutputInterface *> &outputs, OutputInterface *primaryOutput)
{
QList<OutputInterface *> removedOutputs = d->outputs;
for (auto it = outputs.constBegin(), end = outputs.constEnd(); it != end; ++it) {
@ -976,7 +976,7 @@ void SurfaceInterface::setOutputs(const QList<OutputInterface *> &outputs)
d->outputDestroyedConnections[o] = connect(o, &OutputInterface::removed, this, [this, o] {
auto outputs = d->outputs;
if (outputs.removeOne(o)) {
setOutputs(outputs);
setOutputs(outputs, d->primaryOutput);
}
});
@ -990,11 +990,12 @@ void SurfaceInterface::setOutputs(const QList<OutputInterface *> &outputs)
}
d->outputs = outputs;
d->primaryOutput = primaryOutput;
for (auto child : std::as_const(d->current->subsurface.below)) {
child->surface()->setOutputs(outputs);
child->surface()->setOutputs(outputs, primaryOutput);
}
for (auto child : std::as_const(d->current->subsurface.above)) {
child->surface()->setOutputs(outputs);
child->surface()->setOutputs(outputs, primaryOutput);
}
}

View file

@ -281,7 +281,7 @@ public:
*
* @see outputs
*/
void setOutputs(const QList<OutputInterface *> &outputs);
void setOutputs(const QList<OutputInterface *> &outputs, OutputInterface *primaryOutput);
/**
* @returns All OutputInterfaces the SurfaceInterface is on.

View file

@ -146,6 +146,7 @@ public:
Transaction *lastTransaction = nullptr;
QList<OutputInterface *> outputs;
OutputInterface *primaryOutput = nullptr;
std::optional<qreal> preferredBufferScale;
std::optional<OutputTransform> preferredBufferTransform;

View file

@ -156,7 +156,8 @@ void WaylandWindow::updateClientOutputs()
if (isDeleted()) {
return;
}
surface()->setOutputs(waylandServer()->display()->outputsIntersecting(frameGeometry().toAlignedRect()));
surface()->setOutputs(waylandServer()->display()->outputsIntersecting(frameGeometry().toAlignedRect()),
waylandServer()->display()->largestIntersectingOutput(frameGeometry().toAlignedRect()));
if (output()) {
surface()->setPreferredBufferScale(output()->scale());
surface()->setPreferredBufferTransform(output()->transform());