wayland: Don't clear the cursor on leave events
Stop the frame callback and flag the cursor for a refresh when the pointer re-enters the surface, but don't set a null cursor, as it may have already been set after entering a surface that is part of the window decorations, resulting in an unwanted invisible cursor.
This commit is contained in:
@@ -73,7 +73,10 @@ typedef struct SDL_WaylandCursorState
|
|||||||
|
|
||||||
Uint64 last_frame_callback_time_ms;
|
Uint64 last_frame_callback_time_ms;
|
||||||
Uint32 current_frame_time_ms;
|
Uint32 current_frame_time_ms;
|
||||||
|
|
||||||
|
// 0 or greater if a buffer is attached, -1 if in the reset state.
|
||||||
int current_frame;
|
int current_frame;
|
||||||
|
|
||||||
SDL_HitTestResult hit_test_result;
|
SDL_HitTestResult hit_test_result;
|
||||||
} SDL_WaylandCursorState;
|
} SDL_WaylandCursorState;
|
||||||
|
|
||||||
|
|||||||
@@ -900,7 +900,8 @@ static void Wayland_FreeCursorData(SDL_CursorData *d)
|
|||||||
if (seat->pointer.current_cursor == d) {
|
if (seat->pointer.current_cursor == d) {
|
||||||
Wayland_CursorStateDestroyFrameCallback(&seat->pointer.cursor_state);
|
Wayland_CursorStateDestroyFrameCallback(&seat->pointer.cursor_state);
|
||||||
|
|
||||||
if (seat->pointer.cursor_state.surface) {
|
// Custom cursor buffers are about to be destroyed, so ensure they are detached.
|
||||||
|
if (!d->is_system_cursor && seat->pointer.cursor_state.surface) {
|
||||||
wl_surface_attach(seat->pointer.cursor_state.surface, NULL, 0, 0);
|
wl_surface_attach(seat->pointer.cursor_state.surface, NULL, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1040,7 +1041,7 @@ static void Wayland_CursorStateSetCursor(SDL_WaylandCursorState *state, const Wa
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cursor) {
|
if (cursor) {
|
||||||
if (cursor_data == state->current_cursor) {
|
if (cursor_data == state->current_cursor && state->current_frame >= 0) {
|
||||||
// Restart the animation sequence if the cursor didn't change.
|
// Restart the animation sequence if the cursor didn't change.
|
||||||
if (cursor_data->num_frames > 1) {
|
if (cursor_data->num_frames > 1) {
|
||||||
Wayland_CursorStateResetAnimation(state, true);
|
Wayland_CursorStateResetAnimation(state, true);
|
||||||
@@ -1075,6 +1076,7 @@ static void Wayland_CursorStateSetCursor(SDL_WaylandCursorState *state, const Wa
|
|||||||
const enum wp_cursor_shape_device_v1_shape shape = Wayland_GetSystemCursorShape(cursor_data->cursor_data.system.id);
|
const enum wp_cursor_shape_device_v1_shape shape = Wayland_GetSystemCursorShape(cursor_data->cursor_data.system.id);
|
||||||
wp_cursor_shape_device_v1_set_shape(state->cursor_shape, serial, shape);
|
wp_cursor_shape_device_v1_set_shape(state->cursor_shape, serial, shape);
|
||||||
state->current_cursor = cursor_data;
|
state->current_cursor = cursor_data;
|
||||||
|
state->current_frame = 0;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1107,6 +1109,7 @@ static void Wayland_CursorStateSetCursor(SDL_WaylandCursorState *state, const Wa
|
|||||||
|
|
||||||
struct wl_buffer *buffer = Wayland_CursorStateGetFrame(state, 0);
|
struct wl_buffer *buffer = Wayland_CursorStateGetFrame(state, 0);
|
||||||
wl_surface_attach(state->surface, buffer, 0, 0);
|
wl_surface_attach(state->surface, buffer, 0, 0);
|
||||||
|
state->current_frame = 0;
|
||||||
|
|
||||||
if (state->scale != 1.0) {
|
if (state->scale != 1.0) {
|
||||||
if (!state->viewport) {
|
if (!state->viewport) {
|
||||||
@@ -1156,6 +1159,13 @@ static void Wayland_CursorStateSetCursor(SDL_WaylandCursorState *state, const Wa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void Wayland_CursorStateResetCursor(SDL_WaylandCursorState *state)
|
||||||
|
{
|
||||||
|
// Stop the frame callback and set the reset status.
|
||||||
|
Wayland_CursorStateDestroyFrameCallback(state);
|
||||||
|
state->current_frame = -1;
|
||||||
|
}
|
||||||
|
|
||||||
static bool Wayland_ShowCursor(SDL_Cursor *cursor)
|
static bool Wayland_ShowCursor(SDL_Cursor *cursor)
|
||||||
{
|
{
|
||||||
SDL_VideoDevice *vd = SDL_GetVideoDevice();
|
SDL_VideoDevice *vd = SDL_GetVideoDevice();
|
||||||
@@ -1170,7 +1180,7 @@ static bool Wayland_ShowCursor(SDL_Cursor *cursor)
|
|||||||
if (mouse->focus && mouse->focus->internal == seat->pointer.focus) {
|
if (mouse->focus && mouse->focus->internal == seat->pointer.focus) {
|
||||||
Wayland_CursorStateSetCursor(&seat->pointer.cursor_state, &obj, seat->pointer.focus, seat->pointer.enter_serial, cursor);
|
Wayland_CursorStateSetCursor(&seat->pointer.cursor_state, &obj, seat->pointer.focus, seat->pointer.enter_serial, cursor);
|
||||||
} else if (!seat->pointer.focus) {
|
} else if (!seat->pointer.focus) {
|
||||||
Wayland_CursorStateSetCursor(&seat->pointer.cursor_state, &obj, seat->pointer.focus, seat->pointer.enter_serial, NULL);
|
Wayland_CursorStateResetCursor(&seat->pointer.cursor_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_WaylandPenTool *tool;
|
SDL_WaylandPenTool *tool;
|
||||||
@@ -1184,7 +1194,7 @@ static bool Wayland_ShowCursor(SDL_Cursor *cursor)
|
|||||||
if (tool->focus && (!mouse->focus || mouse->focus->internal == tool->focus)) {
|
if (tool->focus && (!mouse->focus || mouse->focus->internal == tool->focus)) {
|
||||||
Wayland_CursorStateSetCursor(&tool->cursor_state, &obj, tool->focus, tool->proximity_serial, mouse->cur_cursor);
|
Wayland_CursorStateSetCursor(&tool->cursor_state, &obj, tool->focus, tool->proximity_serial, mouse->cur_cursor);
|
||||||
} else if (!tool->focus) {
|
} else if (!tool->focus) {
|
||||||
Wayland_CursorStateSetCursor(&tool->cursor_state, &obj, tool->focus, tool->proximity_serial, NULL);
|
Wayland_CursorStateResetCursor(&tool->cursor_state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1506,7 +1516,8 @@ void Wayland_SeatUpdatePointerCursor(SDL_WaylandSeat *seat)
|
|||||||
.is_pointer = true
|
.is_pointer = true
|
||||||
};
|
};
|
||||||
|
|
||||||
if (pointer_focus && mouse->cursor_visible) {
|
if (pointer_focus) {
|
||||||
|
if (mouse->cursor_visible) {
|
||||||
if (!seat->pointer.relative_pointer || !mouse->relative_mode_hide_cursor) {
|
if (!seat->pointer.relative_pointer || !mouse->relative_mode_hide_cursor) {
|
||||||
const SDL_HitTestResult rc = pointer_focus->hit_test_result;
|
const SDL_HitTestResult rc = pointer_focus->hit_test_result;
|
||||||
|
|
||||||
@@ -1520,11 +1531,11 @@ void Wayland_SeatUpdatePointerCursor(SDL_WaylandSeat *seat)
|
|||||||
Wayland_CursorStateSetCursor(&seat->pointer.cursor_state, &obj, pointer_focus, seat->pointer.enter_serial, NULL);
|
Wayland_CursorStateSetCursor(&seat->pointer.cursor_state, &obj, pointer_focus, seat->pointer.enter_serial, NULL);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* The spec states "The cursor actually changes only if the input device focus is one of the
|
|
||||||
* requesting client's surfaces", so just clear the cursor if the seat has no pointer focus.
|
|
||||||
*/
|
|
||||||
Wayland_CursorStateSetCursor(&seat->pointer.cursor_state, &obj, pointer_focus, seat->pointer.enter_serial, NULL);
|
Wayland_CursorStateSetCursor(&seat->pointer.cursor_state, &obj, pointer_focus, seat->pointer.enter_serial, NULL);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Wayland_CursorStateResetCursor(&seat->pointer.cursor_state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wayland_TabletToolUpdateCursor(SDL_WaylandPenTool *tool)
|
void Wayland_TabletToolUpdateCursor(SDL_WaylandPenTool *tool)
|
||||||
@@ -1536,7 +1547,8 @@ void Wayland_TabletToolUpdateCursor(SDL_WaylandPenTool *tool)
|
|||||||
.is_pointer = false
|
.is_pointer = false
|
||||||
};
|
};
|
||||||
|
|
||||||
if (tool_focus && mouse->cursor_visible) {
|
if (tool_focus) {
|
||||||
|
if (mouse->cursor_visible) {
|
||||||
// Relative mode is only relevant if the tool sends pointer events.
|
// Relative mode is only relevant if the tool sends pointer events.
|
||||||
const bool relative = mouse->pen_mouse_events && (tool_focus->sdlwindow->flags & SDL_WINDOW_MOUSE_RELATIVE_MODE);
|
const bool relative = mouse->pen_mouse_events && (tool_focus->sdlwindow->flags & SDL_WINDOW_MOUSE_RELATIVE_MODE);
|
||||||
|
|
||||||
@@ -1549,6 +1561,9 @@ void Wayland_TabletToolUpdateCursor(SDL_WaylandPenTool *tool)
|
|||||||
} else {
|
} else {
|
||||||
Wayland_CursorStateSetCursor(&tool->cursor_state, &obj, tool_focus, tool->proximity_serial, NULL);
|
Wayland_CursorStateSetCursor(&tool->cursor_state, &obj, tool_focus, tool->proximity_serial, NULL);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Wayland_CursorStateResetCursor(&tool->cursor_state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // SDL_VIDEO_DRIVER_WAYLAND
|
#endif // SDL_VIDEO_DRIVER_WAYLAND
|
||||||
|
|||||||
Reference in New Issue
Block a user