[server] Respect input region of sub-surfaces on pointer surface focus
Summary: KWayland takes always the top-most child surface at a given position for its pointer input. But if a sub-surface sets its input region, it should not select this one when the position is out of its input region, but rather try the surface below. Test Plan: My testing was only on my Xwayland branch. Supposed to also fix a problem with Firefox native Wayland port. Reviewers: #frameworks, graesslin, davidedmundson Reviewed By: davidedmundson Subscribers: davidedmundson, zzag, kde-frameworks-devel, graesslin, plasma-devel Tags: #frameworks, #plasma_on_wayland Differential Revision: https://phabricator.kde.org/D7038
This commit is contained in:
parent
1955e15afa
commit
96967485ba
3 changed files with 46 additions and 2 deletions
|
@ -241,7 +241,7 @@ PointerInterface::PointerInterface(SeatInterface *parent, wl_resource *parentRes
|
|||
return;
|
||||
}
|
||||
const QPointF pos = d->seat->focusedPointerSurfaceTransformation().map(d->seat->pointerPos());
|
||||
auto targetSurface = d->focusedSurface->surfaceAt(pos);
|
||||
auto targetSurface = d->focusedSurface->inputSurfaceAt(pos);
|
||||
if (!targetSurface) {
|
||||
targetSurface = d->focusedSurface;
|
||||
}
|
||||
|
@ -286,7 +286,7 @@ void PointerInterface::setFocusedSurface(SurfaceInterface *surface, quint32 seri
|
|||
);
|
||||
|
||||
const QPointF pos = d->seat->focusedPointerSurfaceTransformation().map(d->seat->pointerPos());
|
||||
d->focusedChildSurface = QPointer<SurfaceInterface>(d->focusedSurface->surfaceAt(pos));
|
||||
d->focusedChildSurface = QPointer<SurfaceInterface>(d->focusedSurface->inputSurfaceAt(pos));
|
||||
if (!d->focusedChildSurface) {
|
||||
d->focusedChildSurface = QPointer<SurfaceInterface>(d->focusedSurface);
|
||||
}
|
||||
|
|
|
@ -856,6 +856,35 @@ SurfaceInterface *SurfaceInterface::surfaceAt(const QPointF &position)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
SurfaceInterface *SurfaceInterface::inputSurfaceAt(const QPointF &position)
|
||||
{
|
||||
// TODO: Most of this is very similar to SurfaceInterface::surfaceAt
|
||||
// Is there a way to reduce the code duplication?
|
||||
if (!isMapped()) {
|
||||
return nullptr;
|
||||
}
|
||||
Q_D();
|
||||
// go from top to bottom. Top most child is last in list
|
||||
QListIterator<QPointer<SubSurfaceInterface>> it(d->current.children);
|
||||
it.toBack();
|
||||
while (it.hasPrevious()) {
|
||||
const auto ¤t = it.previous();
|
||||
auto surface = current->surface();
|
||||
if (surface.isNull()) {
|
||||
continue;
|
||||
}
|
||||
if (auto s = surface->inputSurfaceAt(position - current->position())) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
// check whether the geometry and input region contain the pos
|
||||
if (!size().isEmpty() && QRectF(QPoint(0, 0), size()).contains(position) &&
|
||||
(inputIsInfinite() || input().contains(position.toPoint()))) {
|
||||
return this;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QPointer<LockedPointerInterface> SurfaceInterface::lockedPointer() const
|
||||
{
|
||||
Q_D();
|
||||
|
|
|
@ -211,6 +211,21 @@ public:
|
|||
**/
|
||||
SurfaceInterface *surfaceAt(const QPointF &position);
|
||||
|
||||
/**
|
||||
* Finds the input receiving SurfaceInterface at the given @p position in surface-local coordinates.
|
||||
* This can be either a descendant SurfaceInterface honoring the stacking order or
|
||||
* the SurfaceInterface itself if its geometry contains the given @p position.
|
||||
*
|
||||
* If no such SurfaceInterface is found, e.g. because the SurfaceInterface is unmapped or there is no
|
||||
* input region containing the position,
|
||||
* @c nullptr is returned.
|
||||
*
|
||||
* @param position The position in surface-local coordinates
|
||||
* @returns Input receiving child surface at the given @p position or surface itself at the position, might be @c nullptr
|
||||
* @since 5.52
|
||||
**/
|
||||
SurfaceInterface *inputSurfaceAt(const QPointF &position);
|
||||
|
||||
/**
|
||||
* Sets the @p outputs this SurfaceInterface overlaps with, may be empty.
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue