diff options
author | Drew DeVault <sir@cmpwn.com> | 2019-02-17 11:00:13 -0500 |
---|---|---|
committer | emersion <contact@emersion.fr> | 2019-02-23 20:00:20 +0100 |
commit | d1588e37390279c0e99304cda93da8c416292097 (patch) | |
tree | f086e5924e28347759677615678ed71768e143d2 /swaybar/input.c | |
parent | swaybar: process hotspots on touch tap (diff) | |
download | sway-d1588e37390279c0e99304cda93da8c416292097.tar.gz sway-d1588e37390279c0e99304cda93da8c416292097.tar.zst sway-d1588e37390279c0e99304cda93da8c416292097.zip |
swaybar: cycle workspaces on touch drag
Diffstat (limited to 'swaybar/input.c')
-rw-r--r-- | swaybar/input.c | 93 |
1 files changed, 56 insertions, 37 deletions
diff --git a/swaybar/input.c b/swaybar/input.c index d443c777..c83d8c33 100644 --- a/swaybar/input.c +++ b/swaybar/input.c | |||
@@ -159,6 +159,44 @@ static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer, | |||
159 | process_hotspots(output, pointer->x, pointer->y, button); | 159 | process_hotspots(output, pointer->x, pointer->y, button); |
160 | } | 160 | } |
161 | 161 | ||
162 | static void workspace_next(struct swaybar *bar, struct swaybar_output *output, | ||
163 | bool left) { | ||
164 | struct swaybar_config *config = bar->config; | ||
165 | struct swaybar_workspace *first = | ||
166 | wl_container_of(output->workspaces.next, first, link); | ||
167 | struct swaybar_workspace *last = | ||
168 | wl_container_of(output->workspaces.prev, last, link); | ||
169 | |||
170 | struct swaybar_workspace *active; | ||
171 | wl_list_for_each(active, &output->workspaces, link) { | ||
172 | if (active->visible) { | ||
173 | break; | ||
174 | } | ||
175 | } | ||
176 | if (!sway_assert(active->visible, "axis with null workspace")) { | ||
177 | return; | ||
178 | } | ||
179 | |||
180 | struct swaybar_workspace *new; | ||
181 | if (left) { | ||
182 | if (active == first) { | ||
183 | new = config->wrap_scroll ? last : NULL; | ||
184 | } else { | ||
185 | new = wl_container_of(active->link.prev, new, link); | ||
186 | } | ||
187 | } else { | ||
188 | if (active == last) { | ||
189 | new = config->wrap_scroll ? first : NULL; | ||
190 | } else { | ||
191 | new = wl_container_of(active->link.next, new, link); | ||
192 | } | ||
193 | } | ||
194 | |||
195 | if (new) { | ||
196 | ipc_send_workspace_command(bar, new->name); | ||
197 | } | ||
198 | } | ||
199 | |||
162 | static void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, | 200 | static void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, |
163 | uint32_t time, uint32_t axis, wl_fixed_t value) { | 201 | uint32_t time, uint32_t axis, wl_fixed_t value) { |
164 | struct swaybar *bar = data; | 202 | struct swaybar *bar = data; |
@@ -202,39 +240,7 @@ static void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, | |||
202 | return; | 240 | return; |
203 | } | 241 | } |
204 | 242 | ||
205 | struct swaybar_workspace *first = | 243 | workspace_next(bar, output, amt < 0.0); |
206 | wl_container_of(output->workspaces.next, first, link); | ||
207 | struct swaybar_workspace *last = | ||
208 | wl_container_of(output->workspaces.prev, last, link); | ||
209 | |||
210 | struct swaybar_workspace *active; | ||
211 | wl_list_for_each(active, &output->workspaces, link) { | ||
212 | if (active->visible) { | ||
213 | break; | ||
214 | } | ||
215 | } | ||
216 | if (!sway_assert(active->visible, "axis with null workspace")) { | ||
217 | return; | ||
218 | } | ||
219 | |||
220 | struct swaybar_workspace *new; | ||
221 | if (amt < 0.0) { | ||
222 | if (active == first) { | ||
223 | new = config->wrap_scroll ? last : NULL; | ||
224 | } else { | ||
225 | new = wl_container_of(active->link.prev, new, link); | ||
226 | } | ||
227 | } else { | ||
228 | if (active == last) { | ||
229 | new = config->wrap_scroll ? first : NULL; | ||
230 | } else { | ||
231 | new = wl_container_of(active->link.next, new, link); | ||
232 | } | ||
233 | } | ||
234 | |||
235 | if (new) { | ||
236 | ipc_send_workspace_command(bar, new->name); | ||
237 | } | ||
238 | 244 | ||
239 | // Check button release bindings | 245 | // Check button release bindings |
240 | check_bindings(bar, button, WL_POINTER_BUTTON_STATE_RELEASED); | 246 | check_bindings(bar, button, WL_POINTER_BUTTON_STATE_RELEASED); |
@@ -272,7 +278,7 @@ static struct wl_pointer_listener pointer_listener = { | |||
272 | }; | 278 | }; |
273 | 279 | ||
274 | static struct touch_slot *get_touch_slot(struct swaybar_touch *touch, int32_t id) { | 280 | static struct touch_slot *get_touch_slot(struct swaybar_touch *touch, int32_t id) { |
275 | int next = -1; | 281 | ssize_t next = -1; |
276 | for (size_t i = 0; i < sizeof(touch->slots) / sizeof(*touch->slots); ++i) { | 282 | for (size_t i = 0; i < sizeof(touch->slots) / sizeof(*touch->slots); ++i) { |
277 | if (touch->slots[i].id == id) { | 283 | if (touch->slots[i].id == id) { |
278 | return &touch->slots[i]; | 284 | return &touch->slots[i]; |
@@ -292,7 +298,7 @@ static void wl_touch_down(void *data, struct wl_touch *wl_touch, | |||
292 | uint32_t serial, uint32_t time, struct wl_surface *surface, | 298 | uint32_t serial, uint32_t time, struct wl_surface *surface, |
293 | int32_t id, wl_fixed_t _x, wl_fixed_t _y) { | 299 | int32_t id, wl_fixed_t _x, wl_fixed_t _y) { |
294 | struct swaybar *bar = data; | 300 | struct swaybar *bar = data; |
295 | struct swaybar_output *_output, *output; | 301 | struct swaybar_output *_output = NULL, *output = NULL; |
296 | wl_list_for_each(_output, &bar->outputs, link) { | 302 | wl_list_for_each(_output, &bar->outputs, link) { |
297 | if (_output->surface == surface) { | 303 | if (_output->surface == surface) { |
298 | output = _output; | 304 | output = _output; |
@@ -335,9 +341,18 @@ static void wl_touch_motion(void *data, struct wl_touch *wl_touch, | |||
335 | if (!slot) { | 341 | if (!slot) { |
336 | return; | 342 | return; |
337 | } | 343 | } |
344 | int prev_progress = (int)((slot->x - slot->start_x) | ||
345 | / slot->output->width * 100); | ||
338 | slot->x = wl_fixed_to_double(x); | 346 | slot->x = wl_fixed_to_double(x); |
339 | slot->y = wl_fixed_to_double(y); | 347 | slot->y = wl_fixed_to_double(y); |
340 | // TODO: Slide gestures | 348 | // "progress" is a measure from 0..100 representing the fraction of the |
349 | // output the touch gesture has travelled, positive when moving to the right | ||
350 | // and negative when moving to the left. | ||
351 | int progress = (int)((slot->x - slot->start_x) | ||
352 | / slot->output->width * 100); | ||
353 | if (abs(progress) / 20 != abs(prev_progress) / 20) { | ||
354 | workspace_next(bar, slot->output, progress - prev_progress < 0); | ||
355 | } | ||
341 | } | 356 | } |
342 | 357 | ||
343 | static void wl_touch_frame(void *data, struct wl_touch *wl_touch) { | 358 | static void wl_touch_frame(void *data, struct wl_touch *wl_touch) { |
@@ -362,7 +377,7 @@ static void wl_touch_orientation(void *data, struct wl_touch *wl_touch, | |||
362 | // Who cares | 377 | // Who cares |
363 | } | 378 | } |
364 | 379 | ||
365 | static struct wl_touch_listener touch_listener = { | 380 | static const struct wl_touch_listener touch_listener = { |
366 | .down = wl_touch_down, | 381 | .down = wl_touch_down, |
367 | .up = wl_touch_up, | 382 | .up = wl_touch_up, |
368 | .motion = wl_touch_motion, | 383 | .motion = wl_touch_motion, |
@@ -379,6 +394,10 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, | |||
379 | wl_pointer_release(bar->pointer.pointer); | 394 | wl_pointer_release(bar->pointer.pointer); |
380 | bar->pointer.pointer = NULL; | 395 | bar->pointer.pointer = NULL; |
381 | } | 396 | } |
397 | if (bar->touch.touch != NULL) { | ||
398 | wl_touch_release(bar->touch.touch); | ||
399 | bar->touch.touch = NULL; | ||
400 | } | ||
382 | if ((caps & WL_SEAT_CAPABILITY_POINTER)) { | 401 | if ((caps & WL_SEAT_CAPABILITY_POINTER)) { |
383 | bar->pointer.pointer = wl_seat_get_pointer(wl_seat); | 402 | bar->pointer.pointer = wl_seat_get_pointer(wl_seat); |
384 | wl_pointer_add_listener(bar->pointer.pointer, &pointer_listener, bar); | 403 | wl_pointer_add_listener(bar->pointer.pointer, &pointer_listener, bar); |