summaryrefslogtreecommitdiff
path: root/src/wayland/pointer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/wayland/pointer.c')
-rw-r--r--src/wayland/pointer.c66
1 files changed, 31 insertions, 35 deletions
diff --git a/src/wayland/pointer.c b/src/wayland/pointer.c
index 5924eb1..065669f 100644
--- a/src/wayland/pointer.c
+++ b/src/wayland/pointer.c
@@ -248,8 +248,9 @@ static void press_queue_flush(struct seat *s, struct press_queue *q,
struct yasl_mouse_event like)
{
int kept = 0;
- for (int i = 0; i < q->n; i++) {
- struct pending_press p = q->ev[i];
+ int count = q->n;
+ for (int i = 0; i < count; i++) {
+ struct pending_press p = q->ev[(q->head + i) & 7];
if (only && p.surface != only) {
q->ev[kept++] = p;
continue;
@@ -263,26 +264,30 @@ static void press_queue_flush(struct seat *s, struct press_queue *q,
ev.kind = (enum yasl_pointer_kind)p.release;
push_mouse(s, p.surface, ev);
}
+ q->head = 0;
q->n = kept;
}
static void press_queue_push(struct press_queue *q, struct wayland_surface *w,
struct yasl_vector2i pos, int button, bool release)
{
- if (q->n == (int)(sizeof(q->ev) / sizeof(q->ev[0]))) {
- memmove(q->ev, q->ev + 1, sizeof(q->ev[0]) * (size_t)(q->n - 1));
+ if (q->n == 8) {
+ q->head = (q->head + 1) & 7;
q->n--;
}
- q->ev[q->n++] = (struct pending_press){
+ q->ev[(q->head + q->n) & 7] = (struct pending_press){
.surface = w, .pos = pos, .button = button, .release = release,
};
+ q->n++;
}
static void press_queue_forget(struct press_queue *q, struct wayland_surface *w)
{
- for (int i = 0; i < q->n; i++)
- if (q->ev[i].surface == w)
- q->ev[i].surface = NULL;
+ for (int i = 0; i < q->n; i++) {
+ int idx = (q->head + i) & 7;
+ if (q->ev[idx].surface == w)
+ q->ev[idx].surface = NULL;
+ }
}
void seat_pointer_reset(struct seat *s)
@@ -566,28 +571,7 @@ static struct yasl_vector2i touch_pos(const struct touch_point *p)
};
}
-static int touch_count(const struct seat *s)
-{
- int n = 0;
- for (int i = 0; i < SEAT_TOUCH_POINTS; i++)
- if (s->touch_points[i].active && !s->touch_points[i].up)
- n++;
- return n;
-}
-static double touch_centroid_y(const struct seat *s, const struct wayland_surface *on)
-{
- double sum = 0;
- int n = 0;
- for (int i = 0; i < SEAT_TOUCH_POINTS; i++) {
- const struct touch_point *p = &s->touch_points[i];
- if (p->active && !p->up && p->surface == on) {
- sum += p->y;
- n++;
- }
- }
- return n ? sum / n : 0;
-}
static void touch_report(struct seat *s, struct touch_point *p, int button,
enum yasl_pointer_kind kind)
@@ -641,24 +625,35 @@ static void touch_frame(void *data, struct wl_touch *touch)
{
(void)touch;
struct seat *s = data;
+ int active_n = 0;
+ double centroid_sum = 0;
+ int centroid_n = 0;
for (int i = 0; i < SEAT_TOUCH_POINTS; i++) {
struct touch_point *p = &s->touch_points[i];
- if (p->active && p->down && !s->touch_primary && !s->touch_scrolling) {
+ if (!p->active) continue;
+ if (p->down && !s->touch_primary && !s->touch_scrolling) {
s->touch_primary = p;
s->touch_pressed = true;
touch_report(s, p, 0, YASL_PTR_PRESS);
}
+ if (!p->up) {
+ active_n++;
+ if (s->touch_primary && p->surface == s->touch_primary->surface) {
+ centroid_sum += p->y;
+ centroid_n++;
+ }
+ }
}
struct touch_point *primary = s->touch_primary;
- if (primary && !s->touch_scrolling && touch_count(s) >= 2) {
+ if (primary && !s->touch_scrolling && active_n >= 2) {
if (s->touch_pressed)
touch_report(s, primary, 0, YASL_PTR_RELEASE);
s->touch_pressed = false;
s->touch_scrolling = true;
- s->touch_scroll_y = touch_centroid_y(s, primary->surface);
+ s->touch_scroll_y = centroid_n ? centroid_sum / centroid_n : 0;
s->touch_scroll_rest = 0;
- } else if (s->touch_scrolling && primary && touch_count(s) >= 2) {
- double y = touch_centroid_y(s, primary->surface);
+ } 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) {
@@ -679,6 +674,7 @@ static void touch_frame(void *data, struct wl_touch *touch)
struct touch_point *p = &s->touch_points[i];
if (!p->active) continue;
if (p->up) {
+ active_n--;
if (p == s->touch_primary) {
if (s->touch_pressed)
touch_report(s, p, 0, YASL_PTR_RELEASE);
@@ -690,7 +686,7 @@ static void touch_frame(void *data, struct wl_touch *touch)
p->down = p->moved = false;
}
}
- if (!touch_count(s))
+ if (active_n <= 0)
s->touch_scrolling = false;
}