Client: Add support for high-resolution scrolling
With wl_pointer version 8, the axis_discrete event is replaced with the axis_value120 event. The main difference between axis_discrete and axis_value120 is that the latter carries scroll deltas that can be fractions of 120, e.g. 30, etc. See also https://gitlab.freedesktop.org/wayland/wayland/-/merge_requests/72 Change-Id: I4f724ead7ba146dde6d8975fa4edfcfca761769d Reviewed-by: David Edmundson <davidedmundson@kde.org> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
parent
425cceca83
commit
165b770fc5
224
src/3rdparty/wayland/protocols/wayland.xml
vendored
224
src/3rdparty/wayland/protocols/wayland.xml
vendored
@ -187,7 +187,7 @@
|
|||||||
</event>
|
</event>
|
||||||
</interface>
|
</interface>
|
||||||
|
|
||||||
<interface name="wl_compositor" version="4">
|
<interface name="wl_compositor" version="5">
|
||||||
<description summary="the compositor singleton">
|
<description summary="the compositor singleton">
|
||||||
A compositor. This object is a singleton global. The
|
A compositor. This object is a singleton global. The
|
||||||
compositor is in charge of combining the contents of multiple
|
compositor is in charge of combining the contents of multiple
|
||||||
@ -258,6 +258,12 @@
|
|||||||
for the pool from the file descriptor passed when the pool was
|
for the pool from the file descriptor passed when the pool was
|
||||||
created, but using the new size. This request can only be
|
created, but using the new size. This request can only be
|
||||||
used to make the pool bigger.
|
used to make the pool bigger.
|
||||||
|
|
||||||
|
This request only changes the amount of bytes that are mmapped
|
||||||
|
by the server and does not touch the file corresponding to the
|
||||||
|
file descriptor passed at creation time. It is the client's
|
||||||
|
responsibility to ensure that the file is at least as big as
|
||||||
|
the new pool size.
|
||||||
</description>
|
</description>
|
||||||
<arg name="size" type="int" summary="new size of the pool, in bytes"/>
|
<arg name="size" type="int" summary="new size of the pool, in bytes"/>
|
||||||
</request>
|
</request>
|
||||||
@ -271,8 +277,8 @@
|
|||||||
Clients can create wl_shm_pool objects using the create_pool
|
Clients can create wl_shm_pool objects using the create_pool
|
||||||
request.
|
request.
|
||||||
|
|
||||||
At connection setup time, the wl_shm object emits one or more
|
On binding the wl_shm object one or more format events
|
||||||
format events to inform clients about the valid pixel formats
|
are emitted to inform clients about the valid pixel formats
|
||||||
that can be used for buffers.
|
that can be used for buffers.
|
||||||
</description>
|
</description>
|
||||||
|
|
||||||
@ -296,6 +302,9 @@
|
|||||||
The drm format codes match the macros defined in drm_fourcc.h, except
|
The drm format codes match the macros defined in drm_fourcc.h, except
|
||||||
argb8888 and xrgb8888. The formats actually supported by the compositor
|
argb8888 and xrgb8888. The formats actually supported by the compositor
|
||||||
will be reported by the format event.
|
will be reported by the format event.
|
||||||
|
|
||||||
|
For all wl_shm formats and unless specified in another protocol
|
||||||
|
extension, pre-multiplied alpha is used for pixel values.
|
||||||
</description>
|
</description>
|
||||||
<!-- Note to protocol writers: don't update this list manually, instead
|
<!-- Note to protocol writers: don't update this list manually, instead
|
||||||
run the automated script that keeps it in sync with drm_fourcc.h. -->
|
run the automated script that keeps it in sync with drm_fourcc.h. -->
|
||||||
@ -403,6 +412,10 @@
|
|||||||
<entry name="nv15" value="0x3531564e" summary="2x2 subsampled Cr:Cb plane"/>
|
<entry name="nv15" value="0x3531564e" summary="2x2 subsampled Cr:Cb plane"/>
|
||||||
<entry name="q410" value="0x30313451"/>
|
<entry name="q410" value="0x30313451"/>
|
||||||
<entry name="q401" value="0x31303451"/>
|
<entry name="q401" value="0x31303451"/>
|
||||||
|
<entry name="xrgb16161616" value="0x38345258" summary="[63:0] x:R:G:B 16:16:16:16 little endian"/>
|
||||||
|
<entry name="xbgr16161616" value="0x38344258" summary="[63:0] x:B:G:R 16:16:16:16 little endian"/>
|
||||||
|
<entry name="argb16161616" value="0x38345241" summary="[63:0] A:R:G:B 16:16:16:16 little endian"/>
|
||||||
|
<entry name="abgr16161616" value="0x38344241" summary="[63:0] A:B:G:R 16:16:16:16 little endian"/>
|
||||||
</enum>
|
</enum>
|
||||||
|
|
||||||
<request name="create_pool">
|
<request name="create_pool">
|
||||||
@ -431,10 +444,15 @@
|
|||||||
<interface name="wl_buffer" version="1">
|
<interface name="wl_buffer" version="1">
|
||||||
<description summary="content for a wl_surface">
|
<description summary="content for a wl_surface">
|
||||||
A buffer provides the content for a wl_surface. Buffers are
|
A buffer provides the content for a wl_surface. Buffers are
|
||||||
created through factory interfaces such as wl_drm, wl_shm or
|
created through factory interfaces such as wl_shm, wp_linux_buffer_params
|
||||||
similar. It has a width and a height and can be attached to a
|
(from the linux-dmabuf protocol extension) or similar. It has a width and
|
||||||
wl_surface, but the mechanism by which a client provides and
|
a height and can be attached to a wl_surface, but the mechanism by which a
|
||||||
updates the contents is defined by the buffer factory interface.
|
client provides and updates the contents is defined by the buffer factory
|
||||||
|
interface.
|
||||||
|
|
||||||
|
If the buffer uses a format that has an alpha channel, the alpha channel
|
||||||
|
is assumed to be premultiplied in the color channels unless otherwise
|
||||||
|
specified.
|
||||||
</description>
|
</description>
|
||||||
|
|
||||||
<request name="destroy" type="destructor">
|
<request name="destroy" type="destructor">
|
||||||
@ -878,7 +896,7 @@
|
|||||||
which will subsequently be used in either the
|
which will subsequently be used in either the
|
||||||
data_device.enter event (for drag-and-drop) or the
|
data_device.enter event (for drag-and-drop) or the
|
||||||
data_device.selection event (for selections). Immediately
|
data_device.selection event (for selections). Immediately
|
||||||
following the data_device_data_offer event, the new data_offer
|
following the data_device.data_offer event, the new data_offer
|
||||||
object will send out data_offer.offer events to describe the
|
object will send out data_offer.offer events to describe the
|
||||||
mime types it offers.
|
mime types it offers.
|
||||||
</description>
|
</description>
|
||||||
@ -948,9 +966,10 @@
|
|||||||
immediately before receiving keyboard focus and when a new
|
immediately before receiving keyboard focus and when a new
|
||||||
selection is set while the client has keyboard focus. The
|
selection is set while the client has keyboard focus. The
|
||||||
data_offer is valid until a new data_offer or NULL is received
|
data_offer is valid until a new data_offer or NULL is received
|
||||||
or until the client loses keyboard focus. The client must
|
or until the client loses keyboard focus. Switching surface with
|
||||||
destroy the previous selection data_offer, if any, upon receiving
|
keyboard focus within the same client doesn't mean a new selection
|
||||||
this event.
|
will be sent. The client must destroy the previous selection
|
||||||
|
data_offer, if any, upon receiving this event.
|
||||||
</description>
|
</description>
|
||||||
<arg name="id" type="object" interface="wl_data_offer" allow-null="true"
|
<arg name="id" type="object" interface="wl_data_offer" allow-null="true"
|
||||||
summary="selection data_offer object"/>
|
summary="selection data_offer object"/>
|
||||||
@ -1038,7 +1057,8 @@
|
|||||||
a basic surface.
|
a basic surface.
|
||||||
|
|
||||||
Note! This protocol is deprecated and not intended for production use.
|
Note! This protocol is deprecated and not intended for production use.
|
||||||
For desktop-style user interfaces, use xdg_shell.
|
For desktop-style user interfaces, use xdg_shell. Compositors and clients
|
||||||
|
should not implement this interface.
|
||||||
</description>
|
</description>
|
||||||
|
|
||||||
<enum name="error">
|
<enum name="error">
|
||||||
@ -1332,7 +1352,7 @@
|
|||||||
</event>
|
</event>
|
||||||
</interface>
|
</interface>
|
||||||
|
|
||||||
<interface name="wl_surface" version="4">
|
<interface name="wl_surface" version="5">
|
||||||
<description summary="an onscreen surface">
|
<description summary="an onscreen surface">
|
||||||
A surface is a rectangular area that may be displayed on zero
|
A surface is a rectangular area that may be displayed on zero
|
||||||
or more outputs, and shown any number of times at the compositor's
|
or more outputs, and shown any number of times at the compositor's
|
||||||
@ -1384,6 +1404,7 @@
|
|||||||
<entry name="invalid_scale" value="0" summary="buffer scale value is invalid"/>
|
<entry name="invalid_scale" value="0" summary="buffer scale value is invalid"/>
|
||||||
<entry name="invalid_transform" value="1" summary="buffer transform value is invalid"/>
|
<entry name="invalid_transform" value="1" summary="buffer transform value is invalid"/>
|
||||||
<entry name="invalid_size" value="2" summary="buffer size is invalid"/>
|
<entry name="invalid_size" value="2" summary="buffer size is invalid"/>
|
||||||
|
<entry name="invalid_offset" value="3" summary="buffer offset is invalid"/>
|
||||||
</enum>
|
</enum>
|
||||||
|
|
||||||
<request name="destroy" type="destructor">
|
<request name="destroy" type="destructor">
|
||||||
@ -1406,7 +1427,14 @@
|
|||||||
buffer's upper left corner, relative to the current buffer's upper
|
buffer's upper left corner, relative to the current buffer's upper
|
||||||
left corner, in surface-local coordinates. In other words, the
|
left corner, in surface-local coordinates. In other words, the
|
||||||
x and y, combined with the new surface size define in which
|
x and y, combined with the new surface size define in which
|
||||||
directions the surface's size changes.
|
directions the surface's size changes. Setting anything other than 0
|
||||||
|
as x and y arguments is discouraged, and should instead be replaced
|
||||||
|
with using the separate wl_surface.offset request.
|
||||||
|
|
||||||
|
When the bound wl_surface version is 5 or higher, passing any
|
||||||
|
non-zero x or y is a protocol violation, and will result in an
|
||||||
|
'invalid_offset' error being raised. To achieve equivalent semantics,
|
||||||
|
use wl_surface.offset.
|
||||||
|
|
||||||
Surface contents are double-buffered state, see wl_surface.commit.
|
Surface contents are double-buffered state, see wl_surface.commit.
|
||||||
|
|
||||||
@ -1434,9 +1462,12 @@
|
|||||||
from the same backing storage or use wp_linux_buffer_release.
|
from the same backing storage or use wp_linux_buffer_release.
|
||||||
|
|
||||||
Destroying the wl_buffer after wl_buffer.release does not change
|
Destroying the wl_buffer after wl_buffer.release does not change
|
||||||
the surface contents. However, if the client destroys the
|
the surface contents. Destroying the wl_buffer before wl_buffer.release
|
||||||
wl_buffer before receiving the wl_buffer.release event, the surface
|
is allowed as long as the underlying buffer storage isn't re-used (this
|
||||||
contents become undefined immediately.
|
can happen e.g. on client process termination). However, if the client
|
||||||
|
destroys the wl_buffer before receiving the wl_buffer.release event and
|
||||||
|
mutates the underlying buffer storage, the surface contents become
|
||||||
|
undefined immediately.
|
||||||
|
|
||||||
If wl_surface.attach is sent with a NULL wl_buffer, the
|
If wl_surface.attach is sent with a NULL wl_buffer, the
|
||||||
following wl_surface.commit will remove the surface content.
|
following wl_surface.commit will remove the surface content.
|
||||||
@ -1734,9 +1765,30 @@
|
|||||||
<arg name="width" type="int" summary="width of damage rectangle"/>
|
<arg name="width" type="int" summary="width of damage rectangle"/>
|
||||||
<arg name="height" type="int" summary="height of damage rectangle"/>
|
<arg name="height" type="int" summary="height of damage rectangle"/>
|
||||||
</request>
|
</request>
|
||||||
|
|
||||||
|
<!-- Version 5 additions -->
|
||||||
|
|
||||||
|
<request name="offset" since="5">
|
||||||
|
<description summary="set the surface contents offset">
|
||||||
|
The x and y arguments specify the location of the new pending
|
||||||
|
buffer's upper left corner, relative to the current buffer's upper
|
||||||
|
left corner, in surface-local coordinates. In other words, the
|
||||||
|
x and y, combined with the new surface size define in which
|
||||||
|
directions the surface's size changes.
|
||||||
|
|
||||||
|
Surface location offset is double-buffered state, see
|
||||||
|
wl_surface.commit.
|
||||||
|
|
||||||
|
This request is semantically equivalent to and the replaces the x and y
|
||||||
|
arguments in the wl_surface.attach request in wl_surface versions prior
|
||||||
|
to 5. See wl_surface.attach for details.
|
||||||
|
</description>
|
||||||
|
<arg name="x" type="int" summary="surface-local x coordinate"/>
|
||||||
|
<arg name="y" type="int" summary="surface-local y coordinate"/>
|
||||||
|
</request>
|
||||||
</interface>
|
</interface>
|
||||||
|
|
||||||
<interface name="wl_seat" version="7">
|
<interface name="wl_seat" version="8">
|
||||||
<description summary="group of input devices">
|
<description summary="group of input devices">
|
||||||
A seat is a group of keyboards, pointer and touch devices. This
|
A seat is a group of keyboards, pointer and touch devices. This
|
||||||
object is published as a global during start up, or when such a
|
object is published as a global during start up, or when such a
|
||||||
@ -1838,9 +1890,22 @@
|
|||||||
|
|
||||||
<event name="name" since="2">
|
<event name="name" since="2">
|
||||||
<description summary="unique identifier for this seat">
|
<description summary="unique identifier for this seat">
|
||||||
In a multiseat configuration this can be used by the client to help
|
In a multi-seat configuration the seat name can be used by clients to
|
||||||
identify which physical devices the seat represents. Based on
|
help identify which physical devices the seat represents.
|
||||||
the seat configuration used by the compositor.
|
|
||||||
|
The seat name is a UTF-8 string with no convention defined for its
|
||||||
|
contents. Each name is unique among all wl_seat globals. The name is
|
||||||
|
only guaranteed to be unique for the current compositor instance.
|
||||||
|
|
||||||
|
The same seat names are used for all clients. Thus, the name can be
|
||||||
|
shared across processes to refer to a specific wl_seat global.
|
||||||
|
|
||||||
|
The name event is sent after binding to the seat global. This event is
|
||||||
|
only sent once per seat object, and the name does not change over the
|
||||||
|
lifetime of the wl_seat global.
|
||||||
|
|
||||||
|
Compositors may re-use the same seat name if the wl_seat global is
|
||||||
|
destroyed and re-created later.
|
||||||
</description>
|
</description>
|
||||||
<arg name="name" type="string" summary="seat identifier"/>
|
<arg name="name" type="string" summary="seat identifier"/>
|
||||||
</event>
|
</event>
|
||||||
@ -1856,7 +1921,7 @@
|
|||||||
|
|
||||||
</interface>
|
</interface>
|
||||||
|
|
||||||
<interface name="wl_pointer" version="7">
|
<interface name="wl_pointer" version="8">
|
||||||
<description summary="pointer input device">
|
<description summary="pointer input device">
|
||||||
The wl_pointer interface represents one or more input devices,
|
The wl_pointer interface represents one or more input devices,
|
||||||
such as mice, which control the pointer location and pointer_focus
|
such as mice, which control the pointer location and pointer_focus
|
||||||
@ -1905,6 +1970,10 @@
|
|||||||
wl_surface is no longer used as the cursor. When the use as a
|
wl_surface is no longer used as the cursor. When the use as a
|
||||||
cursor ends, the current and pending input regions become
|
cursor ends, the current and pending input regions become
|
||||||
undefined, and the wl_surface is unmapped.
|
undefined, and the wl_surface is unmapped.
|
||||||
|
|
||||||
|
The serial parameter must match the latest wl_pointer.enter
|
||||||
|
serial number sent to the client. Otherwise the request will be
|
||||||
|
ignored.
|
||||||
</description>
|
</description>
|
||||||
<arg name="serial" type="uint" summary="serial number of the enter event"/>
|
<arg name="serial" type="uint" summary="serial number of the enter event"/>
|
||||||
<arg name="surface" type="object" interface="wl_surface" allow-null="true"
|
<arg name="surface" type="object" interface="wl_surface" allow-null="true"
|
||||||
@ -2152,6 +2221,9 @@
|
|||||||
This event carries the axis value of the wl_pointer.axis event in
|
This event carries the axis value of the wl_pointer.axis event in
|
||||||
discrete steps (e.g. mouse wheel clicks).
|
discrete steps (e.g. mouse wheel clicks).
|
||||||
|
|
||||||
|
This event is deprecated with wl_pointer version 8 - this event is not
|
||||||
|
sent to clients supporting version 8 or later.
|
||||||
|
|
||||||
This event does not occur on its own, it is coupled with a
|
This event does not occur on its own, it is coupled with a
|
||||||
wl_pointer.axis event that represents this axis value on a
|
wl_pointer.axis event that represents this axis value on a
|
||||||
continuous scale. The protocol guarantees that each axis_discrete
|
continuous scale. The protocol guarantees that each axis_discrete
|
||||||
@ -2159,7 +2231,8 @@
|
|||||||
axis number within the same wl_pointer.frame. Note that the protocol
|
axis number within the same wl_pointer.frame. Note that the protocol
|
||||||
allows for other events to occur between the axis_discrete and
|
allows for other events to occur between the axis_discrete and
|
||||||
its coupled axis event, including other axis_discrete or axis
|
its coupled axis event, including other axis_discrete or axis
|
||||||
events.
|
events. A wl_pointer.frame must not contain more than one axis_discrete
|
||||||
|
event per axis type.
|
||||||
|
|
||||||
This event is optional; continuous scrolling devices
|
This event is optional; continuous scrolling devices
|
||||||
like two-finger scrolling on touchpads do not have discrete
|
like two-finger scrolling on touchpads do not have discrete
|
||||||
@ -2177,9 +2250,37 @@
|
|||||||
<arg name="axis" type="uint" enum="axis" summary="axis type"/>
|
<arg name="axis" type="uint" enum="axis" summary="axis type"/>
|
||||||
<arg name="discrete" type="int" summary="number of steps"/>
|
<arg name="discrete" type="int" summary="number of steps"/>
|
||||||
</event>
|
</event>
|
||||||
|
|
||||||
|
<event name="axis_value120" since="8">
|
||||||
|
<description summary="axis high-resolution scroll event">
|
||||||
|
Discrete high-resolution scroll information.
|
||||||
|
|
||||||
|
This event carries high-resolution wheel scroll information,
|
||||||
|
with each multiple of 120 representing one logical scroll step
|
||||||
|
(a wheel detent). For example, an axis_value120 of 30 is one quarter of
|
||||||
|
a logical scroll step in the positive direction, a value120 of
|
||||||
|
-240 are two logical scroll steps in the negative direction within the
|
||||||
|
same hardware event.
|
||||||
|
Clients that rely on discrete scrolling should accumulate the
|
||||||
|
value120 to multiples of 120 before processing the event.
|
||||||
|
|
||||||
|
The value120 must not be zero.
|
||||||
|
|
||||||
|
This event replaces the wl_pointer.axis_discrete event in clients
|
||||||
|
supporting wl_pointer version 8 or later.
|
||||||
|
|
||||||
|
Where a wl_pointer.axis_source event occurs in the same
|
||||||
|
wl_pointer.frame, the axis source applies to this event.
|
||||||
|
|
||||||
|
The order of wl_pointer.axis_value120 and wl_pointer.axis_source is
|
||||||
|
not guaranteed.
|
||||||
|
</description>
|
||||||
|
<arg name="axis" type="uint" enum="axis" summary="axis type"/>
|
||||||
|
<arg name="value120" type="int" summary="scroll distance as fraction of 120"/>
|
||||||
|
</event>
|
||||||
</interface>
|
</interface>
|
||||||
|
|
||||||
<interface name="wl_keyboard" version="7">
|
<interface name="wl_keyboard" version="8">
|
||||||
<description summary="keyboard input device">
|
<description summary="keyboard input device">
|
||||||
The wl_keyboard interface represents one or more keyboards
|
The wl_keyboard interface represents one or more keyboards
|
||||||
associated with a seat.
|
associated with a seat.
|
||||||
@ -2193,13 +2294,14 @@
|
|||||||
<entry name="no_keymap" value="0"
|
<entry name="no_keymap" value="0"
|
||||||
summary="no keymap; client must understand how to interpret the raw keycode"/>
|
summary="no keymap; client must understand how to interpret the raw keycode"/>
|
||||||
<entry name="xkb_v1" value="1"
|
<entry name="xkb_v1" value="1"
|
||||||
summary="libxkbcommon compatible; to determine the xkb keycode, clients must add 8 to the key event keycode"/>
|
summary="libxkbcommon compatible, null-terminated string; to determine the xkb keycode, clients must add 8 to the key event keycode"/>
|
||||||
</enum>
|
</enum>
|
||||||
|
|
||||||
<event name="keymap">
|
<event name="keymap">
|
||||||
<description summary="keyboard mapping">
|
<description summary="keyboard mapping">
|
||||||
This event provides a file descriptor to the client which can be
|
This event provides a file descriptor to the client which can be
|
||||||
memory-mapped to provide a keyboard mapping description.
|
memory-mapped in read-only mode to provide a keyboard mapping
|
||||||
|
description.
|
||||||
|
|
||||||
From version 7 onwards, the fd must be mapped with MAP_PRIVATE by
|
From version 7 onwards, the fd must be mapped with MAP_PRIVATE by
|
||||||
the recipient, as MAP_SHARED may fail.
|
the recipient, as MAP_SHARED may fail.
|
||||||
@ -2305,7 +2407,7 @@
|
|||||||
</event>
|
</event>
|
||||||
</interface>
|
</interface>
|
||||||
|
|
||||||
<interface name="wl_touch" version="7">
|
<interface name="wl_touch" version="8">
|
||||||
<description summary="touchscreen input device">
|
<description summary="touchscreen input device">
|
||||||
The wl_touch interface represents a touchscreen
|
The wl_touch interface represents a touchscreen
|
||||||
associated with a seat.
|
associated with a seat.
|
||||||
@ -2449,7 +2551,7 @@
|
|||||||
</event>
|
</event>
|
||||||
</interface>
|
</interface>
|
||||||
|
|
||||||
<interface name="wl_output" version="3">
|
<interface name="wl_output" version="4">
|
||||||
<description summary="compositor output region">
|
<description summary="compositor output region">
|
||||||
An output describes part of the compositor geometry. The
|
An output describes part of the compositor geometry. The
|
||||||
compositor works in the 'compositor coordinate system' and an
|
compositor works in the 'compositor coordinate system' and an
|
||||||
@ -2505,12 +2607,15 @@
|
|||||||
The physical size can be set to zero if it doesn't make sense for this
|
The physical size can be set to zero if it doesn't make sense for this
|
||||||
output (e.g. for projectors or virtual outputs).
|
output (e.g. for projectors or virtual outputs).
|
||||||
|
|
||||||
|
The geometry event will be followed by a done event (starting from
|
||||||
|
version 2).
|
||||||
|
|
||||||
Note: wl_output only advertises partial information about the output
|
Note: wl_output only advertises partial information about the output
|
||||||
position and identification. Some compositors, for instance those not
|
position and identification. Some compositors, for instance those not
|
||||||
implementing a desktop-style output layout or those exposing virtual
|
implementing a desktop-style output layout or those exposing virtual
|
||||||
outputs, might fake this information. Instead of using x and y, clients
|
outputs, might fake this information. Instead of using x and y, clients
|
||||||
should use xdg_output.logical_position. Instead of using make and model,
|
should use xdg_output.logical_position. Instead of using make and model,
|
||||||
clients should use xdg_output.name and xdg_output.description.
|
clients should use name and description.
|
||||||
</description>
|
</description>
|
||||||
<arg name="x" type="int"
|
<arg name="x" type="int"
|
||||||
summary="x position within the global compositor space"/>
|
summary="x position within the global compositor space"/>
|
||||||
@ -2566,6 +2671,9 @@
|
|||||||
The vertical refresh rate can be set to zero if it doesn't make
|
The vertical refresh rate can be set to zero if it doesn't make
|
||||||
sense for this output (e.g. for virtual outputs).
|
sense for this output (e.g. for virtual outputs).
|
||||||
|
|
||||||
|
The mode event will be followed by a done event (starting from
|
||||||
|
version 2).
|
||||||
|
|
||||||
Clients should not use the refresh rate to schedule frames. Instead,
|
Clients should not use the refresh rate to schedule frames. Instead,
|
||||||
they should use the wl_surface.frame event or the presentation-time
|
they should use the wl_surface.frame event or the presentation-time
|
||||||
protocol.
|
protocol.
|
||||||
@ -2612,6 +2720,8 @@
|
|||||||
the scale of the output. That way the compositor can
|
the scale of the output. That way the compositor can
|
||||||
avoid scaling the surface, and the client can supply
|
avoid scaling the surface, and the client can supply
|
||||||
a higher detail image.
|
a higher detail image.
|
||||||
|
|
||||||
|
The scale event will be followed by a done event.
|
||||||
</description>
|
</description>
|
||||||
<arg name="factor" type="int" summary="scaling factor of output"/>
|
<arg name="factor" type="int" summary="scaling factor of output"/>
|
||||||
</event>
|
</event>
|
||||||
@ -2624,6 +2734,62 @@
|
|||||||
use the output object anymore.
|
use the output object anymore.
|
||||||
</description>
|
</description>
|
||||||
</request>
|
</request>
|
||||||
|
|
||||||
|
<!-- Version 4 additions -->
|
||||||
|
|
||||||
|
<event name="name" since="4">
|
||||||
|
<description summary="name of this output">
|
||||||
|
Many compositors will assign user-friendly names to their outputs, show
|
||||||
|
them to the user, allow the user to refer to an output, etc. The client
|
||||||
|
may wish to know this name as well to offer the user similar behaviors.
|
||||||
|
|
||||||
|
The name is a UTF-8 string with no convention defined for its contents.
|
||||||
|
Each name is unique among all wl_output globals. The name is only
|
||||||
|
guaranteed to be unique for the compositor instance.
|
||||||
|
|
||||||
|
The same output name is used for all clients for a given wl_output
|
||||||
|
global. Thus, the name can be shared across processes to refer to a
|
||||||
|
specific wl_output global.
|
||||||
|
|
||||||
|
The name is not guaranteed to be persistent across sessions, thus cannot
|
||||||
|
be used to reliably identify an output in e.g. configuration files.
|
||||||
|
|
||||||
|
Examples of names include 'HDMI-A-1', 'WL-1', 'X11-1', etc. However, do
|
||||||
|
not assume that the name is a reflection of an underlying DRM connector,
|
||||||
|
X11 connection, etc.
|
||||||
|
|
||||||
|
The name event is sent after binding the output object. This event is
|
||||||
|
only sent once per output object, and the name does not change over the
|
||||||
|
lifetime of the wl_output global.
|
||||||
|
|
||||||
|
Compositors may re-use the same output name if the wl_output global is
|
||||||
|
destroyed and re-created later. Compositors should avoid re-using the
|
||||||
|
same name if possible.
|
||||||
|
|
||||||
|
The name event will be followed by a done event.
|
||||||
|
</description>
|
||||||
|
<arg name="name" type="string" summary="output name"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<event name="description" since="4">
|
||||||
|
<description summary="human-readable description of this output">
|
||||||
|
Many compositors can produce human-readable descriptions of their
|
||||||
|
outputs. The client may wish to know this description as well, e.g. for
|
||||||
|
output selection purposes.
|
||||||
|
|
||||||
|
The description is a UTF-8 string with no convention defined for its
|
||||||
|
contents. The description is not guaranteed to be unique among all
|
||||||
|
wl_output globals. Examples might include 'Foocorp 11" Display' or
|
||||||
|
'Virtual X11 output via :1'.
|
||||||
|
|
||||||
|
The description event is sent after binding the output object and
|
||||||
|
whenever the description changes. The description is optional, and may
|
||||||
|
not be sent at all.
|
||||||
|
|
||||||
|
The description event will be followed by a done event.
|
||||||
|
</description>
|
||||||
|
<arg name="description" type="string" summary="output description"/>
|
||||||
|
</event>
|
||||||
</interface>
|
</interface>
|
||||||
|
|
||||||
<interface name="wl_region" version="1">
|
<interface name="wl_region" version="1">
|
||||||
|
@ -375,7 +375,7 @@ QWaylandInputDevice::Touch::~Touch()
|
|||||||
}
|
}
|
||||||
|
|
||||||
QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, int version, uint32_t id)
|
QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, int version, uint32_t id)
|
||||||
: QtWayland::wl_seat(display->wl_registry(), id, qMin(version, 7))
|
: QtWayland::wl_seat(display->wl_registry(), id, qMin(version, 8))
|
||||||
, mQDisplay(display)
|
, mQDisplay(display)
|
||||||
, mDisplay(display->wl_display())
|
, mDisplay(display->wl_display())
|
||||||
{
|
{
|
||||||
@ -982,14 +982,16 @@ void QWaylandInputDevice::Pointer::pointer_axis_discrete(uint32_t axis, int32_t
|
|||||||
if (!focusWindow())
|
if (!focusWindow())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
const int32_t delta120 = value * 15 * 8;
|
||||||
|
|
||||||
switch (axis) {
|
switch (axis) {
|
||||||
case axis_vertical_scroll:
|
case axis_vertical_scroll:
|
||||||
qCDebug(lcQpaWaylandInput) << "wl_pointer.axis_discrete vertical:" << value;
|
qCDebug(lcQpaWaylandInput) << "wl_pointer.axis_discrete vertical:" << value;
|
||||||
mFrameData.discreteDelta.ry() += value;
|
mFrameData.delta120.ry() += delta120;
|
||||||
break;
|
break;
|
||||||
case axis_horizontal_scroll:
|
case axis_horizontal_scroll:
|
||||||
qCDebug(lcQpaWaylandInput) << "wl_pointer.axis_discrete horizontal:" << value;
|
qCDebug(lcQpaWaylandInput) << "wl_pointer.axis_discrete horizontal:" << value;
|
||||||
mFrameData.discreteDelta.rx() += value;
|
mFrameData.delta120.rx() += delta120;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
//TODO: is this really needed?
|
//TODO: is this really needed?
|
||||||
@ -998,6 +1000,26 @@ void QWaylandInputDevice::Pointer::pointer_axis_discrete(uint32_t axis, int32_t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QWaylandInputDevice::Pointer::pointer_axis_value120(uint32_t axis, int32_t value)
|
||||||
|
{
|
||||||
|
if (!focusWindow())
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (axis) {
|
||||||
|
case axis_vertical_scroll:
|
||||||
|
qCDebug(lcQpaWaylandInput) << "wl_pointer.axis_value120 vertical:" << value;
|
||||||
|
mFrameData.delta120.ry() += value;
|
||||||
|
break;
|
||||||
|
case axis_horizontal_scroll:
|
||||||
|
qCDebug(lcQpaWaylandInput) << "wl_pointer.axis_value120 horizontal:" << value;
|
||||||
|
mFrameData.delta120.rx() += value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
qCWarning(lcQpaWaylandInput) << "wl_pointer.axis_value120: Unknown axis:" << axis;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void QWaylandInputDevice::Pointer::setFrameEvent(QWaylandPointerEvent *event)
|
void QWaylandInputDevice::Pointer::setFrameEvent(QWaylandPointerEvent *event)
|
||||||
{
|
{
|
||||||
qCDebug(lcQpaWaylandInput) << "Setting frame event " << event->type;
|
qCDebug(lcQpaWaylandInput) << "Setting frame event " << event->type;
|
||||||
@ -1016,7 +1038,7 @@ void QWaylandInputDevice::Pointer::setFrameEvent(QWaylandPointerEvent *event)
|
|||||||
|
|
||||||
void QWaylandInputDevice::Pointer::FrameData::resetScrollData()
|
void QWaylandInputDevice::Pointer::FrameData::resetScrollData()
|
||||||
{
|
{
|
||||||
discreteDelta = QPoint();
|
delta120 = QPoint();
|
||||||
delta = QPointF();
|
delta = QPointF();
|
||||||
axisSource = axis_source_wheel;
|
axisSource = axis_source_wheel;
|
||||||
}
|
}
|
||||||
@ -1060,15 +1082,16 @@ QPoint QWaylandInputDevice::Pointer::FrameData::pixelDeltaAndError(QPointF *accu
|
|||||||
|
|
||||||
QPoint QWaylandInputDevice::Pointer::FrameData::angleDelta() const
|
QPoint QWaylandInputDevice::Pointer::FrameData::angleDelta() const
|
||||||
{
|
{
|
||||||
if (discreteDelta.isNull()) {
|
if (delta120.isNull()) {
|
||||||
// If we didn't get any discrete events, then we need to fall back to
|
// If we didn't get any discrete events, then we need to fall back to
|
||||||
// the continuous information.
|
// the continuous information.
|
||||||
return (delta * -12).toPoint(); //TODO: why multiply by 12?
|
return (delta * -12).toPoint(); //TODO: why multiply by 12?
|
||||||
}
|
}
|
||||||
|
|
||||||
// The angle delta is in eights of degrees, and our docs says most mice have
|
// The angle delta is in eights of degrees, and our docs says most mice have
|
||||||
// 1 click = 15 degrees. It's also in the opposite direction of surface space.
|
// 1 click = 15 degrees, i.e. 120 is one click. It's also in the opposite
|
||||||
return -discreteDelta * 15 * 8;
|
// direction of surface space.
|
||||||
|
return -delta120;
|
||||||
}
|
}
|
||||||
|
|
||||||
Qt::MouseEventSource QWaylandInputDevice::Pointer::FrameData::wheelEventSource() const
|
Qt::MouseEventSource QWaylandInputDevice::Pointer::FrameData::wheelEventSource() const
|
||||||
|
@ -308,6 +308,7 @@ protected:
|
|||||||
void pointer_axis_stop(uint32_t time, uint32_t axis) override;
|
void pointer_axis_stop(uint32_t time, uint32_t axis) override;
|
||||||
void pointer_axis_discrete(uint32_t axis, int32_t value) override;
|
void pointer_axis_discrete(uint32_t axis, int32_t value) override;
|
||||||
void pointer_frame() override;
|
void pointer_frame() override;
|
||||||
|
void pointer_axis_value120(uint32_t axis, int32_t value120) override;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void handleFocusDestroyed() { invalidateFocus(); }
|
void handleFocusDestroyed() { invalidateFocus(); }
|
||||||
@ -343,7 +344,7 @@ public:
|
|||||||
QWaylandPointerEvent *event = nullptr;
|
QWaylandPointerEvent *event = nullptr;
|
||||||
|
|
||||||
QPointF delta;
|
QPointF delta;
|
||||||
QPoint discreteDelta;
|
QPoint delta120;
|
||||||
axis_source axisSource = axis_source_wheel;
|
axis_source axisSource = axis_source_wheel;
|
||||||
|
|
||||||
void resetScrollData();
|
void resetScrollData();
|
||||||
|
@ -17,6 +17,7 @@ if (NOT WEBOS)
|
|||||||
add_subdirectory(output)
|
add_subdirectory(output)
|
||||||
add_subdirectory(primaryselectionv1)
|
add_subdirectory(primaryselectionv1)
|
||||||
add_subdirectory(seatv4)
|
add_subdirectory(seatv4)
|
||||||
|
add_subdirectory(seatv7)
|
||||||
add_subdirectory(seat)
|
add_subdirectory(seat)
|
||||||
add_subdirectory(surface)
|
add_subdirectory(surface)
|
||||||
add_subdirectory(tabletv2)
|
add_subdirectory(tabletv2)
|
||||||
|
@ -18,7 +18,7 @@ public:
|
|||||||
removeAll<Seat>();
|
removeAll<Seat>();
|
||||||
|
|
||||||
uint capabilities = MockCompositor::Seat::capability_pointer | MockCompositor::Seat::capability_touch;
|
uint capabilities = MockCompositor::Seat::capability_pointer | MockCompositor::Seat::capability_touch;
|
||||||
int version = 7;
|
int version = 8;
|
||||||
add<Seat>(capabilities, version);
|
add<Seat>(capabilities, version);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -40,8 +40,7 @@ private slots:
|
|||||||
void fingerScroll();
|
void fingerScroll();
|
||||||
void fingerScrollSlow();
|
void fingerScrollSlow();
|
||||||
void continuousScroll();
|
void continuousScroll();
|
||||||
void wheelDiscreteScroll_data();
|
void highResolutionScroll();
|
||||||
void wheelDiscreteScroll();
|
|
||||||
|
|
||||||
// Touch tests
|
// Touch tests
|
||||||
void createsTouch();
|
void createsTouch();
|
||||||
@ -56,13 +55,13 @@ private slots:
|
|||||||
void tst_seat::bindsToSeat()
|
void tst_seat::bindsToSeat()
|
||||||
{
|
{
|
||||||
QCOMPOSITOR_COMPARE(get<Seat>()->resourceMap().size(), 1);
|
QCOMPOSITOR_COMPARE(get<Seat>()->resourceMap().size(), 1);
|
||||||
QCOMPOSITOR_COMPARE(get<Seat>()->resourceMap().first()->version(), 7);
|
QCOMPOSITOR_COMPARE(get<Seat>()->resourceMap().first()->version(), 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_seat::createsPointer()
|
void tst_seat::createsPointer()
|
||||||
{
|
{
|
||||||
QCOMPOSITOR_TRY_COMPARE(pointer()->resourceMap().size(), 1);
|
QCOMPOSITOR_TRY_COMPARE(pointer()->resourceMap().size(), 1);
|
||||||
QCOMPOSITOR_TRY_COMPARE(pointer()->resourceMap().first()->version(), 7);
|
QCOMPOSITOR_TRY_COMPARE(pointer()->resourceMap().first()->version(), 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_seat::setsCursorOnEnter()
|
void tst_seat::setsCursorOnEnter()
|
||||||
@ -320,28 +319,19 @@ void tst_seat::fingerScrollSlow()
|
|||||||
QCOMPARE(accumulated.y(), -1);
|
QCOMPARE(accumulated.y(), -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_seat::wheelDiscreteScroll_data()
|
void tst_seat::highResolutionScroll()
|
||||||
{
|
|
||||||
QTest::addColumn<uint>("source");
|
|
||||||
QTest::newRow("wheel") << uint(Pointer::axis_source_wheel);
|
|
||||||
QTest::newRow("wheel tilt") << uint(Pointer::axis_source_wheel_tilt);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tst_seat::wheelDiscreteScroll()
|
|
||||||
{
|
{
|
||||||
WheelWindow window;
|
WheelWindow window;
|
||||||
QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial);
|
QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial);
|
||||||
|
|
||||||
QFETCH(uint, source);
|
|
||||||
|
|
||||||
exec([=] {
|
exec([=] {
|
||||||
auto *p = pointer();
|
auto *p = pointer();
|
||||||
auto *c = client();
|
auto *c = client();
|
||||||
p->sendEnter(xdgToplevel()->surface(), {32, 32});
|
p->sendEnter(xdgToplevel()->surface(), {32, 32});
|
||||||
p->sendFrame(c);
|
p->sendFrame(c);
|
||||||
p->sendAxisSource(c, Pointer::axis_source(source));
|
p->sendAxisSource(c, Pointer::axis_source_wheel);
|
||||||
p->sendAxisDiscrete(c, Pointer::axis_vertical_scroll, 1); // 1 click downwards
|
p->sendAxisValue120(c, Pointer::axis_vertical_scroll, 30); // quarter of a click
|
||||||
p->sendAxis(c, Pointer::axis_vertical_scroll, 1.0);
|
p->sendAxis(c, Pointer::axis_vertical_scroll, 3.75);
|
||||||
p->sendFrame(c);
|
p->sendFrame(c);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -350,10 +340,26 @@ void tst_seat::wheelDiscreteScroll()
|
|||||||
auto e = window.m_events.takeFirst();
|
auto e = window.m_events.takeFirst();
|
||||||
QCOMPARE(e.phase, Qt::NoScrollPhase);
|
QCOMPARE(e.phase, Qt::NoScrollPhase);
|
||||||
QVERIFY(qAbs(e.angleDelta.x()) <= qAbs(e.angleDelta.y())); // Vertical scroll
|
QVERIFY(qAbs(e.angleDelta.x()) <= qAbs(e.angleDelta.y())); // Vertical scroll
|
||||||
// According to the docs the angle delta is in eights of a degree and most mice have
|
QCOMPARE(e.angleDelta, QPoint(0, -30));
|
||||||
// 1 click = 15 degrees. The angle delta should therefore be:
|
// Click scrolls are not continuous and should not have a pixel delta
|
||||||
// 15 degrees / (1/8 eights per degrees) = 120 eights of degrees.
|
QCOMPARE(e.pixelDelta, QPoint(0, 0));
|
||||||
QCOMPARE(e.angleDelta, QPoint(0, -120));
|
}
|
||||||
|
|
||||||
|
exec([=] {
|
||||||
|
auto *p = pointer();
|
||||||
|
auto *c = client();
|
||||||
|
p->sendAxisSource(c, Pointer::axis_source_wheel);
|
||||||
|
p->sendAxisValue120(c, Pointer::axis_vertical_scroll, 90); // complete the click
|
||||||
|
p->sendAxis(c, Pointer::axis_vertical_scroll, 11.25);
|
||||||
|
p->sendFrame(c);
|
||||||
|
});
|
||||||
|
|
||||||
|
QTRY_VERIFY(!window.m_events.empty());
|
||||||
|
{
|
||||||
|
auto e = window.m_events.takeFirst();
|
||||||
|
QCOMPARE(e.phase, Qt::NoScrollPhase);
|
||||||
|
QVERIFY(qAbs(e.angleDelta.x()) <= qAbs(e.angleDelta.y())); // Vertical scroll
|
||||||
|
QCOMPARE(e.angleDelta, QPoint(0, -90));
|
||||||
// Click scrolls are not continuous and should not have a pixel delta
|
// Click scrolls are not continuous and should not have a pixel delta
|
||||||
QCOMPARE(e.pixelDelta, QPoint(0, 0));
|
QCOMPARE(e.pixelDelta, QPoint(0, 0));
|
||||||
}
|
}
|
||||||
@ -388,7 +394,7 @@ void tst_seat::continuousScroll()
|
|||||||
void tst_seat::createsTouch()
|
void tst_seat::createsTouch()
|
||||||
{
|
{
|
||||||
QCOMPOSITOR_TRY_COMPARE(touch()->resourceMap().size(), 1);
|
QCOMPOSITOR_TRY_COMPARE(touch()->resourceMap().size(), 1);
|
||||||
QCOMPOSITOR_TRY_COMPARE(touch()->resourceMap().first()->version(), 7);
|
QCOMPOSITOR_TRY_COMPARE(touch()->resourceMap().first()->version(), 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
class TouchWindow : public QRasterWindow {
|
class TouchWindow : public QRasterWindow {
|
||||||
|
13
tests/auto/wayland/seatv7/CMakeLists.txt
Normal file
13
tests/auto/wayland/seatv7/CMakeLists.txt
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
#####################################################################
|
||||||
|
## tst_seatv7 Test:
|
||||||
|
#####################################################################
|
||||||
|
|
||||||
|
qt_internal_add_test(tst_seatv7
|
||||||
|
SOURCES
|
||||||
|
tst_seatv7.cpp
|
||||||
|
LIBRARIES
|
||||||
|
SharedClientTest
|
||||||
|
)
|
130
tests/auto/wayland/seatv7/tst_seatv7.cpp
Normal file
130
tests/auto/wayland/seatv7/tst_seatv7.cpp
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
// Copyright (C) 2018 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#include "mockcompositor.h"
|
||||||
|
#include <QtOpenGL/QOpenGLWindow>
|
||||||
|
#include <QtGui/QRasterWindow>
|
||||||
|
#include <QtGui/QEventPoint>
|
||||||
|
|
||||||
|
using namespace MockCompositor;
|
||||||
|
|
||||||
|
class SeatCompositor : public DefaultCompositor {
|
||||||
|
public:
|
||||||
|
explicit SeatCompositor()
|
||||||
|
{
|
||||||
|
exec([this] {
|
||||||
|
m_config.autoConfigure = true;
|
||||||
|
|
||||||
|
removeAll<Seat>();
|
||||||
|
|
||||||
|
uint capabilities = MockCompositor::Seat::capability_pointer | MockCompositor::Seat::capability_touch;
|
||||||
|
int version = 7;
|
||||||
|
add<Seat>(capabilities, version);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class tst_seatv7 : public QObject, private SeatCompositor
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
private slots:
|
||||||
|
void cleanup() { QTRY_VERIFY2(isClean(), qPrintable(dirtyMessage())); }
|
||||||
|
void bindsToSeat();
|
||||||
|
|
||||||
|
// Pointer tests
|
||||||
|
void wheelDiscreteScroll_data();
|
||||||
|
void wheelDiscreteScroll();
|
||||||
|
};
|
||||||
|
|
||||||
|
void tst_seatv7::bindsToSeat()
|
||||||
|
{
|
||||||
|
QCOMPOSITOR_COMPARE(get<Seat>()->resourceMap().size(), 1);
|
||||||
|
QCOMPOSITOR_COMPARE(get<Seat>()->resourceMap().first()->version(), 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
class WheelWindow : QRasterWindow {
|
||||||
|
public:
|
||||||
|
WheelWindow()
|
||||||
|
{
|
||||||
|
resize(64, 64);
|
||||||
|
show();
|
||||||
|
}
|
||||||
|
void wheelEvent(QWheelEvent *event) override
|
||||||
|
{
|
||||||
|
QRasterWindow::wheelEvent(event);
|
||||||
|
// qDebug() << event << "angleDelta" << event->angleDelta() << "pixelDelta" << event->pixelDelta();
|
||||||
|
|
||||||
|
if (event->phase() != Qt::ScrollUpdate && event->phase() != Qt::NoScrollPhase) {
|
||||||
|
// Shouldn't have deltas in the these phases
|
||||||
|
QCOMPARE(event->angleDelta(), QPoint(0, 0));
|
||||||
|
QCOMPARE(event->pixelDelta(), QPoint(0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// The axis vector of the event is already in surface space, so there is now way to tell
|
||||||
|
// whether it is inverted or not.
|
||||||
|
QCOMPARE(event->inverted(), false);
|
||||||
|
|
||||||
|
// We didn't press any buttons
|
||||||
|
QCOMPARE(event->buttons(), Qt::NoButton);
|
||||||
|
|
||||||
|
m_events.append(Event{event});
|
||||||
|
}
|
||||||
|
struct Event // Because I didn't find a convenient way to copy it entirely
|
||||||
|
{
|
||||||
|
explicit Event() = default;
|
||||||
|
explicit Event(const QWheelEvent *event)
|
||||||
|
: phase(event->phase())
|
||||||
|
, pixelDelta(event->pixelDelta())
|
||||||
|
, angleDelta(event->angleDelta())
|
||||||
|
, source(event->source())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
Qt::ScrollPhase phase{};
|
||||||
|
QPoint pixelDelta;
|
||||||
|
QPoint angleDelta; // eights of a degree, positive is upwards, left
|
||||||
|
Qt::MouseEventSource source{};
|
||||||
|
};
|
||||||
|
QList<Event> m_events;
|
||||||
|
};
|
||||||
|
|
||||||
|
void tst_seatv7::wheelDiscreteScroll_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<uint>("source");
|
||||||
|
QTest::newRow("wheel") << uint(Pointer::axis_source_wheel);
|
||||||
|
QTest::newRow("wheel tilt") << uint(Pointer::axis_source_wheel_tilt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_seatv7::wheelDiscreteScroll()
|
||||||
|
{
|
||||||
|
WheelWindow window;
|
||||||
|
QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial);
|
||||||
|
|
||||||
|
QFETCH(uint, source);
|
||||||
|
|
||||||
|
exec([=] {
|
||||||
|
auto *p = pointer();
|
||||||
|
auto *c = client();
|
||||||
|
p->sendEnter(xdgToplevel()->surface(), {32, 32});
|
||||||
|
p->sendFrame(c);
|
||||||
|
p->sendAxisSource(c, Pointer::axis_source(source));
|
||||||
|
p->sendAxisDiscrete(c, Pointer::axis_vertical_scroll, 1); // 1 click downwards
|
||||||
|
p->sendAxis(c, Pointer::axis_vertical_scroll, 1.0);
|
||||||
|
p->sendFrame(c);
|
||||||
|
});
|
||||||
|
|
||||||
|
QTRY_VERIFY(!window.m_events.empty());
|
||||||
|
{
|
||||||
|
auto e = window.m_events.takeFirst();
|
||||||
|
QCOMPARE(e.phase, Qt::NoScrollPhase);
|
||||||
|
QVERIFY(qAbs(e.angleDelta.x()) <= qAbs(e.angleDelta.y())); // Vertical scroll
|
||||||
|
// According to the docs the angle delta is in eights of a degree and most mice have
|
||||||
|
// 1 click = 15 degrees. The angle delta should therefore be:
|
||||||
|
// 15 degrees / (1/8 eights per degrees) = 120 eights of degrees.
|
||||||
|
QCOMPARE(e.angleDelta, QPoint(0, -120));
|
||||||
|
// Click scrolls are not continuous and should not have a pixel delta
|
||||||
|
QCOMPARE(e.pixelDelta, QPoint(0, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QCOMPOSITOR_TEST_MAIN(tst_seatv7)
|
||||||
|
#include "tst_seatv7.moc"
|
@ -423,6 +423,13 @@ void Pointer::sendFrame(wl_client *client)
|
|||||||
send_frame(r->handle);
|
send_frame(r->handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Pointer::sendAxisValue120(wl_client *client, QtWaylandServer::wl_pointer::axis axis, int value120)
|
||||||
|
{
|
||||||
|
const auto pointerResources = resourceMap().values(client);
|
||||||
|
for (auto *r : pointerResources)
|
||||||
|
send_axis_value120(r->handle, axis, value120);
|
||||||
|
}
|
||||||
|
|
||||||
void Pointer::pointer_set_cursor(Resource *resource, uint32_t serial, wl_resource *surface, int32_t hotspot_x, int32_t hotspot_y)
|
void Pointer::pointer_set_cursor(Resource *resource, uint32_t serial, wl_resource *surface, int32_t hotspot_x, int32_t hotspot_y)
|
||||||
{
|
{
|
||||||
Q_UNUSED(resource);
|
Q_UNUSED(resource);
|
||||||
|
@ -296,7 +296,7 @@ class Seat : public Global, public QtWaylandServer::wl_seat
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit Seat(CoreCompositor *compositor, uint capabilities = Seat::capability_pointer | Seat::capability_keyboard | Seat::capability_touch, int version = 7);
|
explicit Seat(CoreCompositor *compositor, uint capabilities = Seat::capability_pointer | Seat::capability_keyboard | Seat::capability_touch, int version = 8);
|
||||||
~Seat() override;
|
~Seat() override;
|
||||||
void send_capabilities(Resource *resource, uint capabilities) = delete; // Use wrapper instead
|
void send_capabilities(Resource *resource, uint capabilities) = delete; // Use wrapper instead
|
||||||
void send_capabilities(uint capabilities) = delete; // Use wrapper instead
|
void send_capabilities(uint capabilities) = delete; // Use wrapper instead
|
||||||
@ -346,6 +346,7 @@ public:
|
|||||||
void sendAxisSource(wl_client *client, axis_source source);
|
void sendAxisSource(wl_client *client, axis_source source);
|
||||||
void sendAxisStop(wl_client *client, axis axis);
|
void sendAxisStop(wl_client *client, axis axis);
|
||||||
void sendFrame(wl_client *client);
|
void sendFrame(wl_client *client);
|
||||||
|
void sendAxisValue120(wl_client *client, axis axis, int value120);
|
||||||
|
|
||||||
Seat *m_seat = nullptr;
|
Seat *m_seat = nullptr;
|
||||||
QList<uint> m_enterSerials;
|
QList<uint> m_enterSerials;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user