1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "qwldatadevice_p.h"
5
6#include "qwldatasource_p.h"
7#include "qwldataoffer_p.h"
8#include "qwaylandsurface_p.h"
9#include "qwldatadevicemanager_p.h"
10
11#if QT_CONFIG(draganddrop)
12#include "qwaylanddrag.h"
13#endif
14#include "qwaylandview.h"
15#include <QtWaylandCompositor/QWaylandClient>
16#include <QtWaylandCompositor/private/qwaylandcompositor_p.h>
17#include <QtWaylandCompositor/private/qwaylandseat_p.h>
18#include <QtWaylandCompositor/private/qwaylandpointer_p.h>
19
20#include <QtCore/QPointF>
21#include <QDebug>
22
23QT_BEGIN_NAMESPACE
24
25namespace QtWayland {
26
27DataDevice::DataDevice(QWaylandSeat *seat)
28 : m_compositor(seat->compositor())
29 , m_seat(seat)
30{
31}
32
33void DataDevice::setFocus(QWaylandClient *focusClient)
34{
35 if (!focusClient)
36 return;
37
38 Resource *resource = resourceMap().value(focusClient->client());
39
40 if (!resource)
41 return;
42
43 if (m_selectionSource) {
44 DataOffer *offer = new DataOffer(m_selectionSource, resource);
45 send_selection(resource->handle, offer->resource()->handle);
46 }
47}
48
49void DataDevice::sourceDestroyed(DataSource *source)
50{
51 if (m_selectionSource == source)
52 m_selectionSource = nullptr;
53
54 if (m_dragDataSource == source)
55 m_dragDataSource = nullptr;
56}
57
58#if QT_CONFIG(draganddrop)
59void DataDevice::setDragFocus(QWaylandSurface *focus, const QPointF &localPosition)
60{
61 if (m_dragFocusResource) {
62 send_leave(m_dragFocusResource->handle);
63 m_dragFocus = nullptr;
64 m_dragFocusResource = nullptr;
65 }
66
67 if (!focus)
68 return;
69
70 if (!m_dragDataSource && m_dragClient != focus->waylandClient())
71 return;
72
73 Resource *resource = resourceMap().value(focus->waylandClient());
74
75 if (!resource)
76 return;
77
78 uint32_t serial = m_compositor->nextSerial();
79
80 DataOffer *offer = m_dragDataSource ? new DataOffer(m_dragDataSource, resource) : nullptr;
81
82 if (m_dragDataSource && !offer)
83 return;
84
85 if (offer) {
86 send_enter(resource->handle, serial, focus->resource(),
87 wl_fixed_from_double(d: localPosition.x()), wl_fixed_from_double(d: localPosition.y()),
88 offer->resource()->handle);
89 }
90
91 m_dragFocus = focus;
92 m_dragFocusResource = resource;
93}
94
95QWaylandSurface *DataDevice::dragIcon() const
96{
97 return m_dragIcon;
98}
99
100QWaylandSurface *DataDevice::dragOrigin() const
101{
102 return m_dragOrigin;
103}
104
105void DataDevice::dragMove(QWaylandSurface *target, const QPointF &pos)
106{
107 if (target != m_dragFocus)
108 setDragFocus(focus: target, localPosition: pos);
109 if (!target || !m_dragFocusResource)
110 return;
111 uint time = m_compositor->currentTimeMsecs(); //### should be serial
112 send_motion(m_dragFocusResource->handle, time,
113 wl_fixed_from_double(pos.x()), wl_fixed_from_double(pos.y()));
114}
115
116void DataDevice::drop()
117{
118 if (m_dragFocusResource) {
119 send_drop(m_dragFocusResource->handle);
120 setDragFocus(focus: nullptr, localPosition: QPoint());
121 } else if (m_dragDataSource) {
122 m_dragDataSource->cancel();
123 }
124 m_dragOrigin = nullptr;
125 setDragIcon(nullptr);
126}
127
128void DataDevice::cancelDrag()
129{
130 setDragFocus(focus: nullptr, localPosition: QPoint());
131}
132
133void DataDevice::data_device_start_drag(Resource *resource, struct ::wl_resource *source, struct ::wl_resource *origin, struct ::wl_resource *icon, uint32_t serial)
134{
135 m_dragClient = resource->client();
136 m_dragDataSource = source ? DataSource::fromResource(resource: source) : nullptr;
137 if (m_dragDataSource)
138 m_dragDataSource->setDevice(this);
139 m_dragOrigin = QWaylandSurface::fromResource(resource: origin);
140 QWaylandDrag *drag = m_seat->drag();
141 setDragIcon(icon ? QWaylandSurface::fromResource(resource: icon) : nullptr);
142 Q_EMIT drag->dragStarted();
143 Q_EMIT m_dragOrigin->dragStarted(drag);
144
145 Q_UNUSED(serial);
146 //### need to verify that we have an implicit grab with this serial
147}
148
149void DataDevice::setDragIcon(QWaylandSurface *icon)
150{
151 if (icon == m_dragIcon)
152 return;
153 m_dragIcon = icon;
154 Q_EMIT m_seat->drag()->iconChanged();
155}
156#endif // QT_CONFIG(draganddrop)
157
158void DataDevice::data_device_set_selection(Resource *, struct ::wl_resource *source, uint32_t serial)
159{
160 Q_UNUSED(serial);
161
162 DataSource *dataSource = source ? DataSource::fromResource(resource: source) : nullptr;
163
164 if (m_selectionSource)
165 m_selectionSource->cancel();
166
167 m_selectionSource = dataSource;
168 QWaylandCompositorPrivate::get(compositor: m_compositor)->dataDeviceManager()->setCurrentSelectionSource(m_selectionSource);
169 if (m_selectionSource)
170 m_selectionSource->setDevice(this);
171
172 QWaylandClient *focusClient = m_seat->keyboard()->focusClient();
173 Resource *resource = focusClient ? resourceMap().value(focusClient->client()) : 0;
174
175 if (resource && m_selectionSource) {
176 DataOffer *offer = new DataOffer(m_selectionSource, resource);
177 send_selection(resource->handle, offer->resource()->handle);
178 } else if (resource) {
179 send_selection(resource->handle, nullptr);
180 }
181}
182
183
184}
185
186QT_END_NAMESPACE
187

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtwayland/src/compositor/wayland_wrapper/qwldatadevice.cpp