Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qwaylandtabletv2.cpp
Go to the documentation of this file.
1
// Copyright (C) 2019 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4
#
include
"qwaylandtabletv2_p.h"
5
#
include
"qwaylandinputdevice_p.h"
6
#
include
"qwaylanddisplay_p.h"
7
#
include
"qwaylandsurface_p.h"
8
#
include
"qwaylandscreen_p.h"
9
#
include
"qwaylandbuffer_p.h"
10
#
include
"qwaylandcursorsurface_p.h"
11
#
include
"qwaylandcursor_p.h"
12
13
#
include
<
QtGui
/
private
/
qguiapplication_p
.
h
>
14
#
include
<
QtGui
/
private
/
qpointingdevice_p
.
h
>
15
#
include
<
QtGui
/
qpa
/
qplatformtheme
.
h
>
16
#
include
<
QtGui
/
qpa
/
qwindowsysteminterface_p
.
h
>
17
18
#
include
<
wayland
-
cursor
.
h
>
19
20
QT_BEGIN_NAMESPACE
21
22
namespace
QtWaylandClient
{
23
24
using
namespace
Qt
::
StringLiterals
;
25
26
#
if
QT_CONFIG
(
cursor
)
27
int
QWaylandTabletToolV2
::
idealCursorScale
()
const
28
{
29
if
(
m_tabletSeat
->
seat
()->
mQDisplay
->
compositor
()->
version
() < 3) {
30
return
1;
31
}
32
33
if
(
auto
*
s
=
mCursor
.
surface
.
data
()) {
34
if
(
s
->
outputScale
() > 0)
35
return
s
->
outputScale
();
36
}
37
38
return
m_tabletSeat
->
seat
()->
mCursor
.
fallbackOutputScale
;
39
}
40
41
void
QWaylandTabletToolV2
::
updateCursorTheme
()
42
{
43
QString
cursorThemeName
;
44
QSize
cursorSize
;
45
46
if
(
const
QPlatformTheme
*
platformTheme
=
QGuiApplicationPrivate
::
platformTheme
()) {
47
cursorThemeName
=
platformTheme
->
themeHint
(
QPlatformTheme
::
MouseCursorTheme
).
toString
();
48
cursorSize
=
platformTheme
->
themeHint
(
QPlatformTheme
::
MouseCursorSize
).
toSize
();
49
}
50
51
if
(
cursorThemeName
.
isEmpty
())
52
cursorThemeName
=
QStringLiteral
(
"default"
);
53
if
(
cursorSize
.
isEmpty
())
54
cursorSize
=
QSize
(24, 24);
55
56
int
scale
=
idealCursorScale
();
57
int
pixelSize
=
cursorSize
.
width
() *
scale
;
58
auto
*
display
=
m_tabletSeat
->
seat
()->
mQDisplay
;
59
mCursor
.
theme
=
display
->
loadCursorTheme
(
cursorThemeName
,
pixelSize
);
60
61
if
(!
mCursor
.
theme
)
62
return
;
// A warning has already been printed in loadCursorTheme
63
64
if
(
auto
*
arrow
=
mCursor
.
theme
->
cursor
(
Qt
::
ArrowCursor
)) {
65
int
arrowPixelSize
=
qMax
(
arrow
->
images
[0]->
width
,
66
arrow
->
images
[0]->
height
);
// Not all cursor themes are square
67
while
(
scale
> 1 &&
arrowPixelSize
/
scale
<
cursorSize
.
width
())
68
--
scale
;
69
}
else
{
70
qCWarning
(
lcQpaWayland
) <<
"Cursor theme does not support the arrow cursor"
;
71
}
72
mCursor
.
themeBufferScale
=
scale
;
73
}
74
75
void
QWaylandTabletToolV2
::
updateCursor
()
76
{
77
if
(
mEnterSerial
== 0)
78
return
;
79
80
auto
shape
=
m_tabletSeat
->
seat
()->
mCursor
.
shape
;
81
82
if
(
shape
==
Qt
::
BlankCursor
) {
83
if
(
mCursor
.
surface
)
84
mCursor
.
surface
->
reset
();
85
set_cursor
(
mEnterSerial
,
nullptr
, 0, 0);
86
return
;
87
}
88
89
if
(
shape
==
Qt
::
BitmapCursor
) {
90
auto
buffer
=
m_tabletSeat
->
seat
()->
mCursor
.
bitmapBuffer
;
91
if
(!
buffer
) {
92
qCWarning
(
lcQpaWayland
) <<
"No buffer for bitmap cursor, can't set cursor"
;
93
return
;
94
}
95
auto
hotspot
=
m_tabletSeat
->
seat
()->
mCursor
.
hotspot
;
96
int
bufferScale
=
m_tabletSeat
->
seat
()->
mCursor
.
bitmapScale
;
97
getOrCreateCursorSurface
()->
update
(
buffer
->
buffer
(),
hotspot
,
buffer
->
size
(),
bufferScale
);
98
return
;
99
}
100
101
if
(
mCursor
.
shape
) {
102
if
(
mCursor
.
surface
) {
103
mCursor
.
surface
->
reset
();
104
}
105
mCursor
.
shape
->
setShape
(
mEnterSerial
,
shape
);
106
return
;
107
}
108
109
if
(!
mCursor
.
theme
||
idealCursorScale
() !=
mCursor
.
themeBufferScale
)
110
updateCursorTheme
();
111
112
if
(!
mCursor
.
theme
)
113
return
;
114
115
// Set from shape using theme
116
uint
time
=
m_tabletSeat
->
seat
()->
mCursor
.
animationTimer
.
elapsed
();
117
118
if
(
struct
::
wl_cursor
*
waylandCursor
=
mCursor
.
theme
->
cursor
(
shape
)) {
119
uint
duration
= 0;
120
int
frame
=
wl_cursor_frame_and_duration
(
waylandCursor
,
time
, &
duration
);
121
::
wl_cursor_image
*
image
=
waylandCursor
->
images
[
frame
];
122
123
struct
wl_buffer
*
buffer
=
wl_cursor_image_get_buffer
(
image
);
124
if
(!
buffer
) {
125
qCWarning
(
lcQpaWayland
) <<
"Could not find buffer for cursor"
<<
shape
;
126
return
;
127
}
128
int
bufferScale
=
mCursor
.
themeBufferScale
;
129
QPoint
hotspot
=
QPoint
(
image
->
hotspot_x
,
image
->
hotspot_y
) /
bufferScale
;
130
QSize
size
=
QSize
(
image
->
width
,
image
->
height
) /
bufferScale
;
131
bool
animated
=
duration
> 0;
132
if
(
animated
) {
133
mCursor
.
gotFrameCallback
=
false
;
134
mCursor
.
gotTimerCallback
=
false
;
135
mCursor
.
frameTimer
.
start
(
duration
);
136
}
137
getOrCreateCursorSurface
()->
update
(
buffer
,
hotspot
,
size
,
bufferScale
,
animated
);
138
return
;
139
}
140
141
qCWarning
(
lcQpaWayland
) <<
"Unable to change to cursor"
<<
shape
;
142
}
143
144
CursorSurface
<
QWaylandTabletToolV2
> *
QWaylandTabletToolV2
::
getOrCreateCursorSurface
()
145
{
146
if
(!
mCursor
.
surface
)
147
mCursor
.
surface
.
reset
(
148
new
CursorSurface
<
QWaylandTabletToolV2
>(
this
,
m_tabletSeat
->
seat
()->
mQDisplay
));
149
return
mCursor
.
surface
.
get
();
150
}
151
152
void
QWaylandTabletToolV2
::
cursorTimerCallback
()
153
{
154
mCursor
.
gotTimerCallback
=
true
;
155
if
(
mCursor
.
gotFrameCallback
)
156
updateCursor
();
157
}
158
159
void
QWaylandTabletToolV2
::
cursorFrameCallback
()
160
{
161
mCursor
.
gotFrameCallback
=
true
;
162
if
(
mCursor
.
gotTimerCallback
)
163
updateCursor
();
164
}
165
166
#
endif
// QT_CONFIG(cursor)
167
168
QWaylandTabletManagerV2
::
QWaylandTabletManagerV2
(
QWaylandDisplay
*
display
,
uint
id
,
uint
version
)
169
:
zwp_tablet_manager_v2
(
display
->
wl_registry
(),
id
,
qMin
(
version
,
uint
(1)))
170
{
171
qCDebug
(
lcQpaInputDevices
,
"new tablet manager: ID %d version %d"
,
id
,
version
);
172
}
173
174
QWaylandTabletManagerV2
::~
QWaylandTabletManagerV2
()
175
{
176
destroy
();
177
}
178
179
QWaylandTabletSeatV2
::
QWaylandTabletSeatV2
(
QWaylandTabletManagerV2
*
manager
,
QWaylandInputDevice
*
seat
)
180
:
QtWayland
::
zwp_tablet_seat_v2
(
manager
->
get_tablet_seat
(
seat
->
wl_seat
()))
181
,
m_seat
(
seat
)
182
{
183
qCDebug
(
lcQpaInputDevices
) <<
"new tablet seat"
<<
seat
->
seatname
() <<
"id"
<<
seat
->
id
();
184
}
185
186
QWaylandTabletSeatV2
::~
QWaylandTabletSeatV2
()
187
{
188
qDeleteAll
(
m_tablets
);
189
qDeleteAll
(
m_tools
);
190
qDeleteAll
(
m_deadTools
);
191
qDeleteAll
(
m_pads
);
192
destroy
();
193
}
194
195
void
QWaylandTabletSeatV2
::
zwp_tablet_seat_v2_tablet_added
(
zwp_tablet_v2
*
id
)
196
{
197
auto
*
tablet
=
new
QWaylandTabletV2
(
id
,
m_seat
->
seatname
());
198
qCDebug
(
lcQpaInputDevices
) <<
"seat"
<<
this
<<
id
<<
"has tablet"
<<
tablet
;
199
tablet
->
setParent
(
this
);
200
m_tablets
.
push_back
(
tablet
);
201
connect
(
tablet
, &
QWaylandTabletV2
::
destroyed
,
this
, [
this
,
tablet
] {
m_tablets
.
removeOne
(
tablet
); });
202
}
203
204
void
QWaylandTabletSeatV2
::
zwp_tablet_seat_v2_tool_added
(
zwp_tablet_tool_v2
*
id
)
205
{
206
qDeleteAll
(
m_deadTools
);
207
auto
*
tool
=
new
QWaylandTabletToolV2
(
this
,
id
);
208
if
(
m_tablets
.
size
() == 1) {
209
tool
->
setParent
(
m_tablets
.
first
());
210
QPointingDevicePrivate
*
d
=
QPointingDevicePrivate
::
get
(
tool
);
211
d
->
name
=
m_tablets
.
first
()->
name
() + u" stylus";
212
}
else
{
213
qCDebug
(
lcQpaInputDevices
) <<
"seat"
<<
this
<<
"has tool"
<<
tool
<<
"for one of these tablets:"
<<
m_tablets
;
214
// TODO identify which tablet if there are several; then tool->setParent(tablet)
215
}
216
m_tools
.
push_back
(
tool
);
217
connect
(
tool
, &
QWaylandTabletToolV2
::
destroyed
,
this
, [
this
,
tool
] {
218
m_tools
.
removeOne
(
tool
);
219
m_deadTools
.
removeOne
(
tool
);
220
});
221
}
222
223
void
QWaylandTabletSeatV2
::
zwp_tablet_seat_v2_pad_added
(
zwp_tablet_pad_v2
*
id
)
224
{
225
auto
*
pad
=
new
QWaylandTabletPadV2
(
id
);
226
if
(
m_tablets
.
size
() == 1) {
227
pad
->
setParent
(
m_tablets
.
first
());
228
QPointingDevicePrivate
*
d
=
QPointingDevicePrivate
::
get
(
pad
);
229
d
->
name
=
m_tablets
.
first
()->
name
() + u" touchpad";
230
}
else
{
231
qCDebug
(
lcQpaInputDevices
) <<
"seat"
<<
this
<<
"has touchpad"
<<
pad
<<
"for one of these tablets:"
<<
m_tablets
;
232
// TODO identify which tablet if there are several
233
}
234
m_pads
.
push_back
(
pad
);
235
connect
(
pad
, &
QWaylandTabletPadV2
::
destroyed
,
this
, [
this
,
pad
] {
m_pads
.
removeOne
(
pad
); });
236
}
237
238
QWaylandTabletV2
::
QWaylandTabletV2
(::
zwp_tablet_v2
*
tablet
,
const
QString
&
seatName
)
239
:
QPointingDevice
(u"unknown"_s, -1,
DeviceType
::
Stylus
,
PointerType
::
Pen
,
240
Capability
::
Position
|
Capability
::
Hover
,
241
1, 1,
seatName
)
242
,
QtWayland
::
zwp_tablet_v2
(
tablet
)
243
{
244
qCDebug
(
lcQpaInputDevices
) <<
"new tablet on seat"
<<
seatName
;
245
QPointingDevicePrivate
*
d
=
QPointingDevicePrivate
::
get
(
this
);
246
d
->
seatName
=
seatName
;
247
}
248
249
QWaylandTabletV2
::~
QWaylandTabletV2
()
250
{
251
destroy
();
252
}
253
254
void
QWaylandTabletV2
::
zwp_tablet_v2_name
(
const
QString
&
name
)
255
{
256
QPointingDevicePrivate
*
d
=
QPointingDevicePrivate
::
get
(
this
);
257
d
->
name
=
name
;
258
}
259
260
void
QWaylandTabletV2
::
zwp_tablet_v2_id
(
uint32_t
vid
,
uint32_t
pid
)
261
{
262
QPointingDevicePrivate
*
d
=
QPointingDevicePrivate
::
get
(
this
);
263
d
->
systemId
= (
quint64
(
vid
) << 32) |
pid
;
264
qCDebug
(
lcQpaInputDevices
) <<
"vid"
<<
vid
<<
"pid"
<<
pid
<<
"stored as systemId in"
<<
this
;
265
}
266
267
void
QWaylandTabletV2
::
zwp_tablet_v2_path
(
const
QString
&
path
)
268
{
269
QPointingDevicePrivate
*
d
=
QPointingDevicePrivate
::
get
(
this
);
270
d
->
busId
=
path
;
271
}
272
273
void
QWaylandTabletV2
::
zwp_tablet_v2_done
()
274
{
275
QWindowSystemInterface
::
registerInputDevice
(
this
);
276
}
277
278
void
QWaylandTabletSeatV2
::
updateCursor
()
279
{
280
for
(
auto
tool
:
m_tools
)
281
tool
->
updateCursor
();
282
}
283
284
void
QWaylandTabletSeatV2
::
toolRemoved
(
QWaylandTabletToolV2
*
tool
)
285
{
286
m_tools
.
removeOne
(
tool
);
287
m_deadTools
.
append
(
tool
);
288
}
289
290
void
QWaylandTabletV2
::
zwp_tablet_v2_removed
()
291
{
292
deleteLater
();
293
}
294
295
QWaylandTabletToolV2
::
QWaylandTabletToolV2
(
QWaylandTabletSeatV2
*
tabletSeat
, ::
zwp_tablet_tool_v2
*
tool
)
296
:
QPointingDevice
(u"tool"_s, -1,
DeviceType
::
Stylus
,
PointerType
::
Pen
,
297
Capability
::
Position
|
Capability
::
Hover
,
298
1, 1,
tabletSeat
->
seat
()->
seatname
())
299
,
QtWayland
::
zwp_tablet_tool_v2
(
tool
)
300
,
m_tabletSeat
(
tabletSeat
)
301
{
302
// TODO get the number of buttons somehow?
303
304
#
if
QT_CONFIG
(
cursor
)
305
if
(
auto
cursorShapeManager
=
m_tabletSeat
->
seat
()->
mQDisplay
->
cursorShapeManager
()) {
306
mCursor
.
shape
.
reset
(
307
new
QWaylandCursorShape
(
cursorShapeManager
->
get_tablet_tool_v2
(
object
())));
308
}
309
310
mCursor
.
frameTimer
.
setSingleShot
(
true
);
311
mCursor
.
frameTimer
.
callOnTimeout
(
this
, [&]() {
cursorTimerCallback
(); });
312
#
endif
313
}
314
315
QWaylandTabletToolV2
::~
QWaylandTabletToolV2
()
316
{
317
destroy
();
318
}
319
320
void
QWaylandTabletToolV2
::
zwp_tablet_tool_v2_type
(
uint32_t
tool_type
)
321
{
322
QPointingDevicePrivate
*
d
=
QPointingDevicePrivate
::
get
(
this
);
323
324
switch
(
tool_type
) {
325
case
type_airbrush
:
326
case
type_brush
:
327
case
type_pencil
:
328
case
type_pen
:
329
d
->
pointerType
=
QPointingDevice
::
PointerType
::
Pen
;
330
break
;
331
case
type_eraser
:
332
d
->
pointerType
=
QPointingDevice
::
PointerType
::
Eraser
;
333
break
;
334
case
type_mouse
:
335
case
type_lens
:
336
d
->
pointerType
=
QPointingDevice
::
PointerType
::
Cursor
;
337
break
;
338
case
type_finger
:
339
d
->
pointerType
=
QPointingDevice
::
PointerType
::
Unknown
;
340
break
;
341
}
342
343
switch
(
tool_type
) {
344
case
type
::
type_airbrush
:
345
d
->
deviceType
=
QInputDevice
::
DeviceType
::
Airbrush
;
346
d
->
capabilities
.
setFlag
(
QInputDevice
::
Capability
::
TangentialPressure
);
347
break
;
348
case
type
::
type_brush
:
349
case
type
::
type_pencil
:
350
case
type
::
type_pen
:
351
case
type
::
type_eraser
:
352
d
->
deviceType
=
QInputDevice
::
DeviceType
::
Stylus
;
353
break
;
354
case
type
::
type_lens
:
355
d
->
deviceType
=
QInputDevice
::
DeviceType
::
Puck
;
356
break
;
357
case
type
::
type_mouse
:
358
case
type
::
type_finger
:
359
d
->
deviceType
=
QInputDevice
::
DeviceType
::
Unknown
;
360
break
;
361
}
362
}
363
364
void
QWaylandTabletToolV2
::
zwp_tablet_tool_v2_hardware_serial
(
uint32_t
hardware_serial_hi
,
uint32_t
hardware_serial_lo
)
365
{
366
QPointingDevicePrivate
*
d
=
QPointingDevicePrivate
::
get
(
this
);
367
d
->
uniqueId
=
QPointingDeviceUniqueId
::
fromNumericId
((
quint64
(
hardware_serial_hi
) << 32) +
hardware_serial_lo
);
368
}
369
370
void
QWaylandTabletToolV2
::
zwp_tablet_tool_v2_hardware_id_wacom
(
uint32_t
hardware_id_hi
,
uint32_t
hardware_id_lo
)
371
{
372
QPointingDevicePrivate
*
d
=
QPointingDevicePrivate
::
get
(
this
);
373
d
->
systemId
= (
quint64
(
hardware_id_hi
) << 32) +
hardware_id_lo
;
374
}
375
376
void
QWaylandTabletToolV2
::
zwp_tablet_tool_v2_capability
(
uint32_t
capability
)
377
{
378
QPointingDevicePrivate
*
d
=
QPointingDevicePrivate
::
get
(
this
);
379
switch
(
capability
) {
380
case
capability_tilt
:
381
// no distinction... we have to assume it has both axes
382
d
->
capabilities
.
setFlag
(
QInputDevice
::
Capability
::
XTilt
);
383
d
->
capabilities
.
setFlag
(
QInputDevice
::
Capability
::
YTilt
);
384
break
;
385
case
capability_pressure
:
386
d
->
capabilities
.
setFlag
(
QInputDevice
::
Capability
::
Pressure
);
387
break
;
388
case
capability_distance
:
389
d
->
capabilities
.
setFlag
(
QInputDevice
::
Capability
::
ZPosition
);
390
break
;
391
case
capability_rotation
:
392
d
->
capabilities
.
setFlag
(
QInputDevice
::
Capability
::
Rotation
);
393
break
;
394
case
capability_slider
:
395
// nothing to represent that so far
396
break
;
397
case
capability_wheel
:
398
d
->
capabilities
.
setFlag
(
QInputDevice
::
Capability
::
Scroll
);
399
d
->
capabilities
.
setFlag
(
QInputDevice
::
Capability
::
PixelScroll
);
400
break
;
401
}
402
qCDebug
(
lcQpaInputDevices
) <<
capability
<<
"->"
<<
this
;
403
}
404
405
void
QWaylandTabletToolV2
::
zwp_tablet_tool_v2_done
()
406
{
407
QWindowSystemInterface
::
registerInputDevice
(
this
);
408
}
409
410
void
QWaylandTabletToolV2
::
zwp_tablet_tool_v2_removed
()
411
{
412
m_tabletSeat
->
toolRemoved
(
this
);
413
}
414
415
void
QWaylandTabletToolV2
::
zwp_tablet_tool_v2_proximity_in
(
uint32_t
serial
,
zwp_tablet_v2
*
tablet
,
wl_surface
*
surface
)
416
{
417
Q_UNUSED
(
tablet
);
418
419
m_tabletSeat
->
seat
()->
mSerial
=
serial
;
420
mEnterSerial
=
serial
;
421
422
if
(
Q_UNLIKELY
(!
surface
)) {
423
qCDebug
(
lcQpaWayland
) <<
"Ignoring zwp_tablet_tool_v2_proximity_v2 with no surface"
;
424
return
;
425
}
426
m_pending
.
enteredSurface
=
true
;
427
m_pending
.
proximitySurface
=
QWaylandSurface
::
fromWlSurface
(
surface
);
428
429
#
if
QT_CONFIG
(
cursor
)
430
// Depends on mEnterSerial being updated
431
updateCursor
();
432
#
endif
433
}
434
435
void
QWaylandTabletToolV2
::
zwp_tablet_tool_v2_proximity_out
()
436
{
437
m_pending
.
enteredSurface
=
false
;
438
m_pending
.
proximitySurface
=
nullptr
;
439
}
440
441
void
QWaylandTabletToolV2
::
zwp_tablet_tool_v2_down
(
uint32_t
serial
)
442
{
443
m_pending
.
down
=
true
;
444
445
m_tabletSeat
->
seat
()->
mSerial
=
serial
;
446
447
if
(
m_pending
.
proximitySurface
) {
448
if
(
QWaylandWindow
*
window
=
m_pending
.
proximitySurface
->
waylandWindow
()) {
449
QWaylandInputDevice
*
seat
=
m_tabletSeat
->
seat
();
450
seat
->
display
()->
setLastInputDevice
(
seat
,
serial
,
window
);
451
}
452
}
453
}
454
455
void
QWaylandTabletToolV2
::
zwp_tablet_tool_v2_up
()
456
{
457
m_pending
.
down
=
false
;
458
}
459
460
void
QWaylandTabletToolV2
::
zwp_tablet_tool_v2_motion
(
wl_fixed_t
x
,
wl_fixed_t
y
)
461
{
462
m_pending
.
surfacePosition
=
QPointF
(
wl_fixed_to_double
(
x
),
wl_fixed_to_double
(
y
));
463
}
464
465
void
QWaylandTabletToolV2
::
zwp_tablet_tool_v2_pressure
(
uint32_t
pressure
)
466
{
467
const
int
maxPressure
= 65535;
468
m_pending
.
pressure
=
qreal
(
pressure
)/
maxPressure
;
469
}
470
471
void
QWaylandTabletToolV2
::
zwp_tablet_tool_v2_distance
(
uint32_t
distance
)
472
{
473
m_pending
.
distance
=
distance
;
474
}
475
476
void
QWaylandTabletToolV2
::
zwp_tablet_tool_v2_tilt
(
wl_fixed_t
tilt_x
,
wl_fixed_t
tilt_y
)
477
{
478
m_pending
.
xTilt
=
wl_fixed_to_double
(
tilt_x
);
479
m_pending
.
yTilt
=
wl_fixed_to_double
(
tilt_y
);
480
}
481
482
void
QWaylandTabletToolV2
::
zwp_tablet_tool_v2_rotation
(
wl_fixed_t
degrees
)
483
{
484
m_pending
.
rotation
=
wl_fixed_to_double
(
degrees
);
485
}
486
487
void
QWaylandTabletToolV2
::
zwp_tablet_tool_v2_slider
(
int32_t
position
)
488
{
489
m_pending
.
slider
=
qreal
(
position
) / 65535;
490
}
491
492
static
Qt
::
MouseButton
mouseButtonFromTablet
(uint button)
493
{
494
switch
(button) {
495
case
0x110:
return
Qt::MouseButton::LeftButton;
// BTN_LEFT
496
case
0x14b:
return
Qt::MouseButton::MiddleButton;
// BTN_STYLUS
497
case
0x14c:
return
Qt::MouseButton::RightButton;
// BTN_STYLUS2
498
default
:
499
return
Qt::NoButton;
500
}
501
}
502
503
void
QWaylandTabletToolV2
::
zwp_tablet_tool_v2_button
(
uint32_t
serial
,
uint32_t
button
,
uint32_t
state
)
504
{
505
m_tabletSeat
->
seat
()->
mSerial
=
serial
;
506
507
QPointingDevicePrivate
*
d
=
QPointingDevicePrivate
::
get
(
this
);
508
Qt
::
MouseButton
mouseButton
=
mouseButtonFromTablet
(
button
);
509
if
(
state
==
button_state_pressed
)
510
m_pending
.
buttons
|=
mouseButton
;
511
else
512
m_pending
.
buttons
&= ~
mouseButton
;
513
// ideally we'd get button count when the tool is discovered; seems to be a shortcoming in tablet-unstable-v2
514
// but if we get events from buttons we didn't know existed, increase it
515
if
(
mouseButton
==
Qt
::
RightButton
)
516
d
->
buttonCount
=
qMax
(
d
->
buttonCount
, 2);
517
else
if
(
mouseButton
==
Qt
::
MiddleButton
)
518
d
->
buttonCount
=
qMax
(
d
->
buttonCount
, 3);
519
}
520
521
void
QWaylandTabletToolV2
::
zwp_tablet_tool_v2_frame
(
uint32_t
time
)
522
{
523
if
(!
m_pending
.
proximitySurface
) {
524
if
(
m_applied
.
enteredSurface
) {
525
// leaving proximity
526
QWindowSystemInterface
::
handleTabletEnterLeaveProximityEvent
(
nullptr
,
this
,
false
);
527
m_pending
=
State
();
// Don't leave pressure etc. lying around when we enter the next surface
528
m_applied
=
State
();
529
}
else
{
530
qCWarning
(
lcQpaWayland
) <<
"Can't send tablet event with no proximity surface, ignoring"
;
531
}
532
return
;
533
}
534
535
QWaylandWindow
*
waylandWindow
=
QWaylandWindow
::
fromWlSurface
(
m_pending
.
proximitySurface
->
object
());
536
QWindow
*
window
=
waylandWindow
->
window
();
537
538
if
(!
m_applied
.
proximitySurface
) {
539
// TODO get position etc. as below
540
QWindowSystemInterface
::
handleTabletEnterLeaveProximityEvent
(
window
,
this
,
true
);
541
m_applied
.
proximitySurface
=
m_pending
.
proximitySurface
;
542
}
543
544
if
(!(
m_pending
==
m_applied
)) {
545
ulong
timestamp
=
time
;
546
const
QPointF
localPosition
=
waylandWindow
->
mapFromWlSurface
(
m_pending
.
surfacePosition
);
547
548
const
QPointF
globalPosition
=
waylandWindow
->
mapToGlobalF
(
localPosition
);
549
550
Qt
::
MouseButtons
buttons
=
m_pending
.
down
?
Qt
::
MouseButton
::
LeftButton
:
Qt
::
MouseButton
::
NoButton
;
551
buttons
|=
m_pending
.
buttons
;
552
qreal
pressure
=
m_pending
.
pressure
;
553
qreal
xTilt
=
m_pending
.
xTilt
;
554
qreal
yTilt
=
m_pending
.
yTilt
;
555
qreal
tangentialPressure
=
m_pending
.
slider
;
556
qreal
rotation
=
m_pending
.
rotation
;
557
int
z
=
int
(
m_pending
.
distance
);
558
559
// do not use localPosition here since that is in Qt window coordinates
560
// but we need surface coordinates to include the decoration
561
bool
decorationHandledEvent
=
waylandWindow
->
handleTabletEventDecoration
(
562
m_tabletSeat
->
seat
(),
m_pending
.
surfacePosition
,
563
window
->
mapToGlobal
(
m_pending
.
surfacePosition
),
buttons
,
564
m_tabletSeat
->
seat
()->
modifiers
());
565
566
if
(!
decorationHandledEvent
) {
567
QWindowSystemInterface
::
handleTabletEvent
(
window
,
timestamp
,
this
,
localPosition
,
globalPosition
,
568
buttons
,
pressure
,
569
xTilt
,
yTilt
,
tangentialPressure
,
rotation
,
z
,
570
m_tabletSeat
->
seat
()->
modifiers
());
571
}
572
}
573
574
m_applied
=
m_pending
;
575
}
576
577
// TODO: delete when upgrading to c++20
578
bool
QWaylandTabletToolV2
::
State
::
operator
==(
const
QWaylandTabletToolV2
::
State
&
o
)
const
{
579
return
580
down
==
o
.
down
&&
581
proximitySurface
.
data
() ==
o
.
proximitySurface
.
data
() &&
582
enteredSurface
==
o
.
enteredSurface
&&
583
surfacePosition
==
o
.
surfacePosition
&&
584
distance
==
o
.
distance
&&
585
pressure
==
o
.
pressure
&&
586
rotation
==
o
.
rotation
&&
587
xTilt
==
o
.
xTilt
&&
588
yTilt
==
o
.
yTilt
&&
589
slider
==
o
.
slider
&&
590
buttons
==
o
.
buttons
;
591
}
592
593
QWaylandTabletPadV2
::
QWaylandTabletPadV2
(::
zwp_tablet_pad_v2
*
pad
)
594
:
QPointingDevice
(u"tablet touchpad"_s, -1,
DeviceType
::
TouchPad
,
PointerType
::
Finger
,
595
Capability
::
Position
,
596
1, 1)
597
,
QtWayland
::
zwp_tablet_pad_v2
(
pad
)
598
{
599
}
600
601
QWaylandTabletPadV2
::~
QWaylandTabletPadV2
()
602
{
603
destroy
();
604
}
605
606
void
QWaylandTabletPadV2
::
zwp_tablet_pad_v2_path
(
const
QString
&
path
)
607
{
608
QPointingDevicePrivate
*
d
=
QPointingDevicePrivate
::
get
(
this
);
609
d
->
busId
=
path
;
610
}
611
612
void
QWaylandTabletPadV2
::
zwp_tablet_pad_v2_buttons
(
uint32_t
buttons
)
613
{
614
QPointingDevicePrivate
*
d
=
QPointingDevicePrivate
::
get
(
this
);
615
d
->
buttonCount
=
buttons
;
616
}
617
618
void
QWaylandTabletPadV2
::
zwp_tablet_pad_v2_group
(
zwp_tablet_pad_group_v2
*
pad_group
)
619
{
620
// As of writing Qt does not handle tablet pads group and the controls on it
621
// This proxy is server created so it is just deleted here to not leak it
622
zwp_tablet_pad_group_v2_destroy
(
pad_group
);
623
}
624
625
void
QWaylandTabletPadV2
::
zwp_tablet_pad_v2_done
()
626
{
627
QWindowSystemInterface
::
registerInputDevice
(
this
);
628
}
629
630
void
QWaylandTabletPadV2
::
zwp_tablet_pad_v2_removed
()
631
{
632
delete
this
;
633
}
634
635
}
// namespace QtWaylandClient
636
637
QT_END_NAMESPACE
638
639
#
include
"moc_qwaylandtabletv2_p.cpp"
QtWaylandClient
Definition
qwaylandclientextension.h:15
QtWaylandClient::mouseButtonFromTablet
static Qt::MouseButton mouseButtonFromTablet(uint button)
Definition
qwaylandtabletv2.cpp:492
qtwayland
src
client
qwaylandtabletv2.cpp
Generated on Mon Mar 10 2025 00:55:02 for Qt by
1.13.2