diff options
author | Vlad Zahorodnii <vlad.zahorodnii@kde.org> | 2022-10-24 22:13:33 +0300 |
---|---|---|
committer | Vlad Zahorodnii <vlad.zahorodnii@kde.org> | 2022-10-26 22:34:20 +0300 |
commit | f1e71327d462d2dae0b46677bbc478afb0d1b2f7 (patch) | |
tree | 0e5e8c08dd8e71d94cc5aeaa1b27bdd8c67eeda7 /src | |
parent | 763b3dba2c0e62926072a40373aa7685a6264b7b (diff) | |
download | qtwayland-f1e71327d462d2dae0b46677bbc478afb0d1b2f7.tar.gz |
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>
Diffstat (limited to 'src')
-rw-r--r-- | src/3rdparty/protocol/wayland.xml | 224 | ||||
-rw-r--r-- | src/client/qwaylandinputdevice.cpp | 37 | ||||
-rw-r--r-- | src/client/qwaylandinputdevice_p.h | 3 |
3 files changed, 227 insertions, 37 deletions
diff --git a/src/3rdparty/protocol/wayland.xml b/src/3rdparty/protocol/wayland.xml index 471daf66..01bc267a 100644 --- a/src/3rdparty/protocol/wayland.xml +++ b/src/3rdparty/protocol/wayland.xml @@ -187,7 +187,7 @@ </event> </interface> - <interface name="wl_compositor" version="4"> + <interface name="wl_compositor" version="5"> <description summary="the compositor singleton"> A compositor. This object is a singleton global. The 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 created, but using the new size. This request can only be 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> <arg name="size" type="int" summary="new size of the pool, in bytes"/> </request> @@ -271,8 +277,8 @@ Clients can create wl_shm_pool objects using the create_pool request. - At connection setup time, the wl_shm object emits one or more - format events to inform clients about the valid pixel formats + On binding the wl_shm object one or more format events + are emitted to inform clients about the valid pixel formats that can be used for buffers. </description> @@ -296,6 +302,9 @@ The drm format codes match the macros defined in drm_fourcc.h, except argb8888 and xrgb8888. The formats actually supported by the compositor 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> <!-- Note to protocol writers: don't update this list manually, instead 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="q410" value="0x30313451"/> <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> <request name="create_pool"> @@ -431,10 +444,15 @@ <interface name="wl_buffer" version="1"> <description summary="content for a wl_surface"> A buffer provides the content for a wl_surface. Buffers are - created through factory interfaces such as wl_drm, wl_shm or - similar. It has a width and a height and can be attached to a - wl_surface, but the mechanism by which a client provides and - updates the contents is defined by the buffer factory interface. + created through factory interfaces such as wl_shm, wp_linux_buffer_params + (from the linux-dmabuf protocol extension) or similar. It has a width and + a height and can be attached to a wl_surface, but the mechanism by which a + 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> <request name="destroy" type="destructor"> @@ -878,7 +896,7 @@ which will subsequently be used in either the data_device.enter event (for drag-and-drop) or the 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 mime types it offers. </description> @@ -948,9 +966,10 @@ immediately before receiving keyboard focus and when a new selection is set while the client has keyboard focus. The data_offer is valid until a new data_offer or NULL is received - or until the client loses keyboard focus. The client must - destroy the previous selection data_offer, if any, upon receiving - this event. + or until the client loses keyboard focus. Switching surface with + keyboard focus within the same client doesn't mean a new selection + will be sent. The client must destroy the previous selection + data_offer, if any, upon receiving this event. </description> <arg name="id" type="object" interface="wl_data_offer" allow-null="true" summary="selection data_offer object"/> @@ -1038,7 +1057,8 @@ a basic surface. 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> <enum name="error"> @@ -1332,7 +1352,7 @@ </event> </interface> - <interface name="wl_surface" version="4"> + <interface name="wl_surface" version="5"> <description summary="an onscreen surface"> 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 @@ -1384,6 +1404,7 @@ <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_size" value="2" summary="buffer size is invalid"/> + <entry name="invalid_offset" value="3" summary="buffer offset is invalid"/> </enum> <request name="destroy" type="destructor"> @@ -1406,7 +1427,14 @@ 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. + 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. @@ -1434,9 +1462,12 @@ from the same backing storage or use wp_linux_buffer_release. Destroying the wl_buffer after wl_buffer.release does not change - the surface contents. However, if the client destroys the - wl_buffer before receiving the wl_buffer.release event, the surface - contents become undefined immediately. + the surface contents. Destroying the wl_buffer before wl_buffer.release + is allowed as long as the underlying buffer storage isn't re-used (this + 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 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="height" type="int" summary="height of damage rectangle"/> </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 name="wl_seat" version="7"> + <interface name="wl_seat" version="8"> <description summary="group of input devices"> 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 @@ -1838,9 +1890,22 @@ <event name="name" since="2"> <description summary="unique identifier for this seat"> - In a multiseat configuration this can be used by the client to help - identify which physical devices the seat represents. Based on - the seat configuration used by the compositor. + In a multi-seat configuration the seat name can be used by clients to + help identify which physical devices the seat represents. + + 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> <arg name="name" type="string" summary="seat identifier"/> </event> @@ -1856,7 +1921,7 @@ </interface> - <interface name="wl_pointer" version="7"> + <interface name="wl_pointer" version="8"> <description summary="pointer input device"> The wl_pointer interface represents one or more input devices, 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 cursor ends, the current and pending input regions become 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> <arg name="serial" type="uint" summary="serial number of the enter event"/> <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 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 wl_pointer.axis event that represents this axis value on a 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 allows for other events to occur between the axis_discrete and 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 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="discrete" type="int" summary="number of steps"/> </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 name="wl_keyboard" version="7"> + <interface name="wl_keyboard" version="8"> <description summary="keyboard input device"> The wl_keyboard interface represents one or more keyboards associated with a seat. @@ -2193,13 +2294,14 @@ <entry name="no_keymap" value="0" summary="no keymap; client must understand how to interpret the raw keycode"/> <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> <event name="keymap"> <description summary="keyboard mapping"> 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 the recipient, as MAP_SHARED may fail. @@ -2305,7 +2407,7 @@ </event> </interface> - <interface name="wl_touch" version="7"> + <interface name="wl_touch" version="8"> <description summary="touchscreen input device"> The wl_touch interface represents a touchscreen associated with a seat. @@ -2449,7 +2551,7 @@ </event> </interface> - <interface name="wl_output" version="3"> + <interface name="wl_output" version="4"> <description summary="compositor output region"> An output describes part of the compositor geometry. The 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 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 position and identification. Some compositors, for instance those not implementing a desktop-style output layout or those exposing virtual outputs, might fake this information. Instead of using x and y, clients 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> <arg name="x" type="int" 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 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, they should use the wl_surface.frame event or the presentation-time protocol. @@ -2612,6 +2720,8 @@ the scale of the output. That way the compositor can avoid scaling the surface, and the client can supply a higher detail image. + + The scale event will be followed by a done event. </description> <arg name="factor" type="int" summary="scaling factor of output"/> </event> @@ -2624,6 +2734,62 @@ use the output object anymore. </description> </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 name="wl_region" version="1"> diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp index 56c89688..4b4e54bd 100644 --- a/src/client/qwaylandinputdevice.cpp +++ b/src/client/qwaylandinputdevice.cpp @@ -375,7 +375,7 @@ QWaylandInputDevice::Touch::~Touch() } 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) , mDisplay(display->wl_display()) { @@ -982,14 +982,16 @@ void QWaylandInputDevice::Pointer::pointer_axis_discrete(uint32_t axis, int32_t if (!focusWindow()) return; + const int32_t delta120 = value * 15 * 8; + switch (axis) { case axis_vertical_scroll: qCDebug(lcQpaWaylandInput) << "wl_pointer.axis_discrete vertical:" << value; - mFrameData.discreteDelta.ry() += value; + mFrameData.delta120.ry() += delta120; break; case axis_horizontal_scroll: qCDebug(lcQpaWaylandInput) << "wl_pointer.axis_discrete horizontal:" << value; - mFrameData.discreteDelta.rx() += value; + mFrameData.delta120.rx() += delta120; break; default: //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) { qCDebug(lcQpaWaylandInput) << "Setting frame event " << event->type; @@ -1016,7 +1038,7 @@ void QWaylandInputDevice::Pointer::setFrameEvent(QWaylandPointerEvent *event) void QWaylandInputDevice::Pointer::FrameData::resetScrollData() { - discreteDelta = QPoint(); + delta120 = QPoint(); delta = QPointF(); axisSource = axis_source_wheel; } @@ -1060,15 +1082,16 @@ QPoint QWaylandInputDevice::Pointer::FrameData::pixelDeltaAndError(QPointF *accu 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 // the continuous information. return (delta * -12).toPoint(); //TODO: why multiply by 12? } // 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. - return -discreteDelta * 15 * 8; + // 1 click = 15 degrees, i.e. 120 is one click. It's also in the opposite + // direction of surface space. + return -delta120; } Qt::MouseEventSource QWaylandInputDevice::Pointer::FrameData::wheelEventSource() const diff --git a/src/client/qwaylandinputdevice_p.h b/src/client/qwaylandinputdevice_p.h index b9c69ee1..fbc26008 100644 --- a/src/client/qwaylandinputdevice_p.h +++ b/src/client/qwaylandinputdevice_p.h @@ -308,6 +308,7 @@ protected: void pointer_axis_stop(uint32_t time, uint32_t axis) override; void pointer_axis_discrete(uint32_t axis, int32_t value) override; void pointer_frame() override; + void pointer_axis_value120(uint32_t axis, int32_t value120) override; private slots: void handleFocusDestroyed() { invalidateFocus(); } @@ -343,7 +344,7 @@ public: QWaylandPointerEvent *event = nullptr; QPointF delta; - QPoint discreteDelta; + QPoint delta120; axis_source axisSource = axis_source_wheel; void resetScrollData(); |