aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--types/seat/wlr_seat_pointer.c73
1 files changed, 42 insertions, 31 deletions
diff --git a/types/seat/wlr_seat_pointer.c b/types/seat/wlr_seat_pointer.c
index 7d37fb12..36ce42b3 100644
--- a/types/seat/wlr_seat_pointer.c
+++ b/types/seat/wlr_seat_pointer.c
@@ -279,10 +279,17 @@ static bool should_reset_value120_accumulators(int32_t current, int32_t last) {
static void update_value120_accumulators(struct wlr_seat_client *client,
enum wlr_axis_orientation orientation,
- double value, int32_t value_discrete) {
+ double value, int32_t value_discrete,
+ double *low_res_value, int32_t *low_res_value_discrete) {
+ if (value_discrete == 0) {
+ // Continuous scrolling has no effect on accumulators
+ return;
+ }
+
int32_t *acc_discrete = &client->value120.acc_discrete[orientation];
int32_t *last_discrete = &client->value120.last_discrete[orientation];
double *acc_axis = &client->value120.acc_axis[orientation];
+
if (should_reset_value120_accumulators(value_discrete, *last_discrete)) {
*acc_discrete = 0;
*acc_axis = 0;
@@ -290,33 +297,17 @@ static void update_value120_accumulators(struct wlr_seat_client *client,
*acc_discrete += value_discrete;
*last_discrete = value_discrete;
*acc_axis += value;
-}
-static void send_axis_discrete(struct wlr_seat_client *client,
- struct wl_resource *resource, uint32_t time,
- enum wlr_axis_orientation orientation, double value,
- int32_t value_discrete) {
- int32_t *acc_discrete = &client->value120.acc_discrete[orientation];
- double *acc_axis = &client->value120.acc_axis[orientation];
-
- if (abs(*acc_discrete) < WLR_POINTER_AXIS_DISCRETE_STEP) {
- return;
+ // Compute low resolution event values for older clients and reset
+ // the accumulators if needed
+ *low_res_value_discrete = *acc_discrete / WLR_POINTER_AXIS_DISCRETE_STEP;
+ if (*low_res_value_discrete == 0) {
+ *low_res_value = 0;
+ } else {
+ *acc_discrete -= *low_res_value_discrete * WLR_POINTER_AXIS_DISCRETE_STEP;
+ *low_res_value = *acc_axis;
+ *acc_axis = 0;
}
-
- wl_pointer_send_axis_discrete(resource, orientation,
- *acc_discrete / WLR_POINTER_AXIS_DISCRETE_STEP);
- wl_pointer_send_axis(resource, time, orientation,
- wl_fixed_from_double(*acc_axis));
- *acc_discrete %= WLR_POINTER_AXIS_DISCRETE_STEP;
- *acc_axis = 0;
-}
-
-static void send_axis_value120(struct wl_resource *resource, uint32_t time,
- enum wlr_axis_orientation orientation, double value,
- int32_t value_discrete) {
- wl_pointer_send_axis_value120(resource, orientation, value_discrete);
- wl_pointer_send_axis(resource, time, orientation,
- wl_fixed_from_double(value));
}
void wlr_seat_pointer_send_axis(struct wlr_seat *wlr_seat, uint32_t time,
@@ -336,7 +327,10 @@ void wlr_seat_pointer_send_axis(struct wlr_seat *wlr_seat, uint32_t time,
send_source = true;
}
- update_value120_accumulators(client, orientation, value, value_discrete);
+ double low_res_value;
+ int32_t low_res_value_discrete;
+ update_value120_accumulators(client, orientation, value, value_discrete,
+ &low_res_value, &low_res_value_discrete);
struct wl_resource *resource;
wl_resource_for_each(resource, &client->pointers) {
@@ -346,19 +340,36 @@ void wlr_seat_pointer_send_axis(struct wlr_seat *wlr_seat, uint32_t time,
uint32_t version = wl_resource_get_version(resource);
+ if (version < WL_POINTER_AXIS_VALUE120_SINCE_VERSION &&
+ value_discrete != 0 && low_res_value_discrete == 0) {
+ // The client doesn't support high resolution discrete scrolling
+ // and we haven't accumulated enough wheel clicks for a single
+ // low resolution event. Don't send anything.
+ continue;
+ }
+
if (send_source && version >= WL_POINTER_AXIS_SOURCE_SINCE_VERSION) {
wl_pointer_send_axis_source(resource, source);
}
if (value) {
if (value_discrete) {
if (version >= WL_POINTER_AXIS_VALUE120_SINCE_VERSION) {
- send_axis_value120(resource, time, orientation, value,
+ // High resolution discrete scrolling
+ wl_pointer_send_axis_value120(resource, orientation,
value_discrete);
- } else if (version >= WL_POINTER_AXIS_DISCRETE_SINCE_VERSION) {
- send_axis_discrete(client, resource, time, orientation,
- value, value_discrete);
+ wl_pointer_send_axis(resource, time, orientation,
+ wl_fixed_from_double(value));
+ } else {
+ // Low resolution discrete scrolling
+ if (version >= WL_POINTER_AXIS_DISCRETE_SINCE_VERSION) {
+ wl_pointer_send_axis_discrete(resource, orientation,
+ low_res_value_discrete);
+ }
+ wl_pointer_send_axis(resource, time, orientation,
+ wl_fixed_from_double(low_res_value));
}
} else {
+ // Continuous scrolling
wl_pointer_send_axis(resource, time, orientation,
wl_fixed_from_double(value));
}