Skip to content

Commit 4215dfd

Browse files
committed
Merge pull request godotengine#96973 from Riteo/pointing-the-obvious
Wayland: Simplify cursor code and fix custom cursors
2 parents ebe8f36 + c15cd3a commit 4215dfd

File tree

3 files changed

+59
-93
lines changed

3 files changed

+59
-93
lines changed

platform/linuxbsd/wayland/display_server_wayland.cpp

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -327,15 +327,7 @@ void DisplayServerWayland::mouse_set_mode(MouseMode p_mode) {
327327

328328
bool show_cursor = (p_mode == MOUSE_MODE_VISIBLE || p_mode == MOUSE_MODE_CONFINED);
329329

330-
if (show_cursor) {
331-
if (custom_cursors.has(cursor_shape)) {
332-
wayland_thread.cursor_set_custom_shape(cursor_shape);
333-
} else {
334-
wayland_thread.cursor_set_shape(cursor_shape);
335-
}
336-
} else {
337-
wayland_thread.cursor_hide();
338-
}
330+
wayland_thread.cursor_set_visible(show_cursor);
339331

340332
WaylandThread::PointerConstraint constraint = WaylandThread::PointerConstraint::NONE;
341333

@@ -993,11 +985,7 @@ void DisplayServerWayland::cursor_set_shape(CursorShape p_shape) {
993985
return;
994986
}
995987

996-
if (custom_cursors.has(p_shape)) {
997-
wayland_thread.cursor_set_custom_shape(p_shape);
998-
} else {
999-
wayland_thread.cursor_set_shape(p_shape);
1000-
}
988+
wayland_thread.cursor_set_shape(p_shape);
1001989
}
1002990

1003991
DisplayServerWayland::CursorShape DisplayServerWayland::cursor_get_shape() const {
@@ -1009,18 +997,13 @@ DisplayServerWayland::CursorShape DisplayServerWayland::cursor_get_shape() const
1009997
void DisplayServerWayland::cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
1010998
MutexLock mutex_lock(wayland_thread.mutex);
1011999

1012-
bool visible = (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED);
1013-
10141000
if (p_cursor.is_valid()) {
10151001
HashMap<CursorShape, CustomCursor>::Iterator cursor_c = custom_cursors.find(p_shape);
10161002

10171003
if (cursor_c) {
10181004
if (cursor_c->value.rid == p_cursor->get_rid() && cursor_c->value.hotspot == p_hotspot) {
10191005
// We have a cached cursor. Nice.
1020-
if (visible) {
1021-
wayland_thread.cursor_set_custom_shape(p_shape);
1022-
}
1023-
1006+
wayland_thread.cursor_set_shape(p_shape);
10241007
return;
10251008
}
10261009

@@ -1039,20 +1022,18 @@ void DisplayServerWayland::cursor_set_custom_image(const Ref<Resource> &p_cursor
10391022

10401023
wayland_thread.cursor_shape_set_custom_image(p_shape, image, p_hotspot);
10411024

1042-
if (visible) {
1043-
wayland_thread.cursor_set_custom_shape(p_shape);
1044-
}
1025+
wayland_thread.cursor_set_shape(p_shape);
10451026
} else {
10461027
// Clear cache and reset to default system cursor.
1047-
if (cursor_shape == p_shape && visible) {
1028+
wayland_thread.cursor_shape_clear_custom_image(p_shape);
1029+
1030+
if (cursor_shape == p_shape) {
10481031
wayland_thread.cursor_set_shape(p_shape);
10491032
}
10501033

10511034
if (custom_cursors.has(p_shape)) {
10521035
custom_cursors.erase(p_shape);
10531036
}
1054-
1055-
wayland_thread.cursor_shape_clear_custom_image(p_shape);
10561037
}
10571038
}
10581039

platform/linuxbsd/wayland/wayland_thread.cpp

Lines changed: 49 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,6 @@ bool WaylandThread::_load_cursor_theme(int p_cursor_size) {
265265
if (wl_cursor_theme) {
266266
wl_cursor_theme_destroy(wl_cursor_theme);
267267
wl_cursor_theme = nullptr;
268-
269-
current_wl_cursor = nullptr;
270268
}
271269

272270
if (cursor_theme_name.is_empty()) {
@@ -357,7 +355,12 @@ void WaylandThread::_update_scale(int p_scale) {
357355
int cursor_size = unscaled_cursor_size * p_scale;
358356

359357
if (_load_cursor_theme(cursor_size)) {
360-
cursor_set_shape(last_cursor_shape);
358+
for (struct wl_seat *wl_seat : registry.wl_seats) {
359+
SeatState *ss = wl_seat_get_seat_state(wl_seat);
360+
ERR_FAIL_NULL(ss);
361+
362+
seat_state_update_cursor(ss);
363+
}
361364
}
362365
}
363366

@@ -3074,19 +3077,25 @@ void WaylandThread::seat_state_confine_pointer(SeatState *p_ss) {
30743077

30753078
void WaylandThread::seat_state_update_cursor(SeatState *p_ss) {
30763079
ERR_FAIL_NULL(p_ss);
3080+
3081+
WaylandThread *thread = p_ss->wayland_thread;
30773082
ERR_FAIL_NULL(p_ss->wayland_thread);
30783083

3079-
if (p_ss->wl_pointer && p_ss->cursor_surface) {
3080-
// NOTE: Those values are valid by default and will hide the cursor when
3081-
// unchanged, which happens when both the current custom cursor and the
3082-
// current wl_cursor are `nullptr`.
3083-
struct wl_buffer *cursor_buffer = nullptr;
3084-
uint32_t hotspot_x = 0;
3085-
uint32_t hotspot_y = 0;
3086-
int scale = 1;
3084+
if (!p_ss->wl_pointer || !p_ss->cursor_surface) {
3085+
return;
3086+
}
3087+
3088+
// NOTE: Those values are valid by default and will hide the cursor when
3089+
// unchanged.
3090+
struct wl_buffer *cursor_buffer = nullptr;
3091+
uint32_t hotspot_x = 0;
3092+
uint32_t hotspot_y = 0;
3093+
int scale = 1;
30873094

3088-
CustomCursor *custom_cursor = p_ss->wayland_thread->current_custom_cursor;
3089-
struct wl_cursor *wl_cursor = p_ss->wayland_thread->current_wl_cursor;
3095+
if (thread->cursor_visible) {
3096+
DisplayServer::CursorShape shape = thread->cursor_shape;
3097+
3098+
struct CustomCursor *custom_cursor = thread->custom_cursors.getptr(shape);
30903099

30913100
if (custom_cursor) {
30923101
cursor_buffer = custom_cursor->wl_buffer;
@@ -3096,7 +3105,13 @@ void WaylandThread::seat_state_update_cursor(SeatState *p_ss) {
30963105
// We can't really reasonably scale custom cursors, so we'll let the
30973106
// compositor do it for us (badly).
30983107
scale = 1;
3099-
} else if (wl_cursor) {
3108+
} else {
3109+
struct wl_cursor *wl_cursor = thread->wl_cursors[shape];
3110+
3111+
if (!wl_cursor) {
3112+
return;
3113+
}
3114+
31003115
int frame_idx = 0;
31013116

31023117
if (wl_cursor->image_count > 1) {
@@ -3112,24 +3127,24 @@ void WaylandThread::seat_state_update_cursor(SeatState *p_ss) {
31123127

31133128
struct wl_cursor_image *wl_cursor_image = wl_cursor->images[frame_idx];
31143129

3115-
scale = p_ss->wayland_thread->cursor_scale;
3130+
scale = thread->cursor_scale;
31163131

31173132
cursor_buffer = wl_cursor_image_get_buffer(wl_cursor_image);
31183133

31193134
// As the surface's buffer is scaled (thus the surface is smaller) and the
31203135
// hotspot must be expressed in surface-local coordinates, we need to scale
3121-
// them down accordingly.
3136+
// it down accordingly.
31223137
hotspot_x = wl_cursor_image->hotspot_x / scale;
31233138
hotspot_y = wl_cursor_image->hotspot_y / scale;
31243139
}
3140+
}
31253141

3126-
wl_pointer_set_cursor(p_ss->wl_pointer, p_ss->pointer_enter_serial, p_ss->cursor_surface, hotspot_x, hotspot_y);
3127-
wl_surface_set_buffer_scale(p_ss->cursor_surface, scale);
3128-
wl_surface_attach(p_ss->cursor_surface, cursor_buffer, 0, 0);
3129-
wl_surface_damage_buffer(p_ss->cursor_surface, 0, 0, INT_MAX, INT_MAX);
3142+
wl_pointer_set_cursor(p_ss->wl_pointer, p_ss->pointer_enter_serial, p_ss->cursor_surface, hotspot_x, hotspot_y);
3143+
wl_surface_set_buffer_scale(p_ss->cursor_surface, scale);
3144+
wl_surface_attach(p_ss->cursor_surface, cursor_buffer, 0, 0);
3145+
wl_surface_damage_buffer(p_ss->cursor_surface, 0, 0, INT_MAX, INT_MAX);
31303146

3131-
wl_surface_commit(p_ss->cursor_surface);
3132-
}
3147+
wl_surface_commit(p_ss->cursor_surface);
31333148
}
31343149

31353150
void WaylandThread::seat_state_echo_keys(SeatState *p_ss) {
@@ -3770,49 +3785,26 @@ Error WaylandThread::init() {
37703785
return OK;
37713786
}
37723787

3773-
void WaylandThread::cursor_hide() {
3774-
current_wl_cursor = nullptr;
3775-
current_custom_cursor = nullptr;
3776-
3777-
SeatState *ss = wl_seat_get_seat_state(wl_seat_current);
3778-
ERR_FAIL_NULL(ss);
3779-
seat_state_update_cursor(ss);
3780-
}
3781-
3782-
void WaylandThread::cursor_set_shape(DisplayServer::CursorShape p_cursor_shape) {
3783-
if (!wl_cursors[p_cursor_shape]) {
3784-
return;
3785-
}
3786-
3787-
// The point of this method is make the current cursor a "plain" shape and, as
3788-
// the custom cursor overrides what gets set, we have to clear it too.
3789-
current_custom_cursor = nullptr;
3790-
3791-
current_wl_cursor = wl_cursors[p_cursor_shape];
3788+
void WaylandThread::cursor_set_visible(bool p_visible) {
3789+
cursor_visible = p_visible;
37923790

37933791
for (struct wl_seat *wl_seat : registry.wl_seats) {
37943792
SeatState *ss = wl_seat_get_seat_state(wl_seat);
37953793
ERR_FAIL_NULL(ss);
37963794

37973795
seat_state_update_cursor(ss);
37983796
}
3799-
3800-
last_cursor_shape = p_cursor_shape;
38013797
}
38023798

3803-
void WaylandThread::cursor_set_custom_shape(DisplayServer::CursorShape p_cursor_shape) {
3804-
ERR_FAIL_COND(!custom_cursors.has(p_cursor_shape));
3805-
3806-
current_custom_cursor = &custom_cursors[p_cursor_shape];
3799+
void WaylandThread::cursor_set_shape(DisplayServer::CursorShape p_cursor_shape) {
3800+
cursor_shape = p_cursor_shape;
38073801

38083802
for (struct wl_seat *wl_seat : registry.wl_seats) {
38093803
SeatState *ss = wl_seat_get_seat_state(wl_seat);
38103804
ERR_FAIL_NULL(ss);
38113805

38123806
seat_state_update_cursor(ss);
38133807
}
3814-
3815-
last_cursor_shape = p_cursor_shape;
38163808
}
38173809

38183810
void WaylandThread::cursor_shape_set_custom_image(DisplayServer::CursorShape p_cursor_shape, Ref<Image> p_image, const Point2i &p_hotspot) {
@@ -3832,23 +3824,21 @@ void WaylandThread::cursor_shape_set_custom_image(DisplayServer::CursorShape p_c
38323824
CustomCursor &cursor = custom_cursors[p_cursor_shape];
38333825
cursor.hotspot = p_hotspot;
38343826

3827+
if (cursor.wl_buffer) {
3828+
// Clean up the old Wayland buffer.
3829+
wl_buffer_destroy(cursor.wl_buffer);
3830+
}
3831+
38353832
if (cursor.buffer_data) {
38363833
// Clean up the old buffer data.
38373834
munmap(cursor.buffer_data, cursor.buffer_data_size);
38383835
}
38393836

3840-
// NOTE: From `wl_keyboard`s of version 7 or later, the spec requires the mmap
3841-
// operation to be done with MAP_PRIVATE, as "MAP_SHARED may fail". We'll do it
3842-
// regardless of global version.
3843-
cursor.buffer_data = (uint32_t *)mmap(nullptr, data_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
3844-
3845-
if (cursor.wl_buffer) {
3846-
// Clean up the old Wayland buffer.
3847-
wl_buffer_destroy(cursor.wl_buffer);
3848-
}
3837+
cursor.buffer_data = (uint32_t *)mmap(nullptr, data_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
3838+
cursor.buffer_data_size = data_size;
38493839

38503840
// Create the Wayland buffer.
3851-
struct wl_shm_pool *wl_shm_pool = wl_shm_create_pool(registry.wl_shm, fd, image_size.height * data_size);
3841+
struct wl_shm_pool *wl_shm_pool = wl_shm_create_pool(registry.wl_shm, fd, data_size);
38523842
// TODO: Make sure that WL_SHM_FORMAT_ARGB8888 format is supported. It
38533843
// technically isn't garaunteed to be supported, but I think that'd be a
38543844
// pretty unlikely thing to stumble upon.
@@ -3876,8 +3866,6 @@ void WaylandThread::cursor_shape_clear_custom_image(DisplayServer::CursorShape p
38763866
CustomCursor cursor = custom_cursors[p_cursor_shape];
38773867
custom_cursors.erase(p_cursor_shape);
38783868

3879-
current_custom_cursor = nullptr;
3880-
38813869
if (cursor.wl_buffer) {
38823870
wl_buffer_destroy(cursor.wl_buffer);
38833871
}

platform/linuxbsd/wayland/wayland_thread.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,6 @@ class WaylandThread {
469469
uint32_t *buffer_data = nullptr;
470470
uint32_t buffer_data_size = 0;
471471

472-
RID rid;
473472
Point2i hotspot;
474473
};
475474

@@ -506,10 +505,8 @@ class WaylandThread {
506505

507506
HashMap<DisplayServer::CursorShape, CustomCursor> custom_cursors;
508507

509-
struct wl_cursor *current_wl_cursor = nullptr;
510-
struct CustomCursor *current_custom_cursor = nullptr;
511-
512-
DisplayServer::CursorShape last_cursor_shape = DisplayServer::CURSOR_ARROW;
508+
DisplayServer::CursorShape cursor_shape = DisplayServer::CURSOR_ARROW;
509+
bool cursor_visible = true;
513510

514511
PointerConstraint pointer_constraint = PointerConstraint::NONE;
515512

@@ -962,7 +959,7 @@ class WaylandThread {
962959
DisplayServer::WindowID pointer_get_pointed_window_id() const;
963960
BitField<MouseButtonMask> pointer_get_button_mask() const;
964961

965-
void cursor_hide();
962+
void cursor_set_visible(bool p_visible);
966963
void cursor_set_shape(DisplayServer::CursorShape p_cursor_shape);
967964

968965
void cursor_set_custom_shape(DisplayServer::CursorShape p_cursor_shape);

0 commit comments

Comments
 (0)