7#include <QtWaylandCompositor/QWaylandClient>
8#include <QtWaylandCompositor/QWaylandCompositor>
12QWaylandSurfaceRole QWaylandPointerPrivate::s_role(
"wl_pointer");
14QWaylandPointerPrivate::QWaylandPointerPrivate(QWaylandPointer *pointer, QWaylandSeat *seat)
20uint QWaylandPointerPrivate::sendButton(Qt::MouseButton button, uint32_t state)
23 if (!q->mouseFocus() || !q->mouseFocus()->surface())
26 wl_client *client = q->mouseFocus()->surface()->waylandClient();
27 uint32_t time = compositor()->currentTimeMsecs();
28 uint32_t serial = compositor()->nextSerial();
29 const auto resources = resourceMap().values(client);
30 for (
auto resource : resources)
31 send_button(resource->handle, serial, time, q->toWaylandButton(button), state);
35void QWaylandPointerPrivate::sendMotion()
37 Q_ASSERT(enteredSurface);
38 uint32_t time = compositor()->currentTimeMsecs();
39 wl_fixed_t x = wl_fixed_from_double(localPosition.x());
40 wl_fixed_t y = wl_fixed_from_double(localPosition.y());
41 const auto resources = resourceMap().values(enteredSurface->waylandClient());
42 for (
auto resource : resources)
43 wl_pointer_send_motion(resource->handle, time, x, y);
46void QWaylandPointerPrivate::sendEnter(QWaylandSurface *surface)
48 Q_ASSERT(surface && !enteredSurface);
49 enterSerial = compositor()->nextSerial();
51 QWaylandKeyboard *keyboard = seat->keyboard();
53 keyboard->sendKeyModifiers(surface->client(), enterSerial);
55 wl_fixed_t x = wl_fixed_from_double(localPosition.x());
56 wl_fixed_t y = wl_fixed_from_double(localPosition.y());
57 const auto resources = resourceMap().values(surface->waylandClient());
58 for (
auto resource : resources)
59 send_enter(resource->handle, enterSerial, surface->resource(), x, y);
61 enteredSurface = surface;
62 enteredSurfaceDestroyListener.listenForDestruction(surface->resource());
65void QWaylandPointerPrivate::sendLeave()
67 Q_ASSERT(enteredSurface);
68 uint32_t serial = compositor()->nextSerial();
69 const auto resources = resourceMap().values(enteredSurface->waylandClient());
70 for (
auto resource : resources)
71 send_leave(resource->handle, serial, enteredSurface->resource());
72 localPosition = QPointF();
73 enteredSurfaceDestroyListener.reset();
74 enteredSurface =
nullptr;
77void QWaylandPointerPrivate::ensureEntered(QWaylandSurface *surface)
79 if (enteredSurface == surface)
89void QWaylandPointerPrivate::pointer_release(wl_pointer::Resource *resource)
91 wl_resource_destroy(resource->handle);
94void QWaylandPointerPrivate::pointer_set_cursor(wl_pointer::Resource *resource, uint32_t serial, wl_resource *surface, int32_t hotspot_x, int32_t hotspot_y)
99 seat->cursorSurfaceRequested(
nullptr, 0, 0, QWaylandClient::fromWlClient(compositor(), resource->client()));
103 QWaylandSurface *s = QWaylandSurface::fromResource(surface);
111 wl_resource *displayRes = wl_client_get_object(resource->client(), 1);
112 if (s->setRole(&QWaylandPointerPrivate::s_role, displayRes, WL_DISPLAY_ERROR_INVALID_OBJECT)) {
113 s->markAsCursorSurface(
true);
114 seat->cursorSurfaceRequested(s, hotspot_x, hotspot_y, QWaylandClient::fromWlClient(compositor(), resource->client()));
119
120
121
122
123
124
125
126
129
130
131QWaylandPointer::QWaylandPointer(QWaylandSeat *seat, QObject *parent)
132 : QWaylandObject(*
new QWaylandPointerPrivate(
this, seat), parent)
134 connect(&d_func()->enteredSurfaceDestroyListener, &QWaylandDestroyListener::fired,
this, &QWaylandPointer::enteredSurfaceDestroyed);
135 connect(seat, &QWaylandSeat::mouseFocusChanged,
this, &QWaylandPointer::pointerFocusChanged);
139
140
141QWaylandSeat *QWaylandPointer::seat()
const
143 Q_D(
const QWaylandPointer);
148
149
150QWaylandCompositor *QWaylandPointer::compositor()
const
152 Q_D(
const QWaylandPointer);
153 return d->compositor();
157
158
159QWaylandOutput *QWaylandPointer::output()
const
161 Q_D(
const QWaylandPointer);
166
167
168void QWaylandPointer::setOutput(QWaylandOutput *output)
170 Q_D(QWaylandPointer);
171 if (d->output == output)
return;
177
178
179
180
181uint QWaylandPointer::sendMousePressEvent(Qt::MouseButton button)
183 Q_D(QWaylandPointer);
186 if (d->buttonCount == 1)
187 emit buttonPressedChanged();
189 return d->sendButton(button, WL_POINTER_BUTTON_STATE_PRESSED);
193
194
195
196
197uint QWaylandPointer::sendMouseReleaseEvent(Qt::MouseButton button)
199 Q_D(QWaylandPointer);
202 if (d->buttonCount == 0)
203 emit buttonPressedChanged();
205 return d->sendButton(button, WL_POINTER_BUTTON_STATE_RELEASED);
209
210
211
212void QWaylandPointer::sendMouseMoveEvent(QWaylandView *view,
const QPointF &localPos,
const QPointF &outputSpacePos)
214 Q_D(QWaylandPointer);
215 if (view && (!view->surface() || view->surface()->isCursorSurface()))
217 d->seat->setMouseFocus(view);
218 d->localPosition = localPos;
219 d->spacePosition = outputSpacePos;
224 QSizeF size(view->surface()->destinationSize());
225 if (d->localPosition.x() == size.width())
226 d->localPosition.rx() -= 0.01;
227 if (d->localPosition.y() == size.height())
228 d->localPosition.ry() -= 0.01;
230 d->ensureEntered(view->surface());
234 setOutput(view->output());
239
240
241void QWaylandPointer::sendMouseWheelEvent(Qt::Orientation orientation,
int delta)
243 Q_D(QWaylandPointer);
244 if (!d->enteredSurface)
247 uint32_t time = d->compositor()->currentTimeMsecs();
248 uint32_t axis = orientation == Qt::Horizontal ? WL_POINTER_AXIS_HORIZONTAL_SCROLL
249 : WL_POINTER_AXIS_VERTICAL_SCROLL;
251 const auto resources = d->resourceMap().values(d->enteredSurface->waylandClient());
252 for (
auto resource : resources)
253 d->send_axis(resource->handle, time, axis, wl_fixed_from_int(-delta / 12));
257
258
259QWaylandView *QWaylandPointer::mouseFocus()
const
261 Q_D(
const QWaylandPointer);
262 return d->seat->mouseFocus();
266
267
268QPointF QWaylandPointer::currentLocalPosition()
const
270 Q_D(
const QWaylandPointer);
271 return d->localPosition;
275
276
277QPointF QWaylandPointer::currentSpacePosition()
const
279 Q_D(
const QWaylandPointer);
280 return d->spacePosition;
284
285
286
287
288
289
290
293
294
295bool QWaylandPointer::isButtonPressed()
const
297 Q_D(
const QWaylandPointer);
298 return d->buttonCount > 0;
302
303
304void QWaylandPointer::addClient(QWaylandClient *client, uint32_t id, uint32_t version)
306 Q_D(QWaylandPointer);
307 wl_resource *resource = d->add(client->client(), id, qMin<uint32_t>(QtWaylandServer::wl_pointer::interfaceVersion(), version))->handle;
308 if (d->enteredSurface && client == d->enteredSurface->client()) {
309 d->send_enter(resource, d->enterSerial, d->enteredSurface->resource(),
310 wl_fixed_from_double(d->localPosition.x()),
311 wl_fixed_from_double(d->localPosition.y()));
316
317
318
319
320
321struct wl_resource *QWaylandPointer::focusResource()
const
323 Q_D(
const QWaylandPointer);
324 QWaylandView *focus = d->seat->mouseFocus();
329 return d->resourceMap().value(focus->surface()->waylandClient())->handle;
333
334
335uint QWaylandPointer::sendButton(
struct wl_resource *resource, uint32_t time, Qt::MouseButton button, uint32_t state)
339 Q_D(QWaylandPointer);
340 uint32_t serial = d->compositor()->nextSerial();
341 d->send_button(resource, serial, time, toWaylandButton(button), state);
346
347
348uint32_t QWaylandPointer::toWaylandButton(Qt::MouseButton button)
351 uint32_t BTN_LEFT = 0x110;
356 case Qt::LeftButton:
return BTN_LEFT;
357 case Qt::RightButton:
return uint32_t(0x111);
358 case Qt::MiddleButton:
return uint32_t(0x112);
359 case Qt::ExtraButton1:
return uint32_t(0x113);
360 case Qt::ExtraButton2:
return uint32_t(0x114);
361 case Qt::ExtraButton3:
return uint32_t(0x115);
362 case Qt::ExtraButton4:
return uint32_t(0x116);
363 case Qt::ExtraButton5:
return uint32_t(0x117);
364 case Qt::ExtraButton6:
return uint32_t(0x118);
365 case Qt::ExtraButton7:
return uint32_t(0x119);
366 case Qt::ExtraButton8:
return uint32_t(0x11a);
367 case Qt::ExtraButton9:
return uint32_t(0x11b);
368 case Qt::ExtraButton10:
return uint32_t(0x11c);
369 case Qt::ExtraButton11:
return uint32_t(0x11d);
370 case Qt::ExtraButton12:
return uint32_t(0x11e);
371 case Qt::ExtraButton13:
return uint32_t(0x11f);
373 default:
return uint32_t(0x11f);
378
379
380void QWaylandPointer::enteredSurfaceDestroyed(
void *data)
382 Q_D(QWaylandPointer);
384 d->enteredSurfaceDestroyListener.reset();
385 d->enteredSurface =
nullptr;
387 d->seat->setMouseFocus(
nullptr);
389 if (d->buttonCount != 0) {
391 emit buttonPressedChanged();
396
397
398void QWaylandPointer::pointerFocusChanged(QWaylandView *newFocus, QWaylandView *oldFocus)
400 Q_D(QWaylandPointer);
402 bool wasSameSurface = newFocus && newFocus->surface() == d->enteredSurface;
403 if (d->enteredSurface && !wasSameSurface)
409#include "moc_qwaylandpointer.cpp"
Combined button and popup list for selecting options.