aboutsummaryrefslogtreecommitdiffstats
path: root/swaybar
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2019-02-17 10:13:11 -0500
committerLibravatar emersion <contact@emersion.fr>2019-02-23 20:00:20 +0100
commit4599907de7af4f5b6335399644b47f4be91bd949 (patch)
tree6b68209ad3fd571f621870ba7b7fef680172c7e4 /swaybar
parentMerge pull request #3700 from emersion/refactor-dnd (diff)
downloadsway-4599907de7af4f5b6335399644b47f4be91bd949.tar.gz
sway-4599907de7af4f5b6335399644b47f4be91bd949.tar.zst
sway-4599907de7af4f5b6335399644b47f4be91bd949.zip
swaybar: process hotspots on touch tap
Diffstat (limited to 'swaybar')
-rw-r--r--swaybar/input.c139
1 files changed, 124 insertions, 15 deletions
diff --git a/swaybar/input.c b/swaybar/input.c
index e416f6e7..d443c777 100644
--- a/swaybar/input.c
+++ b/swaybar/input.c
@@ -123,6 +123,23 @@ static bool check_bindings(struct swaybar *bar, uint32_t button,
123 return false; 123 return false;
124} 124}
125 125
126static void process_hotspots(struct swaybar_output *output,
127 double x, double y, uint32_t button) {
128 x *= output->scale;
129 y *= output->scale;
130 struct swaybar_hotspot *hotspot;
131 wl_list_for_each(hotspot, &output->hotspots, link) {
132 if (x >= hotspot->x && y >= hotspot->y
133 && x < hotspot->x + hotspot->width
134 && y < hotspot->y + hotspot->height) {
135 if (HOTSPOT_IGNORE == hotspot->callback(output, hotspot,
136 x / output->scale, y / output->scale, button, hotspot->data)) {
137 return;
138 }
139 }
140 }
141}
142
126static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer, 143static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
127 uint32_t serial, uint32_t time, uint32_t button, uint32_t state) { 144 uint32_t serial, uint32_t time, uint32_t button, uint32_t state) {
128 struct swaybar *bar = data; 145 struct swaybar *bar = data;
@@ -139,20 +156,7 @@ static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
139 if (state != WL_POINTER_BUTTON_STATE_PRESSED) { 156 if (state != WL_POINTER_BUTTON_STATE_PRESSED) {
140 return; 157 return;
141 } 158 }
142 struct swaybar_hotspot *hotspot; 159 process_hotspots(output, pointer->x, pointer->y, button);
143 wl_list_for_each(hotspot, &output->hotspots, link) {
144 double x = pointer->x * output->scale;
145 double y = pointer->y * output->scale;
146 if (x >= hotspot->x
147 && y >= hotspot->y
148 && x < hotspot->x + hotspot->width
149 && y < hotspot->y + hotspot->height) {
150 if (HOTSPOT_IGNORE == hotspot->callback(output, hotspot,
151 pointer->x, pointer->y, button, hotspot->data)) {
152 return;
153 }
154 }
155 }
156} 160}
157 161
158static void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, 162static void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer,
@@ -255,7 +259,7 @@ static void wl_pointer_axis_discrete(void *data, struct wl_pointer *wl_pointer,
255 // Who cares 259 // Who cares
256} 260}
257 261
258struct wl_pointer_listener pointer_listener = { 262static struct wl_pointer_listener pointer_listener = {
259 .enter = wl_pointer_enter, 263 .enter = wl_pointer_enter,
260 .leave = wl_pointer_leave, 264 .leave = wl_pointer_leave,
261 .motion = wl_pointer_motion, 265 .motion = wl_pointer_motion,
@@ -267,6 +271,107 @@ struct wl_pointer_listener pointer_listener = {
267 .axis_discrete = wl_pointer_axis_discrete, 271 .axis_discrete = wl_pointer_axis_discrete,
268}; 272};
269 273
274static struct touch_slot *get_touch_slot(struct swaybar_touch *touch, int32_t id) {
275 int next = -1;
276 for (size_t i = 0; i < sizeof(touch->slots) / sizeof(*touch->slots); ++i) {
277 if (touch->slots[i].id == id) {
278 return &touch->slots[i];
279 }
280 if (next == -1 && !touch->slots[i].output) {
281 next = i;
282 }
283 }
284 if (next == -1) {
285 sway_log(SWAY_ERROR, "Ran out of touch slots");
286 return NULL;
287 }
288 return &touch->slots[next];
289}
290
291static void wl_touch_down(void *data, struct wl_touch *wl_touch,
292 uint32_t serial, uint32_t time, struct wl_surface *surface,
293 int32_t id, wl_fixed_t _x, wl_fixed_t _y) {
294 struct swaybar *bar = data;
295 struct swaybar_output *_output, *output;
296 wl_list_for_each(_output, &bar->outputs, link) {
297 if (_output->surface == surface) {
298 output = _output;
299 break;
300 }
301 }
302 if (!output) {
303 sway_log(SWAY_DEBUG, "Got touch event for unknown surface");
304 return;
305 }
306 struct touch_slot *slot = get_touch_slot(&bar->touch, id);
307 if (!slot) {
308 return;
309 }
310 slot->id = id;
311 slot->output = output;
312 slot->x = slot->start_x = wl_fixed_to_double(_x);
313 slot->y = slot->start_y = wl_fixed_to_double(_y);
314 slot->time = time;
315}
316
317static void wl_touch_up(void *data, struct wl_touch *wl_touch,
318 uint32_t serial, uint32_t time, int32_t id) {
319 struct swaybar *bar = data;
320 struct touch_slot *slot = get_touch_slot(&bar->touch, id);
321 if (!slot) {
322 return;
323 }
324 if (time - slot->time < 500) {
325 // Tap, treat it like a pointer click
326 process_hotspots(slot->output, slot->x, slot->y, BTN_LEFT);
327 }
328 slot->output = NULL;
329}
330
331static void wl_touch_motion(void *data, struct wl_touch *wl_touch,
332 uint32_t time, int32_t id, wl_fixed_t x, wl_fixed_t y) {
333 struct swaybar *bar = data;
334 struct touch_slot *slot = get_touch_slot(&bar->touch, id);
335 if (!slot) {
336 return;
337 }
338 slot->x = wl_fixed_to_double(x);
339 slot->y = wl_fixed_to_double(y);
340 // TODO: Slide gestures
341}
342
343static void wl_touch_frame(void *data, struct wl_touch *wl_touch) {
344 // Who cares
345}
346
347static void wl_touch_cancel(void *data, struct wl_touch *wl_touch) {
348 struct swaybar *bar = data;
349 struct swaybar_touch *touch = &bar->touch;
350 for (size_t i = 0; i < sizeof(touch->slots) / sizeof(*touch->slots); ++i) {
351 touch->slots[i].output = NULL;
352 }
353}
354
355static void wl_touch_shape(void *data, struct wl_touch *wl_touch, int32_t id,
356 wl_fixed_t major, wl_fixed_t minor) {
357 // Who cares
358}
359
360static void wl_touch_orientation(void *data, struct wl_touch *wl_touch,
361 int32_t id, wl_fixed_t orientation) {
362 // Who cares
363}
364
365static struct wl_touch_listener touch_listener = {
366 .down = wl_touch_down,
367 .up = wl_touch_up,
368 .motion = wl_touch_motion,
369 .frame = wl_touch_frame,
370 .cancel = wl_touch_cancel,
371 .shape = wl_touch_shape,
372 .orientation = wl_touch_orientation,
373};
374
270static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, 375static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
271 enum wl_seat_capability caps) { 376 enum wl_seat_capability caps) {
272 struct swaybar *bar = data; 377 struct swaybar *bar = data;
@@ -278,6 +383,10 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
278 bar->pointer.pointer = wl_seat_get_pointer(wl_seat); 383 bar->pointer.pointer = wl_seat_get_pointer(wl_seat);
279 wl_pointer_add_listener(bar->pointer.pointer, &pointer_listener, bar); 384 wl_pointer_add_listener(bar->pointer.pointer, &pointer_listener, bar);
280 } 385 }
386 if ((caps & WL_SEAT_CAPABILITY_TOUCH)) {
387 bar->touch.touch = wl_seat_get_touch(wl_seat);
388 wl_touch_add_listener(bar->touch.touch, &touch_listener, bar);
389 }
281} 390}
282 391
283static void seat_handle_name(void *data, struct wl_seat *wl_seat, 392static void seat_handle_name(void *data, struct wl_seat *wl_seat,