diff options
Diffstat (limited to 'swaybar')
-rw-r--r-- | swaybar/input.c | 139 |
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 | ||
126 | static 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 | |||
126 | static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer, | 143 | static 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 | ||
158 | static void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, | 162 | static 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 | ||
258 | struct wl_pointer_listener pointer_listener = { | 262 | static 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 | ||
274 | static 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 | |||
291 | static 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 | |||
317 | static 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 | |||
331 | static 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 | |||
343 | static void wl_touch_frame(void *data, struct wl_touch *wl_touch) { | ||
344 | // Who cares | ||
345 | } | ||
346 | |||
347 | static 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 | |||
355 | static 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 | |||
360 | static void wl_touch_orientation(void *data, struct wl_touch *wl_touch, | ||
361 | int32_t id, wl_fixed_t orientation) { | ||
362 | // Who cares | ||
363 | } | ||
364 | |||
365 | static 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 | |||
270 | static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, | 375 | static 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 | ||
283 | static void seat_handle_name(void *data, struct wl_seat *wl_seat, | 392 | static void seat_handle_name(void *data, struct wl_seat *wl_seat, |