Skip to content

Commit 92f44da

Browse files
committed
input/seatop_default: handle continuous scroll events
The implementation is similar to how swaybar handles these events, except that swaybar does it in a pointer frame event handler. Fixes #8014
1 parent 0e19d85 commit 92f44da

File tree

3 files changed

+38
-1
lines changed

3 files changed

+38
-1
lines changed

include/sway/input/cursor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "sway/input/seat.h"
99
#include "config.h"
1010

11+
#define SWAY_CONTINUOUS_SCROLL_TIMEOUT 1000
1112
#define SWAY_CURSOR_PRESSED_BUTTONS_CAP 32
1213

1314
#define SWAY_SCROLL_UP KEY_MAX + 1

include/sway/input/seat.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,15 @@ struct sway_drag {
8080
struct wl_listener destroy;
8181
};
8282

83+
struct sway_scroll_axis {
84+
double value;
85+
uint32_t time_msec;
86+
};
87+
8388
struct sway_seat {
8489
struct wlr_seat *wlr_seat;
8590
struct sway_cursor *cursor;
91+
struct sway_scroll_axis axis[2];
8692

8793
// Seat scene tree structure
8894
// - scene_tree

sway/input/seatop_default.c

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,35 @@ static uint32_t wl_axis_to_button(struct wlr_pointer_axis_event *event) {
702702
}
703703
}
704704

705+
static int calc_scroll_steps(struct sway_seat *seat,
706+
struct wlr_pointer_axis_event *event, float scroll_factor) {
707+
if (event->delta_discrete) {
708+
return roundf(scroll_factor * event->delta_discrete /
709+
WLR_POINTER_AXIS_DISCRETE_STEP);
710+
}
711+
if (!sway_assert(event->orientation < 2, "axis out of range")) {
712+
return 0;
713+
}
714+
715+
struct sway_scroll_axis *axis = &seat->axis[event->orientation];
716+
if (event->time_msec - axis->time_msec > SWAY_CONTINUOUS_SCROLL_TIMEOUT) {
717+
axis->value = 0;
718+
}
719+
720+
axis->value += event->delta;
721+
axis->time_msec = event->time_msec;
722+
if (axis->value > WLR_POINTER_AXIS_DISCRETE_STEP) {
723+
axis->value -= WLR_POINTER_AXIS_DISCRETE_STEP;
724+
return 1;
725+
}
726+
if (axis->value < -WLR_POINTER_AXIS_DISCRETE_STEP) {
727+
axis->value += WLR_POINTER_AXIS_DISCRETE_STEP;
728+
return -1;
729+
}
730+
731+
return 0;
732+
}
733+
705734
static void handle_pointer_axis(struct sway_seat *seat,
706735
struct wlr_pointer_axis_event *event) {
707736
struct sway_input_device *input_device =
@@ -758,8 +787,9 @@ static void handle_pointer_axis(struct sway_seat *seat,
758787
struct sway_node *active =
759788
seat_get_active_tiling_child(seat, tabcontainer);
760789
list_t *siblings = container_get_siblings(cont);
790+
761791
int desired = list_find(siblings, active->sway_container) +
762-
roundf(scroll_factor * event->delta_discrete / WLR_POINTER_AXIS_DISCRETE_STEP);
792+
calc_scroll_steps(seat, event, scroll_factor);
763793
if (desired < 0) {
764794
desired = 0;
765795
} else if (desired >= siblings->length) {

0 commit comments

Comments
 (0)