wayland: Set tablet cursors separately from pointer cursors

Some compositors don't implicitly use the pointer cursor when the tablet cursor is not set, and the presence of a tablet doesn't necessarily guarantee pointer capability. Set the cursor for tablet tools independently of pointer cursors.

This required refactoring of cursor state handling, as well as some tablet related structures.
This commit is contained in:
Frank Praznik
2025-10-31 16:15:12 -04:00
parent ca569bb837
commit 6a510d6174
4 changed files with 437 additions and 348 deletions
File diff suppressed because it is too large Load Diff
+61 -17
View File
@@ -56,6 +56,66 @@ typedef struct
char text[8];
} SDL_WaylandKeyboardRepeat;
typedef struct SDL_WaylandCursorState
{
SDL_CursorData *current_cursor;
struct wp_cursor_shape_device_v1 *cursor_shape;
struct wl_surface *surface;
struct wp_viewport *viewport;
double scale;
// Pointer to the internal data for system cursors.
void *system_cursor_handle;
// The cursor animation thread lock must be held when modifying this.
struct wl_callback *frame_callback;
Uint64 last_frame_callback_time_ms;
Uint32 current_frame_time_ms;
int current_frame;
SDL_HitTestResult hit_test_result;
} SDL_WaylandCursorState;
typedef struct SDL_WaylandPenTool // a stylus, etc, on a tablet.
{
SDL_PenID instance_id;
SDL_PenInfo info;
SDL_WindowData *focus;
struct zwp_tablet_tool_v2 *wltool;
Uint32 proximity_serial;
struct
{
float x;
float y;
float axes[SDL_PEN_AXIS_COUNT];
Uint32 axes_set;
enum
{
WAYLAND_TABLET_TOOL_BUTTON_NONE = 0,
WAYLAND_TABLET_TOOL_BUTTON_DOWN,
WAYLAND_TABLET_TOOL_BUTTON_UP
} buttons[3];
enum
{
WAYLAND_TABLET_TOOL_STATE_NONE = 0,
WAYLAND_TABLET_TOOL_STATE_DOWN,
WAYLAND_TABLET_TOOL_STATE_UP
} tool_state;
bool have_motion;
bool have_proximity_in;
bool have_proximity_out;
} frame;
SDL_WaylandCursorState cursor_state;
struct wl_list link;
} SDL_WaylandPenTool;
typedef struct SDL_WaylandSeat
{
SDL_VideoData *display;
@@ -120,7 +180,6 @@ typedef struct SDL_WaylandSeat
struct wl_pointer *wl_pointer;
struct zwp_relative_pointer_v1 *relative_pointer;
struct zwp_input_timestamps_v1 *timestamps;
struct wp_cursor_shape_device_v1 *cursor_shape;
struct zwp_locked_pointer_v1 *locked_pointer;
struct zwp_confined_pointer_v1 *confined_pointer;
struct zwp_pointer_gesture_pinch_v1 *gesture_pinch;
@@ -176,22 +235,7 @@ typedef struct SDL_WaylandSeat
Uint64 timestamp_ns;
} pending_frame;
// Cursor state
struct
{
struct wl_surface *surface;
struct wp_viewport *viewport;
// Animation state for cursors
void *cursor_handle;
// The cursor animation thread lock must be held when modifying this.
struct wl_callback *frame_callback;
Uint64 last_frame_callback_time_ms;
Uint32 current_frame_time_ms;
int current_frame;
} cursor_state;
SDL_WaylandCursorState cursor_state;
} pointer;
struct
File diff suppressed because it is too large Load Diff
+5 -3
View File
@@ -26,10 +26,12 @@
extern void Wayland_InitMouse(SDL_VideoData *data);
extern void Wayland_FiniMouse(SDL_VideoData *data);
extern void Wayland_SeatUpdateCursor(SDL_WaylandSeat *seat);
extern void Wayland_SeatUpdatePointerCursor(SDL_WaylandSeat *seat);
extern void Wayland_TabletToolUpdateCursor(SDL_WaylandPenTool *tool);
extern void Wayland_SeatWarpMouse(SDL_WaylandSeat *seat, SDL_WindowData *window, float x, float y);
extern void Wayland_SeatSetCursorFrameCallback(SDL_WaylandSeat *seat);
extern void Wayland_SeatDestroyCursorFrameCallback(SDL_WaylandSeat *seat);
extern void Wayland_CursorStateSetFrameCallback(SDL_WaylandCursorState *state, void *userdata);
extern void Wayland_CursorStateDestroyFrameCallback(SDL_WaylandCursorState *state);
extern void Wayland_CursorStateRelease(SDL_WaylandCursorState *state);
#if 0 // TODO RECONNECT: See waylandvideo.c for more information!
extern void Wayland_RecreateCursors(void);
#endif // 0