diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c
index 40616df53..aa376556f 100644
--- a/src/video/wayland/SDL_waylandevents.c
+++ b/src/video/wayland/SDL_waylandevents.c
@@ -64,7 +64,9 @@
#include "../../events/SDL_keysym_to_scancode_c.h"
/* Clamp the wl_seat version on older versions of libwayland. */
-#if SDL_WAYLAND_CHECK_VERSION(1, 21, 0)
+#if SDL_WAYLAND_CHECK_VERSION(1, 22, 0)
+#define SDL_WL_SEAT_VERSION 9
+#elif SDL_WAYLAND_CHECK_VERSION(1, 21, 0)
#define SDL_WL_SEAT_VERSION 8
#else
#define SDL_WL_SEAT_VERSION 5
@@ -844,11 +846,31 @@ static void pointer_handle_axis(void *data, struct wl_pointer *pointer,
}
}
-static void pointer_handle_frame(void *data, struct wl_pointer *pointer)
+static void
+pointer_handle_axis_relative_direction(void *data, struct wl_pointer *pointer,
+ uint32_t axis, uint32_t axis_relative_direction)
+{
+ struct SDL_WaylandInput *input = data;
+ if (axis != WL_POINTER_AXIS_VERTICAL_SCROLL) {
+ return;
+ }
+ switch (axis_relative_direction) {
+ case WL_POINTER_AXIS_RELATIVE_DIRECTION_IDENTICAL:
+ input->pointer_curr_axis_info.direction = SDL_MOUSEWHEEL_NORMAL;
+ break;
+ case WL_POINTER_AXIS_RELATIVE_DIRECTION_INVERTED:
+ input->pointer_curr_axis_info.direction = SDL_MOUSEWHEEL_FLIPPED;
+ break;
+ }
+}
+
+static void
+pointer_handle_frame(void *data, struct wl_pointer *pointer)
{
struct SDL_WaylandInput *input = data;
SDL_WindowData *window = input->pointer_focus;
float x, y;
+ SDL_MouseWheelDirection direction = input->pointer_curr_axis_info.direction;
switch (input->pointer_curr_axis_info.x_axis_type) {
case AXIS_EVENT_CONTINUOUS:
@@ -885,7 +907,7 @@ static void pointer_handle_frame(void *data, struct wl_pointer *pointer)
if (x != 0.0f || y != 0.0f) {
SDL_SendMouseWheel(input->pointer_curr_axis_info.timestamp_ns,
- window->sdlwindow, 0, x, y, SDL_MOUSEWHEEL_NORMAL);
+ window->sdlwindow, 0, x, y, direction);
}
}
@@ -927,7 +949,8 @@ static const struct wl_pointer_listener pointer_listener = {
pointer_handle_axis_source, /* Version 5 */
pointer_handle_axis_stop, /* Version 5 */
pointer_handle_axis_discrete, /* Version 5 */
- pointer_handle_axis_value120 /* Version 8 */
+ pointer_handle_axis_value120, /* Version 8 */
+ pointer_handle_axis_relative_direction /* Version 9 */
};
static void touch_handler_down(void *data, struct wl_touch *touch, uint32_t serial,
diff --git a/src/video/wayland/SDL_waylandevents_c.h b/src/video/wayland/SDL_waylandevents_c.h
index 6e8afda89..15049b3f8 100644
--- a/src/video/wayland/SDL_waylandevents_c.h
+++ b/src/video/wayland/SDL_waylandevents_c.h
@@ -21,9 +21,12 @@
#include "SDL_internal.h"
+
#ifndef SDL_waylandevents_h_
#define SDL_waylandevents_h_
+#include "../../events/SDL_mouse_c.h"
+
#include "SDL_waylandvideo.h"
#include "SDL_waylandwindow.h"
#include "SDL_waylanddatamanager.h"
@@ -151,6 +154,7 @@ struct SDL_WaylandInput
/* Event timestamp in nanoseconds */
Uint64 timestamp_ns;
+ SDL_MouseWheelDirection direction;
} pointer_curr_axis_info;
SDL_WaylandKeyboardRepeat keyboard_repeat;
diff --git a/wayland-protocols/wayland.xml b/wayland-protocols/wayland.xml
index 10781cf16..10e039d6e 100644
--- a/wayland-protocols/wayland.xml
+++ b/wayland-protocols/wayland.xml
@@ -177,6 +177,9 @@
Clients can handle the 'done' event to get notified when
the related request is done.
+
+ Note, because wl_callback objects are created from multiple independent
+ factory interfaces, the wl_callback interface is frozen at version 1.
@@ -187,7 +190,7 @@
-
+
A compositor. This object is a singleton global. The
compositor is in charge of combining the contents of multiple
@@ -453,6 +456,9 @@
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.
+
+ Note, because wl_buffer objects are created from multiple independent
+ factory interfaces, the wl_buffer interface is frozen at version 1.
@@ -624,8 +630,9 @@
This event indicates the actions offered by the data source. It
- will be sent right after wl_data_device.enter, or anytime the source
- side changes its offered actions through wl_data_source.set_actions.
+ will be sent immediately after creating the wl_data_offer object,
+ or anytime the source side changes its offered actions through
+ wl_data_source.set_actions.
@@ -867,11 +874,8 @@
a drag-and-drop icon. If the icon surface already has another role,
it raises a protocol error.
- The current and pending input regions of the icon wl_surface are
- cleared, and wl_surface.set_input_region is ignored until the
- wl_surface is no longer used as the icon surface. When the use
- as an icon ends, the current and pending input regions become
- undefined, and the wl_surface is unmapped.
+ The input region is ignored for wl_surfaces with the role of a
+ drag-and-drop icon.
@@ -1352,7 +1356,7 @@
-
+
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,8 +1388,9 @@
that this request gives a role to a wl_surface. Often, this
request also creates a new protocol object that represents the
role and adds additional functionality to wl_surface. When a
- client wants to destroy a wl_surface, they must destroy this 'role
- object' before the wl_surface.
+ client wants to destroy a wl_surface, they must destroy this role
+ object before the wl_surface, otherwise a defunct_role_object error is
+ sent.
Destroying the role object does not remove the role from the
wl_surface, but it may stop the wl_surface from "playing the role".
@@ -1405,6 +1410,8 @@
+
@@ -1433,8 +1440,9 @@
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.
+ 'invalid_offset' error being raised. The x and y arguments are ignored
+ and do not change the pending state. To achieve equivalent semantics,
+ use wl_surface.offset.
Surface contents are double-buffered state, see wl_surface.commit.
@@ -1786,9 +1794,37 @@
+
+
+
+
+
+ This event indicates the preferred buffer scale for this surface. It is
+ sent whenever the compositor's preference changes.
+
+ It is intended that scaling aware clients use this event to scale their
+ content and use wl_surface.set_buffer_scale to indicate the scale they
+ have rendered with. This allows clients to supply a higher detail
+ buffer.
+
+
+
+
+
+
+ This event indicates the preferred buffer transform for this surface.
+ It is sent whenever the compositor's preference changes.
+
+ It is intended that transform aware clients use this event to apply the
+ transform to their content and use wl_surface.set_buffer_transform to
+ indicate the transform they have rendered with.
+
+
+
-
+
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
@@ -1921,7 +1957,7 @@
-
+
The wl_pointer interface represents one or more input devices,
such as mice, which control the pointer location and pointer_focus
@@ -1965,11 +2001,9 @@
pointer surface to this request with new values for hotspot_x
and hotspot_y.
- The current and pending input regions of the wl_surface are
- cleared, and wl_surface.set_input_region is ignored until the
- 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 input region is ignored for wl_surfaces with the role of
+ a cursor. When the use as a cursor ends, 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
@@ -2278,9 +2312,65 @@
+
+
+
+
+
+ This specifies the direction of the physical motion that caused a
+ wl_pointer.axis event, relative to the wl_pointer.axis direction.
+
+
+
+
+
+
+
+ Relative directional information of the entity causing the axis
+ motion.
+
+ For a wl_pointer.axis event, the wl_pointer.axis_relative_direction
+ event specifies the movement direction of the entity causing the
+ wl_pointer.axis event. For example:
+ - if a user's fingers on a touchpad move down and this
+ causes a wl_pointer.axis vertical_scroll down event, the physical
+ direction is 'identical'
+ - if a user's fingers on a touchpad move down and this causes a
+ wl_pointer.axis vertical_scroll up scroll up event ('natural
+ scrolling'), the physical direction is 'inverted'.
+
+ A client may use this information to adjust scroll motion of
+ components. Specifically, enabling natural scrolling causes the
+ content to change direction compared to traditional scrolling.
+ Some widgets like volume control sliders should usually match the
+ physical direction regardless of whether natural scrolling is
+ active. This event enables clients to match the scroll direction of
+ a widget to the physical direction.
+
+ This event does not occur on its own, it is coupled with a
+ wl_pointer.axis event that represents this axis value.
+ The protocol guarantees that each axis_relative_direction event is
+ always followed by exactly one axis event with the same
+ axis number within the same wl_pointer.frame. Note that the protocol
+ allows for other events to occur between the axis_relative_direction
+ and its coupled axis event.
+
+ The axis number is identical to the axis number in the associated
+ axis event.
+
+ The order of wl_pointer.axis_relative_direction,
+ wl_pointer.axis_discrete and wl_pointer.axis_source is not
+ guaranteed.
+
+
+
+
-
+
The wl_keyboard interface represents one or more keyboards
associated with a seat.
@@ -2407,7 +2497,7 @@
-
+
The wl_touch interface represents a touchscreen
associated with a seat.
@@ -2861,6 +2951,8 @@
+
@@ -2870,14 +2962,18 @@
plain wl_surface into a sub-surface.
The to-be sub-surface must not already have another role, and it
- must not have an existing wl_subsurface object. Otherwise a protocol
- error is raised.
+ must not have an existing wl_subsurface object. Otherwise the
+ bad_surface protocol error is raised.
Adding sub-surfaces to a parent is a double-buffered operation on the
parent (see wl_surface.commit). The effect of adding a sub-surface
becomes visible on the next time the state of the parent surface is
applied.
+ The parent surface must not be one of the child surface's descendants,
+ and the parent must be different from the child surface, otherwise the
+ bad_parent protocol error is raised.
+
This request modifies the behaviour of wl_surface.commit request on
the sub-surface, see the documentation on wl_subsurface interface.
@@ -2932,12 +3028,10 @@
synchronized mode, and then assume that all its child and grand-child
sub-surfaces are synchronized, too, without explicitly setting them.
- If the wl_surface associated with the wl_subsurface is destroyed, the
- wl_subsurface object becomes inert. Note, that destroying either object
- takes effect immediately. If you need to synchronize the removal
- of a sub-surface to the parent surface update, unmap the sub-surface
- first by attaching a NULL wl_buffer, update parent, and then destroy
- the sub-surface.
+ Destroying a sub-surface takes effect immediately. If you need to
+ synchronize the removal of a sub-surface to the parent surface update,
+ unmap the sub-surface first by attaching a NULL wl_buffer, update parent,
+ and then destroy the sub-surface.
If the parent wl_surface object is destroyed, the sub-surface is
unmapped.
@@ -2948,8 +3042,7 @@
The sub-surface interface is removed from the wl_surface object
that was turned into a sub-surface with a
wl_subcompositor.get_subsurface request. The wl_surface's association
- to the parent is deleted, and the wl_surface loses its role as
- a sub-surface. The wl_surface is unmapped immediately.
+ to the parent is deleted. The wl_surface is unmapped immediately.