diff --git a/input.c b/input.c index 6112be86..93bdc9fd 100644 --- a/input.c +++ b/input.c @@ -410,37 +410,54 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, } } +static void +mouse_scroll(struct terminal *term, int amount) +{ + int button = amount < 0 ? BTN_BACK : BTN_FORWARD; + + void (*scrollback)(struct terminal *term, int rows) + = amount < 0 ? &cmd_scrollback_up : &cmd_scrollback_down; + + amount = abs(amount); + + for (int i = 0; i < amount; i++) + term_mouse_down(term, button, term->mouse.row, term->mouse.col, + term->kbd.shift, term->kbd.alt, term->kbd.ctrl); + + scrollback(term, amount); +} + static void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value) { - struct terminal *term = data; - - /* TODO: generate button event for BTN_FORWARD/BTN_BACK? */ - if (axis != WL_POINTER_AXIS_VERTICAL_SCROLL) return; - int amount = wl_fixed_to_int(value); + struct terminal *term = data; + if (term->mouse.have_discrete) + return; - if (amount < 0) { - for (int i = 0; i < -amount; i++) { - term_mouse_down(term, BTN_BACK, term->mouse.row, term->mouse.col, - term->kbd.shift, term->kbd.alt, term->kbd.ctrl); - } - cmd_scrollback_up(term, -amount); - } else { - for (int i = 0; i < amount; i++) { - term_mouse_down(term, BTN_FORWARD, term->mouse.row, term->mouse.col, - term->kbd.shift, term->kbd.alt, term->kbd.ctrl); - } - cmd_scrollback_down(term, amount); - } + mouse_scroll(term, wl_fixed_to_int(value)); +} + +static void +wl_pointer_axis_discrete(void *data, struct wl_pointer *wl_pointer, + uint32_t axis, int32_t discrete) +{ + if (axis != WL_POINTER_AXIS_VERTICAL_SCROLL) + return; + + struct terminal *term = data; + term->mouse.have_discrete = true; + mouse_scroll(term, discrete); } static void wl_pointer_frame(void *data, struct wl_pointer *wl_pointer) { + struct terminal *term = data; + term->mouse.have_discrete = false; } static void @@ -455,12 +472,6 @@ wl_pointer_axis_stop(void *data, struct wl_pointer *wl_pointer, { } -static void -wl_pointer_axis_discrete(void *data, struct wl_pointer *wl_pointer, - uint32_t axis, int32_t discrete) -{ -} - const struct wl_pointer_listener pointer_listener = { .enter = wl_pointer_enter, .leave = wl_pointer_leave, diff --git a/main.c b/main.c index 5968a14c..8248e28a 100644 --- a/main.c +++ b/main.c @@ -125,7 +125,7 @@ handle_global(void *data, struct wl_registry *registry, else if (strcmp(interface, wl_seat_interface.name) == 0) { term->wl.seat = wl_registry_bind( - term->wl.registry, name, &wl_seat_interface, 4); + term->wl.registry, name, &wl_seat_interface, 5); wl_seat_add_listener(term->wl.seat, &seat_listener, term); wl_display_roundtrip(term->wl.display); } diff --git a/terminal.h b/terminal.h index c6227d26..1971d3f4 100644 --- a/terminal.h +++ b/terminal.h @@ -288,6 +288,9 @@ struct terminal { int last_button; struct timeval last_time; + + /* We used a discrete axis event in the current pointer frame */ + bool have_discrete; } mouse; struct coord cursor;