Changeset View
Changeset View
Standalone View
Standalone View
src/server/pointer_interface.cpp
Show All 15 Lines | |||||
16 | 16 | | |||
17 | You should have received a copy of the GNU Lesser General Public | 17 | You should have received a copy of the GNU Lesser General Public | ||
18 | License along with this library. If not, see <http://www.gnu.org/licenses/>. | 18 | License along with this library. If not, see <http://www.gnu.org/licenses/>. | ||
19 | *********************************************************************/ | 19 | *********************************************************************/ | ||
20 | #include "pointer_interface.h" | 20 | #include "pointer_interface.h" | ||
21 | #include "resource_p.h" | 21 | #include "resource_p.h" | ||
22 | #include "seat_interface.h" | 22 | #include "seat_interface.h" | ||
23 | #include "display.h" | 23 | #include "display.h" | ||
24 | #include "subcompositor_interface.h" | ||||
24 | #include "surface_interface.h" | 25 | #include "surface_interface.h" | ||
25 | // Wayland | 26 | // Wayland | ||
26 | #include <wayland-server.h> | 27 | #include <wayland-server.h> | ||
27 | 28 | | |||
28 | namespace KWayland | 29 | namespace KWayland | ||
29 | { | 30 | { | ||
30 | 31 | | |||
31 | namespace Server | 32 | namespace Server | ||
32 | { | 33 | { | ||
33 | 34 | | |||
34 | class PointerInterface::Private : public Resource::Private | 35 | class PointerInterface::Private : public Resource::Private | ||
35 | { | 36 | { | ||
36 | public: | 37 | public: | ||
37 | Private(SeatInterface *parent, wl_resource *parentResource, PointerInterface *q); | 38 | Private(SeatInterface *parent, wl_resource *parentResource, PointerInterface *q); | ||
38 | 39 | | |||
39 | SeatInterface *seat; | 40 | SeatInterface *seat; | ||
40 | SurfaceInterface *focusedSurface = nullptr; | 41 | SurfaceInterface *focusedSurface = nullptr; | ||
42 | QPointer<SurfaceInterface> focusedChildSurface; | ||||
41 | QMetaObject::Connection destroyConnection; | 43 | QMetaObject::Connection destroyConnection; | ||
42 | Cursor *cursor = nullptr; | 44 | Cursor *cursor = nullptr; | ||
43 | 45 | | |||
46 | void sendLeave(SurfaceInterface *surface, quint32 serial); | ||||
47 | void sendEnter(SurfaceInterface *surface, const QPointF &parentSurfacePosition, quint32 serial); | ||||
48 | | ||||
44 | private: | 49 | private: | ||
45 | PointerInterface *q_func() { | 50 | PointerInterface *q_func() { | ||
46 | return reinterpret_cast<PointerInterface *>(q); | 51 | return reinterpret_cast<PointerInterface *>(q); | ||
47 | } | 52 | } | ||
48 | void setCursor(quint32 serial, SurfaceInterface *surface, const QPoint &hotspot); | 53 | void setCursor(quint32 serial, SurfaceInterface *surface, const QPoint &hotspot); | ||
49 | // interface | 54 | // interface | ||
50 | static void setCursorCallback(wl_client *client, wl_resource *resource, uint32_t serial, | 55 | static void setCursorCallback(wl_client *client, wl_resource *resource, uint32_t serial, | ||
51 | wl_resource *surface, int32_t hotspot_x, int32_t hotspot_y); | 56 | wl_resource *surface, int32_t hotspot_x, int32_t hotspot_y); | ||
Show All 32 Lines | 86 | if (!cursor) { | |||
84 | cursor->d->update(QPointer<SurfaceInterface>(surface), serial, hotspot); | 89 | cursor->d->update(QPointer<SurfaceInterface>(surface), serial, hotspot); | ||
85 | QObject::connect(cursor, &Cursor::changed, q, &PointerInterface::cursorChanged); | 90 | QObject::connect(cursor, &Cursor::changed, q, &PointerInterface::cursorChanged); | ||
86 | emit q->cursorChanged(); | 91 | emit q->cursorChanged(); | ||
87 | } else { | 92 | } else { | ||
88 | cursor->d->update(QPointer<SurfaceInterface>(surface), serial, hotspot); | 93 | cursor->d->update(QPointer<SurfaceInterface>(surface), serial, hotspot); | ||
89 | } | 94 | } | ||
90 | } | 95 | } | ||
91 | 96 | | |||
97 | void PointerInterface::Private::sendLeave(SurfaceInterface *surface, quint32 serial) | ||||
98 | { | ||||
99 | if (!surface) { | ||||
100 | return; | ||||
101 | } | ||||
102 | if (resource && surface->resource()) { | ||||
103 | wl_pointer_send_leave(resource, serial, surface->resource()); | ||||
104 | } | ||||
105 | } | ||||
106 | | ||||
107 | namespace { | ||||
108 | static QPointF surfacePosition(SurfaceInterface *surface) { | ||||
109 | if (surface && surface->subSurface()) { | ||||
110 | return surface->subSurface()->position() + surfacePosition(surface->subSurface()->parentSurface().data()); | ||||
111 | } | ||||
112 | return QPointF(); | ||||
113 | } | ||||
114 | } | ||||
115 | | ||||
116 | void PointerInterface::Private::sendEnter(SurfaceInterface *surface, const QPointF &parentSurfacePosition, quint32 serial) | ||||
117 | { | ||||
118 | if (!surface) { | ||||
119 | return; | ||||
120 | } | ||||
121 | const QPointF adjustedPos = parentSurfacePosition - surfacePosition(surface); | ||||
122 | wl_pointer_send_enter(resource, serial, | ||||
123 | surface->resource(), | ||||
124 | wl_fixed_from_double(adjustedPos.x()), wl_fixed_from_double(adjustedPos.y())); | ||||
125 | } | ||||
126 | | ||||
92 | #ifndef DOXYGEN_SHOULD_SKIP_THIS | 127 | #ifndef DOXYGEN_SHOULD_SKIP_THIS | ||
93 | const struct wl_pointer_interface PointerInterface::Private::s_interface = { | 128 | const struct wl_pointer_interface PointerInterface::Private::s_interface = { | ||
94 | setCursorCallback, | 129 | setCursorCallback, | ||
95 | releaseCallback | 130 | releaseCallback | ||
96 | }; | 131 | }; | ||
97 | #endif | 132 | #endif | ||
98 | 133 | | |||
99 | PointerInterface::PointerInterface(SeatInterface *parent, wl_resource *parentResource) | 134 | PointerInterface::PointerInterface(SeatInterface *parent, wl_resource *parentResource) | ||
100 | : Resource(new Private(parent, parentResource, this), parent) | 135 | : Resource(new Private(parent, parentResource, this), parent) | ||
101 | { | 136 | { | ||
102 | // TODO: handle touch | 137 | // TODO: handle touch | ||
103 | connect(parent, &SeatInterface::pointerPosChanged, this, [this] { | 138 | connect(parent, &SeatInterface::pointerPosChanged, this, [this] { | ||
104 | Q_D(); | 139 | Q_D(); | ||
105 | if (d->seat->isDragPointer()) { | 140 | if (d->seat->isDragPointer()) { | ||
106 | // handled by DataDevice | 141 | // handled by DataDevice | ||
107 | return; | 142 | return; | ||
108 | } | 143 | } | ||
109 | if (d->focusedSurface && d->resource) { | 144 | if (d->focusedSurface && d->resource) { | ||
110 | const QPointF pos = d->seat->focusedPointerSurfaceTransformation().map(d->seat->pointerPos()); | 145 | const QPointF pos = d->seat->focusedPointerSurfaceTransformation().map(d->seat->pointerPos()); | ||
146 | auto targetSurface = d->focusedSurface->surfaceAt(pos); | ||||
147 | if (!targetSurface) { | ||||
148 | targetSurface = d->focusedSurface; | ||||
149 | } | ||||
150 | if (targetSurface != d->focusedChildSurface.data()) { | ||||
151 | const quint32 serial = d->seat->display()->nextSerial(); | ||||
152 | d->sendLeave(d->focusedChildSurface.data(), serial); | ||||
153 | d->focusedChildSurface = QPointer<SurfaceInterface>(targetSurface); | ||||
154 | d->sendEnter(targetSurface, pos, serial); | ||||
155 | d->client->flush(); | ||||
156 | } else { | ||||
157 | const QPointF adjustedPos = pos - surfacePosition(d->focusedChildSurface); | ||||
111 | wl_pointer_send_motion(d->resource, d->seat->timestamp(), | 158 | wl_pointer_send_motion(d->resource, d->seat->timestamp(), | ||
112 | wl_fixed_from_double(pos.x()), wl_fixed_from_double(pos.y())); | 159 | wl_fixed_from_double(adjustedPos.x()), wl_fixed_from_double(adjustedPos.y())); | ||
160 | } | ||||
113 | } | 161 | } | ||
114 | }); | 162 | }); | ||
115 | } | 163 | } | ||
116 | 164 | | |||
117 | PointerInterface::~PointerInterface() = default; | 165 | PointerInterface::~PointerInterface() = default; | ||
118 | 166 | | |||
119 | void PointerInterface::setFocusedSurface(SurfaceInterface *surface, quint32 serial) | 167 | void PointerInterface::setFocusedSurface(SurfaceInterface *surface, quint32 serial) | ||
120 | { | 168 | { | ||
121 | Q_D(); | 169 | Q_D(); | ||
122 | if (d->focusedSurface) { | 170 | d->sendLeave(d->focusedChildSurface.data(), serial); | ||
123 | if (d->resource && d->focusedSurface->resource()) { | | |||
124 | wl_pointer_send_leave(d->resource, serial, d->focusedSurface->resource()); | | |||
125 | } | | |||
126 | disconnect(d->destroyConnection); | 171 | disconnect(d->destroyConnection); | ||
127 | } | | |||
128 | if (!surface) { | 172 | if (!surface) { | ||
129 | d->focusedSurface = nullptr; | 173 | d->focusedSurface = nullptr; | ||
174 | d->focusedChildSurface.clear(); | ||||
130 | return; | 175 | return; | ||
131 | } | 176 | } | ||
132 | d->focusedSurface = surface; | 177 | d->focusedSurface = surface; | ||
133 | d->destroyConnection = connect(d->focusedSurface, &QObject::destroyed, this, | 178 | d->destroyConnection = connect(d->focusedSurface, &QObject::destroyed, this, | ||
134 | [this] { | 179 | [this] { | ||
135 | Q_D(); | 180 | Q_D(); | ||
136 | d->focusedSurface = nullptr; | 181 | d->focusedSurface = nullptr; | ||
182 | d->focusedChildSurface.clear(); | ||||
137 | } | 183 | } | ||
138 | ); | 184 | ); | ||
139 | 185 | | |||
140 | const QPointF pos = d->seat->focusedPointerSurfaceTransformation().map(d->seat->pointerPos()); | 186 | const QPointF pos = d->seat->focusedPointerSurfaceTransformation().map(d->seat->pointerPos()); | ||
141 | wl_pointer_send_enter(d->resource, serial, | 187 | d->focusedChildSurface = QPointer<SurfaceInterface>(d->focusedSurface->surfaceAt(pos)); | ||
142 | d->focusedSurface->resource(), | 188 | if (!d->focusedChildSurface) { | ||
143 | wl_fixed_from_double(pos.x()), wl_fixed_from_double(pos.y())); | 189 | d->focusedChildSurface = QPointer<SurfaceInterface>(d->focusedSurface); | ||
190 | } | ||||
191 | d->sendEnter(d->focusedChildSurface.data(), pos, serial); | ||||
144 | d->client->flush(); | 192 | d->client->flush(); | ||
145 | } | 193 | } | ||
146 | 194 | | |||
147 | void PointerInterface::buttonPressed(quint32 button, quint32 serial) | 195 | void PointerInterface::buttonPressed(quint32 button, quint32 serial) | ||
148 | { | 196 | { | ||
149 | Q_D(); | 197 | Q_D(); | ||
150 | Q_ASSERT(d->focusedSurface); | 198 | Q_ASSERT(d->focusedSurface); | ||
151 | if (!d->resource) { | 199 | if (!d->resource) { | ||
▲ Show 20 Lines • Show All 117 Lines • Show Last 20 Lines |