From 94c5e361fbb229b0cd6853e2102a7d95f1f358b3 Mon Sep 17 00:00:00 2001 From: Berke Güzel Date: Mon, 12 Oct 2026 22:12:02 +0300 Subject: better public interface and doxygen --- src/wayland/pointer.c | 126 ++++++++++++++++---------------------------------- 1 file changed, 39 insertions(+), 87 deletions(-) (limited to 'src/wayland/pointer.c') diff --git a/src/wayland/pointer.c b/src/wayland/pointer.c index 065669f..90b7ecc 100644 --- a/src/wayland/pointer.c +++ b/src/wayland/pointer.c @@ -109,12 +109,12 @@ static void report_mouse(struct seat *s, struct wayland_surface *w, struct yasl_ }); } -static void report_wheel(struct seat *s, struct wayland_surface *w, struct yasl_vector2i pos, - int button, int lines, float delta) +static void report_wheel(struct seat *s, struct wayland_surface *w, + struct yasl_vector2i pos, double x, double y) { + if ((x == 0 && y == 0) || !isfinite(x) || !isfinite(y)) return; push_mouse(s, w, (struct yasl_mouse_event){ - .pos = pos, .button = button, .kind = YASL_PTR_SCROLL, - .scroll_lines = lines, .scroll_delta = delta, + .pos = pos, .kind = YASL_PTR_SCROLL, .scroll = {x, y}, }); } @@ -295,12 +295,11 @@ void seat_pointer_reset(struct seat *s) s->pointer_buttons = 0; s->pointer_serial = 0; s->motion_pending = false; - s->axis_v = s->axis_h = s->frame_v = 0; - s->frame_v120 = 0; - s->axis_discrete_v = s->axis_discrete_h = 0; - s->axis_value120_v = s->axis_value120_h = 0; - s->axis_has_v120_v = s->axis_has_v120_h = false; - s->axis_smooth = false; + memset(s->axis, 0, sizeof(s->axis)); + memset(s->axis_value120, 0, sizeof(s->axis_value120)); + memset(s->axis_discrete, 0, sizeof(s->axis_discrete)); + memset(s->axis_has_value120, 0, sizeof(s->axis_has_value120)); + memset(s->axis_has_discrete, 0, sizeof(s->axis_has_discrete)); s->cursor_shape = -1; } @@ -405,8 +404,7 @@ static void pointer_axis(void *data, struct wl_pointer *pointer, if (unlikely(!s->pointer_focus)) return; double v = wl_fixed_to_double(value); if (likely(axis < 2)) { - (&s->axis_v)[axis] += v; - s->frame_v += v * (!axis); + s->axis[axis] += v; } pointer_event_done(s); } @@ -414,81 +412,49 @@ static void pointer_axis(void *data, struct wl_pointer *pointer, static void pointer_axis_source(void *data, struct wl_pointer *pointer, uint32_t axis_source) { (void)pointer; - struct seat *s = data; - s->axis_smooth = (axis_source == WL_POINTER_AXIS_SOURCE_FINGER || - axis_source == WL_POINTER_AXIS_SOURCE_CONTINUOUS); + (void)data; (void)axis_source; } static void pointer_axis_stop(void *data, struct wl_pointer *pointer, uint32_t time, uint32_t axis) { - (void)pointer; (void)time; - struct seat *s = data; - if (likely(axis < 2)) { - (&s->axis_value120_v)[axis] = 0; - (&s->axis_has_v120_v)[axis] = false; - } + /* A stop ends a gesture, not the offsets already received in this frame. */ + (void)data; (void)pointer; (void)time; (void)axis; } static void pointer_axis_discrete(void *data, struct wl_pointer *pointer, uint32_t axis, int32_t discrete) { (void)pointer; struct seat *s = data; - if (likely(axis < 2)) - (&s->axis_discrete_v)[axis] += discrete; + if (axis < 2) { + s->axis_discrete[axis] += discrete; + s->axis_has_discrete[axis] = true; + } } static void pointer_axis_value120(void *data, struct wl_pointer *pointer, uint32_t axis, int32_t value120) { (void)pointer; struct seat *s = data; - if (likely(axis < 2)) { - (&s->axis_value120_v)[axis] += value120; - (&s->axis_has_v120_v)[axis] = true; - s->frame_v120 += value120 * (!axis); + if (axis < 2) { + s->axis_value120[axis] += value120; + s->axis_has_value120[axis] = true; } } -static void pointer_frame_vertical(struct seat *s, struct wayland_surface *w) -{ - if (s->axis_has_v120_v) { - int discrete = s->axis_value120_v / 120; - s->axis_value120_v -= discrete * 120; - float delta = -(float)s->frame_v120 / 120.0f; - int btn = discrete ? (discrete < 0 ? 4 : 5) : (delta > 0 ? 4 : 5); - if (discrete || delta != 0.0f) - report_wheel(s, w, s->pointer_pos, btn, -discrete, delta); - s->axis_v = 0; - } else if (s->axis_discrete_v) { - report_wheel(s, w, s->pointer_pos, s->axis_discrete_v > 0 ? 5 : 4, -s->axis_discrete_v, 0.0f); - s->axis_v = 0; - } else if (s->frame_v != 0.0) { - int lines = -(int)(s->axis_v / SCROLL_PX_PER_LINE); - s->axis_v += (double)lines * SCROLL_PX_PER_LINE; - float delta = (float)(-s->frame_v / SCROLL_PX_PER_LINE); - report_wheel(s, w, s->pointer_pos, delta > 0 ? 4 : 5, lines, delta); - } - s->frame_v = 0; - s->frame_v120 = 0; -} - -static void pointer_frame_horizontal(struct seat *s, struct wayland_surface *w) -{ - if (s->axis_has_v120_h) { - int discrete = s->axis_value120_h / 120; - s->axis_value120_h -= discrete * 120; - if (discrete) - report_wheel(s, w, s->pointer_pos, discrete > 0 ? 7 : 6, discrete, 0.0f); - s->axis_h = 0; - } else if (s->axis_discrete_h) { - report_wheel(s, w, s->pointer_pos, s->axis_discrete_h > 0 ? 7 : 6, s->axis_discrete_h, 0.0f); - s->axis_h = 0; - } else if (s->axis_h) { - int steps = (int)(s->axis_h / SCROLL_PX_PER_LINE); - if (steps != 0) { - s->axis_h -= (double)steps * SCROLL_PX_PER_LINE; - report_wheel(s, w, s->pointer_pos, steps > 0 ? 7 : 6, steps, 0.0f); - } +static void pointer_frame_scroll(struct seat *s, struct wayland_surface *w) +{ + double lines[2]; + for (int axis = 0; axis < 2; axis++) { + /* A wheel may provide all three representations. Pick one, never sum + * them. value120 preserves high-resolution detents on both axes. */ + lines[axis] = s->axis_has_value120[axis] ? s->axis_value120[axis] / 120.0 : + s->axis_has_discrete[axis] ? (double)s->axis_discrete[axis] : + s->axis[axis] / SCROLL_PX_PER_LINE; + s->axis[axis] = s->axis_value120[axis] = 0; + s->axis_discrete[axis] = 0; + s->axis_has_value120[axis] = s->axis_has_discrete[axis] = false; } + report_wheel(s, w, s->pointer_pos, lines[1], lines[0]); } static void pointer_frame(void *data, struct wl_pointer *pointer) @@ -521,18 +487,7 @@ static void pointer_frame(void *data, struct wl_pointer *pointer) flush_pending_motion(s, w); press_queue_flush(s, &s->ptr_presses, NULL, &s->pointer_buttons, (struct yasl_mouse_event){0}); - if (s->axis_smooth) { - if (!s->axis_has_v120_v) s->axis_value120_v = 0; - if (!s->axis_has_v120_h) s->axis_value120_h = 0; - s->axis_smooth = false; - } - pointer_frame_vertical(s, w); - pointer_frame_horizontal(s, w); - - s->axis_discrete_v = 0; - s->axis_discrete_h = 0; - s->axis_has_v120_v = false; - s->axis_has_v120_h = false; + pointer_frame_scroll(s, w); } static void pointer_axis_relative_direction(void *data, struct wl_pointer *pointer, uint32_t axis, uint32_t direction) @@ -651,20 +606,15 @@ static void touch_frame(void *data, struct wl_touch *touch) s->touch_pressed = false; s->touch_scrolling = true; s->touch_scroll_y = centroid_n ? centroid_sum / centroid_n : 0; - s->touch_scroll_rest = 0; } else if (s->touch_scrolling && primary && active_n >= 2) { double y = centroid_n ? centroid_sum / centroid_n : 0; double dy = y - s->touch_scroll_y; s->touch_scroll_y = y; if (dy != 0.0) { double lines = dy / SCROLL_PX_PER_LINE; - s->touch_scroll_rest += lines; - int whole = (int)s->touch_scroll_rest; - s->touch_scroll_rest -= whole; push_mouse(s, primary->surface, (struct yasl_mouse_event){ - .pos = touch_pos(primary), .button = lines > 0 ? 4 : 5, - .kind = YASL_PTR_SCROLL, .scroll_lines = whole, - .scroll_delta = (float)lines, .device = YASL_PTR_DEV_TOUCH, + .pos = touch_pos(primary), .kind = YASL_PTR_SCROLL, + .scroll = {0, -lines}, .device = YASL_PTR_DEV_TOUCH, }); } } else if (primary && primary->moved && s->touch_pressed) { @@ -870,7 +820,7 @@ static void tool_frame(void *d, struct zwp_tablet_tool_v2 *t, uint32_t time) struct yasl_mouse_event ev = like; ev.pos = s->tool_pos; ev.kind = YASL_PTR_SCROLL; - ev.scroll_lines = -s->tool_wheel; + ev.scroll.y = s->tool_wheel; push_mouse(s, w, ev); s->tool_wheel = 0; } @@ -1105,6 +1055,7 @@ static void seat_drop_pointer(struct seat *s) static void seat_drop_keyboard(struct seat *s) { keyboard_repeat_stop(s); + keyboard_text_reset(s); if (s->keyboard) { if (wl_keyboard_get_version(s->keyboard) >= WL_KEYBOARD_RELEASE_SINCE_VERSION) wl_keyboard_release(s->keyboard); @@ -1281,6 +1232,7 @@ void seat_destroy(struct seat *s) if (s->cursor_viewport) wp_viewport_destroy(s->cursor_viewport); if (s->cursor_surface) wl_surface_destroy(s->cursor_surface); if (s->xkb_state) xkb_state_unref(s->xkb_state); + if (s->compose) xkb_compose_state_unref(s->compose); if (s->xkb_keymap) xkb_keymap_unref(s->xkb_keymap); if (s->proxy) { if (wl_seat_get_version(s->proxy) >= WL_SEAT_RELEASE_SINCE_VERSION) -- cgit v1.2.3