6#include <QtWaylandCompositor/QWaylandClient>
7#include <QtWaylandCompositor/QWaylandCompositor>
11QWaylandSurfaceRole QWaylandPointerPrivate::s_role(
"wl_pointer");
13QWaylandPointerPrivate::QWaylandPointerPrivate(QWaylandPointer *pointer, QWaylandSeat *seat)
19uint QWaylandPointerPrivate::sendButton(Qt::MouseButton button, uint32_t state)
22 if (!q->mouseFocus() || !q->mouseFocus()->surface())
25 wl_client *client = q->mouseFocus()->surface()->waylandClient();
26 uint32_t time = compositor()->currentTimeMsecs();
27 uint32_t serial = compositor()->nextSerial();
28 for (
auto resource : resourceMap().values(client))
29 send_button(resource->handle, serial, time, q->toWaylandButton(button), state);
33void QWaylandPointerPrivate::sendMotion()
35 Q_ASSERT(enteredSurface);
36 uint32_t time = compositor()->currentTimeMsecs();
37 wl_fixed_t x = wl_fixed_from_double(localPosition.x());
38 wl_fixed_t y = wl_fixed_from_double(localPosition.y());
39 for (
auto resource : resourceMap().values(enteredSurface->waylandClient()))
40 wl_pointer_send_motion(resource->handle, time, x, y);
43void QWaylandPointerPrivate::sendEnter(QWaylandSurface *surface)
45 Q_ASSERT(surface && !enteredSurface);
46 enterSerial = compositor()->nextSerial();
48 QWaylandKeyboard *keyboard = seat->keyboard();
50 keyboard->sendKeyModifiers(surface->client(), enterSerial);
52 wl_fixed_t x = wl_fixed_from_double(localPosition.x());
53 wl_fixed_t y = wl_fixed_from_double(localPosition.y());
54 for (
auto resource : resourceMap().values(surface->waylandClient()))
55 send_enter(resource->handle, enterSerial, surface->resource(), x, y);
57 enteredSurface = surface;
58 enteredSurfaceDestroyListener.listenForDestruction(surface->resource());
61void QWaylandPointerPrivate::sendLeave()
63 Q_ASSERT(enteredSurface);
64 uint32_t serial = compositor()->nextSerial();
65 for (
auto resource : resourceMap().values(enteredSurface->waylandClient()))
66 send_leave(resource->handle, serial, enteredSurface->resource());
67 localPosition = QPointF();
68 enteredSurfaceDestroyListener.reset();
69 enteredSurface =
nullptr;
72void QWaylandPointerPrivate::ensureEntered(QWaylandSurface *surface)
74 if (enteredSurface == surface)
84void QWaylandPointerPrivate::pointer_release(wl_pointer::Resource *resource)
86 wl_resource_destroy(resource->handle);
89void QWaylandPointerPrivate::pointer_set_cursor(wl_pointer::Resource *resource, uint32_t serial, wl_resource *surface, int32_t hotspot_x, int32_t hotspot_y)
94 seat->cursorSurfaceRequested(
nullptr, 0, 0, QWaylandClient::fromWlClient(compositor(), resource->client()));
98 QWaylandSurface *s = QWaylandSurface::fromResource(surface);
106 wl_resource *displayRes = wl_client_get_object(resource->client(), 1);
107 if (s->setRole(&QWaylandPointerPrivate::s_role, displayRes, WL_DISPLAY_ERROR_INVALID_OBJECT)) {
108 s->markAsCursorSurface(
true);
109 seat->cursorSurfaceRequested(s, hotspot_x, hotspot_y, QWaylandClient::fromWlClient(compositor(), resource->client()));
114
115
116
117
118
119
120
121
124
125
126QWaylandPointer::QWaylandPointer(QWaylandSeat *seat, QObject *parent)
127 : QWaylandObject(*
new QWaylandPointerPrivate(
this, seat), parent)
129 connect(&d_func()->enteredSurfaceDestroyListener, &QWaylandDestroyListener::fired,
this, &QWaylandPointer::enteredSurfaceDestroyed);
130 connect(seat, &QWaylandSeat::mouseFocusChanged,
this, &QWaylandPointer::pointerFocusChanged);
134
135
136QWaylandSeat *QWaylandPointer::seat()
const
138 Q_D(
const QWaylandPointer);
143
144
145QWaylandCompositor *QWaylandPointer::compositor()
const
147 Q_D(
const QWaylandPointer);
148 return d->compositor();
152
153
154QWaylandOutput *QWaylandPointer::output()
const
156 Q_D(
const QWaylandPointer);
161
162
163void QWaylandPointer::setOutput(QWaylandOutput *output)
165 Q_D(QWaylandPointer);
166 if (d->output == output)
return;
172
173
174
175
176uint QWaylandPointer::sendMousePressEvent(Qt::MouseButton button)
178 Q_D(QWaylandPointer);
181 if (d->buttonCount == 1)
182 emit buttonPressedChanged();
184 return d->sendButton(button, WL_POINTER_BUTTON_STATE_PRESSED);
188
189
190
191
192uint QWaylandPointer::sendMouseReleaseEvent(Qt::MouseButton button)
194 Q_D(QWaylandPointer);
197 if (d->buttonCount == 0)
198 emit buttonPressedChanged();
200 return d->sendButton(button, WL_POINTER_BUTTON_STATE_RELEASED);
204
205
206
207void QWaylandPointer::sendMouseMoveEvent(QWaylandView *view,
const QPointF &localPos,
const QPointF &outputSpacePos)
209 Q_D(QWaylandPointer);
210 if (view && (!view->surface() || view->surface()->isCursorSurface()))
212 d->seat->setMouseFocus(view);
213 d->localPosition = localPos;
214 d->spacePosition = outputSpacePos;
219 QSizeF size(view->surface()->destinationSize());
220 if (d->localPosition.x() == size.width())
221 d->localPosition.rx() -= 0.01;
222 if (d->localPosition.y() == size.height())
223 d->localPosition.ry() -= 0.01;
225 d->ensureEntered(view->surface());
229 setOutput(view->output());
234
235
236void QWaylandPointer::sendMouseWheelEvent(Qt::Orientation orientation,
int delta)
238 Q_D(QWaylandPointer);
239 if (!d->enteredSurface)
242 uint32_t time = d->compositor()->currentTimeMsecs();
243 uint32_t axis = orientation == Qt::Horizontal ? WL_POINTER_AXIS_HORIZONTAL_SCROLL
244 : WL_POINTER_AXIS_VERTICAL_SCROLL;
246 for (
auto resource : d->resourceMap().values(d->enteredSurface->waylandClient()))
247 d->send_axis(resource->handle, time, axis, wl_fixed_from_int(-delta / 12));
251
252
253QWaylandView *QWaylandPointer::mouseFocus()
const
255 Q_D(
const QWaylandPointer);
256 return d->seat->mouseFocus();
260
261
262QPointF QWaylandPointer::currentLocalPosition()
const
264 Q_D(
const QWaylandPointer);
265 return d->localPosition;
269
270
271QPointF QWaylandPointer::currentSpacePosition()
const
273 Q_D(
const QWaylandPointer);
274 return d->spacePosition;
278
279
280bool QWaylandPointer::isButtonPressed()
const
282 Q_D(
const QWaylandPointer);
283 return d->buttonCount > 0;
287
288
289void QWaylandPointer::addClient(QWaylandClient *client, uint32_t id, uint32_t version)
291 Q_D(QWaylandPointer);
292 wl_resource *resource = d->add(client->client(), id, qMin<uint32_t>(QtWaylandServer::wl_pointer::interfaceVersion(), version))->handle;
293 if (d->enteredSurface && client == d->enteredSurface->client()) {
294 d->send_enter(resource, d->enterSerial, d->enteredSurface->resource(),
295 wl_fixed_from_double(d->localPosition.x()),
296 wl_fixed_from_double(d->localPosition.y()));
301
302
303
304
305
306struct wl_resource *QWaylandPointer::focusResource()
const
308 Q_D(
const QWaylandPointer);
309 QWaylandView *focus = d->seat->mouseFocus();
314 return d->resourceMap().value(focus->surface()->waylandClient())->handle;
318
319
320uint QWaylandPointer::sendButton(
struct wl_resource *resource, uint32_t time, Qt::MouseButton button, uint32_t state)
324 Q_D(QWaylandPointer);
325 uint32_t serial = d->compositor()->nextSerial();
326 d->send_button(resource, serial, time, toWaylandButton(button), state);
331
332
333uint32_t QWaylandPointer::toWaylandButton(Qt::MouseButton button)
336 uint32_t BTN_LEFT = 0x110;
341 case Qt::LeftButton:
return BTN_LEFT;
342 case Qt::RightButton:
return uint32_t(0x111);
343 case Qt::MiddleButton:
return uint32_t(0x112);
344 case Qt::ExtraButton1:
return uint32_t(0x113);
345 case Qt::ExtraButton2:
return uint32_t(0x114);
346 case Qt::ExtraButton3:
return uint32_t(0x115);
347 case Qt::ExtraButton4:
return uint32_t(0x116);
348 case Qt::ExtraButton5:
return uint32_t(0x117);
349 case Qt::ExtraButton6:
return uint32_t(0x118);
350 case Qt::ExtraButton7:
return uint32_t(0x119);
351 case Qt::ExtraButton8:
return uint32_t(0x11a);
352 case Qt::ExtraButton9:
return uint32_t(0x11b);
353 case Qt::ExtraButton10:
return uint32_t(0x11c);
354 case Qt::ExtraButton11:
return uint32_t(0x11d);
355 case Qt::ExtraButton12:
return uint32_t(0x11e);
356 case Qt::ExtraButton13:
return uint32_t(0x11f);
358 default:
return uint32_t(0x11f);
363
364
365void QWaylandPointer::enteredSurfaceDestroyed(
void *data)
367 Q_D(QWaylandPointer);
369 d->enteredSurfaceDestroyListener.reset();
370 d->enteredSurface =
nullptr;
372 d->seat->setMouseFocus(
nullptr);
374 if (d->buttonCount != 0) {
376 emit buttonPressedChanged();
381
382
383void QWaylandPointer::pointerFocusChanged(QWaylandView *newFocus, QWaylandView *oldFocus)
385 Q_D(QWaylandPointer);
387 bool wasSameSurface = newFocus && newFocus->surface() == d->enteredSurface;
388 if (d->enteredSurface && !wasSameSurface)
394#include "moc_qwaylandpointer.cpp"