summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compositor/compositor_api/qwaylandpointer.cpp90
-rw-r--r--src/compositor/compositor_api/qwaylandpointer_p.h6
2 files changed, 60 insertions, 36 deletions
diff --git a/src/compositor/compositor_api/qwaylandpointer.cpp b/src/compositor/compositor_api/qwaylandpointer.cpp
index 267b5d98..d1ca174d 100644
--- a/src/compositor/compositor_api/qwaylandpointer.cpp
+++ b/src/compositor/compositor_api/qwaylandpointer.cpp
@@ -51,17 +51,29 @@ QWaylandPointerPrivate::QWaylandPointerPrivate(QWaylandPointer *pointer, QWaylan
, wl_pointer()
, seat(seat)
, output()
- , focusResource()
, hasSentEnter(false)
+ , enterSerial(0)
, buttonCount()
{
Q_UNUSED(pointer);
}
-void QWaylandPointerPrivate::pointer_destroy_resource(wl_pointer::Resource *resource)
+const QList<QtWaylandServer::wl_pointer::Resource *> QWaylandPointerPrivate::pointerResourcesForFocusedSurface() const
{
- if (focusResource == resource->handle)
- focusResource = 0;
+ if (!seat->mouseFocus())
+ return {};
+
+ return resourceMap().values(seat->mouseFocus()->surfaceResource()->client);
+}
+
+uint QWaylandPointerPrivate::sendButton(Qt::MouseButton button, uint32_t state)
+{
+ Q_Q(QWaylandPointer);
+ uint32_t time = compositor()->currentTimeMsecs();
+ uint32_t serial = compositor()->nextSerial();
+ for (auto resource : pointerResourcesForFocusedSurface())
+ send_button(resource->handle, serial, time, q->toWaylandButton(button), state);
+ return serial;
}
void QWaylandPointerPrivate::pointer_release(wl_pointer::Resource *resource)
@@ -160,12 +172,11 @@ void QWaylandPointer::setOutput(QWaylandOutput *output)
uint QWaylandPointer::sendMousePressEvent(Qt::MouseButton button)
{
Q_D(QWaylandPointer);
- uint32_t time = d->compositor()->currentTimeMsecs();
d->buttonCount++;
uint serial = 0;
- if (d->focusResource)
- serial = sendButton(d->focusResource, time, button, WL_POINTER_BUTTON_STATE_PRESSED);
+ if (d->seat->mouseFocus())
+ serial = d->sendButton(button, WL_POINTER_BUTTON_STATE_PRESSED);
if (d->buttonCount == 1) {
emit buttonPressedChanged();
@@ -182,12 +193,11 @@ uint QWaylandPointer::sendMousePressEvent(Qt::MouseButton button)
uint QWaylandPointer::sendMouseReleaseEvent(Qt::MouseButton button)
{
Q_D(QWaylandPointer);
- uint32_t time = d->compositor()->currentTimeMsecs();
d->buttonCount--;
uint serial = 0;
- if (d->focusResource)
- serial = sendButton(d->focusResource, time, button, WL_POINTER_BUTTON_STATE_RELEASED);
+ if (d->seat->mouseFocus())
+ serial = d->sendButton(button, WL_POINTER_BUTTON_STATE_RELEASED);
if (d->buttonCount == 0)
emit buttonPressedChanged();
@@ -219,31 +229,30 @@ void QWaylandPointer::sendMouseMoveEvent(QWaylandView *view, const QPointF &loca
d->localPosition.ry() -= 0.01;
}
- QWaylandPointerPrivate::Resource *resource = view ? d->resourceMap().value(view->surface()->waylandClient()) : 0;
- if (resource && !d->hasSentEnter) {
- uint32_t serial = d->compositor()->nextSerial();
+ if (!d->hasSentEnter) {
+ d->enterSerial = d->compositor()->nextSerial();
QWaylandKeyboard *keyboard = d->seat->keyboard();
- if (keyboard) {
- keyboard->sendKeyModifiers(view->surface()->client(), serial);
+ if (keyboard)
+ keyboard->sendKeyModifiers(view->surface()->client(), d->enterSerial);
+ for (auto resource : d->pointerResourcesForFocusedSurface()) {
+ d->send_enter(resource->handle, d->enterSerial, view->surface()->resource(),
+ wl_fixed_from_double(d->localPosition.x()),
+ wl_fixed_from_double(d->localPosition.y()));
}
- d->send_enter(resource->handle, serial, view->surface()->resource(),
- wl_fixed_from_double(d->localPosition.x()), wl_fixed_from_double(d->localPosition.y()));
-
d->focusDestroyListener.listenForDestruction(view->surface()->resource());
d->hasSentEnter = true;
}
- d->focusResource = resource ? resource->handle : 0;
-
if (view && view->output())
setOutput(view->output());
uint32_t time = d->compositor()->currentTimeMsecs();
- if (d->focusResource) {
+ if (d->seat->mouseFocus()) {
wl_fixed_t x = wl_fixed_from_double(currentLocalPosition().x());
wl_fixed_t y = wl_fixed_from_double(currentLocalPosition().y());
- wl_pointer_send_motion(d->focusResource, time, x, y);
+ for (auto resource : d->pointerResourcesForFocusedSurface())
+ wl_pointer_send_motion(resource->handle, time, x, y);
}
}
@@ -253,13 +262,15 @@ void QWaylandPointer::sendMouseMoveEvent(QWaylandView *view, const QPointF &loca
void QWaylandPointer::sendMouseWheelEvent(Qt::Orientation orientation, int delta)
{
Q_D(QWaylandPointer);
- if (!d->focusResource)
+ if (!d->seat->mouseFocus())
return;
uint32_t time = d->compositor()->currentTimeMsecs();
uint32_t axis = orientation == Qt::Horizontal ? WL_POINTER_AXIS_HORIZONTAL_SCROLL
: WL_POINTER_AXIS_VERTICAL_SCROLL;
- d->send_axis(d->focusResource, time, axis, wl_fixed_from_int(-delta / 12));
+
+ for (auto resource : d->pointerResourcesForFocusedSurface())
+ d->send_axis(resource->handle, time, axis, wl_fixed_from_int(-delta / 12));
}
/*!
@@ -304,19 +315,30 @@ bool QWaylandPointer::isButtonPressed() const
void QWaylandPointer::addClient(QWaylandClient *client, uint32_t id, uint32_t version)
{
Q_D(QWaylandPointer);
- d->add(client->client(), id, qMin<uint32_t>(QtWaylandServer::wl_pointer::interfaceVersion(), version));
+ wl_resource *resource = d->add(client->client(), id, qMin<uint32_t>(QtWaylandServer::wl_pointer::interfaceVersion(), version))->handle;
+ QWaylandView *focus = d->seat->mouseFocus();
+ if (focus && client == focus->surface()->client()) {
+ d->send_enter(resource, d->enterSerial, focus->surfaceResource(),
+ wl_fixed_from_double(d->localPosition.x()),
+ wl_fixed_from_double(d->localPosition.y()));
+ }
}
/*!
- * Returns the Wayland resource for this QWaylandPointer.
+ * Returns a Wayland resource for this QWaylandPointer.
+ *
+ * This API doesn't actually make sense, since there may be many pointer resources per client
+ * It's here for compatibility reasons.
*/
struct wl_resource *QWaylandPointer::focusResource() const
{
Q_D(const QWaylandPointer);
- if (!d->focusResource)
- return Q_NULLPTR;
+ QWaylandView *focus = d->seat->mouseFocus();
+ if (!focus)
+ return nullptr;
- return d->focusResource;
+ // Just return the first resource we can find.
+ return d->resourceMap().value(focus->surface()->waylandClient())->handle;
}
/*!
@@ -324,6 +346,8 @@ struct wl_resource *QWaylandPointer::focusResource() const
*/
uint QWaylandPointer::sendButton(struct wl_resource *resource, uint32_t time, Qt::MouseButton button, uint32_t state)
{
+ // This method is here for compatibility reasons only, since it usually doesn't make sense to
+ // send button events to just one of the pointer resources for a client.
Q_D(QWaylandPointer);
uint32_t serial = d->compositor()->nextSerial();
d->send_button(resource, serial, time, toWaylandButton(button), state);
@@ -372,7 +396,6 @@ void QWaylandPointer::focusDestroyed(void *data)
d->focusDestroyListener.reset();
d->seat->setMouseFocus(Q_NULLPTR);
- d->focusResource = 0;
d->buttonCount = 0;
}
@@ -385,13 +408,12 @@ void QWaylandPointer::pointerFocusChanged(QWaylandView *newFocus, QWaylandView *
Q_D(QWaylandPointer);
d->localPosition = QPointF();
d->hasSentEnter = false;
- if (d->focusResource && oldFocus) {
+ if (oldFocus) {
uint32_t serial = d->compositor()->nextSerial();
- d->send_leave(d->focusResource, serial, oldFocus->surfaceResource());
+ for (auto resource : d->resourceMap().values(oldFocus->surfaceResource()->client))
+ d->send_leave(resource->handle, serial, oldFocus->surfaceResource());
d->focusDestroyListener.reset();
- d->focusResource = 0;
}
-
}
QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandpointer_p.h b/src/compositor/compositor_api/qwaylandpointer_p.h
index f9c24789..0a9ef232 100644
--- a/src/compositor/compositor_api/qwaylandpointer_p.h
+++ b/src/compositor/compositor_api/qwaylandpointer_p.h
@@ -84,17 +84,19 @@ public:
protected:
void pointer_set_cursor(Resource *resource, uint32_t serial, wl_resource *surface, int32_t hotspot_x, int32_t hotspot_y) override;
void pointer_release(Resource *resource) override;
- void pointer_destroy_resource(Resource *resource) override;
private:
+ const QList<Resource *> pointerResourcesForFocusedSurface() const;
+ uint sendButton(Qt::MouseButton button, uint32_t state);
+
QWaylandSeat *seat;
QWaylandOutput *output;
QPointF localPosition;
QPointF spacePosition;
- struct ::wl_resource *focusResource;
bool hasSentEnter;
+ uint enterSerial;
int buttonCount;