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