diff options
Diffstat (limited to 'swaybar')
-rw-r--r-- | swaybar/bar.c | 8 | ||||
-rw-r--r-- | swaybar/tray/item.c | 89 |
2 files changed, 95 insertions, 2 deletions
diff --git a/swaybar/bar.c b/swaybar/bar.c index 668168eb..ebb9bc12 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c | |||
@@ -215,12 +215,16 @@ struct wl_output_listener output_listener = { | |||
215 | 215 | ||
216 | static void xdg_output_handle_logical_position(void *data, | 216 | static void xdg_output_handle_logical_position(void *data, |
217 | struct zxdg_output_v1 *xdg_output, int32_t x, int32_t y) { | 217 | struct zxdg_output_v1 *xdg_output, int32_t x, int32_t y) { |
218 | // Who cares | 218 | struct swaybar_output *output = data; |
219 | output->output_x = x; | ||
220 | output->output_y = y; | ||
219 | } | 221 | } |
220 | 222 | ||
221 | static void xdg_output_handle_logical_size(void *data, | 223 | static void xdg_output_handle_logical_size(void *data, |
222 | struct zxdg_output_v1 *xdg_output, int32_t width, int32_t height) { | 224 | struct zxdg_output_v1 *xdg_output, int32_t width, int32_t height) { |
223 | // Who cares | 225 | struct swaybar_output *output = data; |
226 | output->output_height = height; | ||
227 | output->output_width = width; | ||
224 | } | 228 | } |
225 | 229 | ||
226 | static void xdg_output_handle_done(void *data, | 230 | static void xdg_output_handle_done(void *data, |
diff --git a/swaybar/tray/item.c b/swaybar/tray/item.c index 019e8ed0..450b6882 100644 --- a/swaybar/tray/item.c +++ b/swaybar/tray/item.c | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <string.h> | 5 | #include <string.h> |
6 | #include "swaybar/bar.h" | 6 | #include "swaybar/bar.h" |
7 | #include "swaybar/config.h" | 7 | #include "swaybar/config.h" |
8 | #include "swaybar/input.h" | ||
8 | #include "swaybar/tray/host.h" | 9 | #include "swaybar/tray/host.h" |
9 | #include "swaybar/tray/icon.h" | 10 | #include "swaybar/tray/icon.h" |
10 | #include "swaybar/tray/item.h" | 11 | #include "swaybar/tray/item.h" |
@@ -13,6 +14,7 @@ | |||
13 | #include "cairo.h" | 14 | #include "cairo.h" |
14 | #include "list.h" | 15 | #include "list.h" |
15 | #include "log.h" | 16 | #include "log.h" |
17 | #include "wlr-layer-shell-unstable-v1-client-protocol.h" | ||
16 | 18 | ||
17 | // TODO menu | 19 | // TODO menu |
18 | 20 | ||
@@ -248,6 +250,83 @@ void destroy_sni(struct swaybar_sni *sni) { | |||
248 | free(sni); | 250 | free(sni); |
249 | } | 251 | } |
250 | 252 | ||
253 | static void handle_click(struct swaybar_sni *sni, int x, int y, | ||
254 | enum x11_button button, int delta) { | ||
255 | const char *method = sni->tray->bar->config->tray_bindings[button]; | ||
256 | if (!method) { | ||
257 | static const char *default_bindings[10] = { | ||
258 | "nop", | ||
259 | "Activate", | ||
260 | "SecondaryActivate", | ||
261 | "ContextMenu", | ||
262 | "ScrollUp", | ||
263 | "ScrollDown", | ||
264 | "ScrollLeft", | ||
265 | "ScrollRight", | ||
266 | "nop", | ||
267 | "nop" | ||
268 | }; | ||
269 | method = default_bindings[button]; | ||
270 | } | ||
271 | if (strcmp(method, "nop") == 0) { | ||
272 | return; | ||
273 | } | ||
274 | if (sni->item_is_menu && strcmp(method, "Activate") == 0) { | ||
275 | method = "ContextMenu"; | ||
276 | } | ||
277 | |||
278 | if (strncmp(method, "Scroll", strlen("Scroll")) == 0) { | ||
279 | char dir = method[strlen("Scroll")]; | ||
280 | char *orientation = (dir = 'U' || dir == 'D') ? "vertical" : "horizontal"; | ||
281 | int sign = (dir == 'U' || dir == 'L') ? -1 : 1; | ||
282 | |||
283 | int ret = sd_bus_call_method_async(sni->tray->bus, NULL, sni->service, | ||
284 | sni->path, sni->interface, "Scroll", NULL, NULL, "is", | ||
285 | delta*sign, orientation); | ||
286 | if (ret < 0) { | ||
287 | wlr_log(WLR_DEBUG, "Failed to scroll on SNI: %s", strerror(-ret)); | ||
288 | } | ||
289 | } else { | ||
290 | int ret = sd_bus_call_method_async(sni->tray->bus, NULL, sni->service, | ||
291 | sni->path, sni->interface, method, NULL, NULL, "ii", x, y); | ||
292 | if (ret < 0) { | ||
293 | wlr_log(WLR_DEBUG, "Failed to click on SNI: %s", strerror(-ret)); | ||
294 | } | ||
295 | } | ||
296 | } | ||
297 | |||
298 | static int cmp_sni_id(const void *item, const void *cmp_to) { | ||
299 | const struct swaybar_sni *sni = item; | ||
300 | return strcmp(sni->watcher_id, cmp_to); | ||
301 | } | ||
302 | |||
303 | static enum hotspot_event_handling icon_hotspot_callback( | ||
304 | struct swaybar_output *output, struct swaybar_hotspot *hotspot, | ||
305 | int x, int y, enum x11_button button, void *data) { | ||
306 | wlr_log(WLR_DEBUG, "Clicked on Status Notifier Item '%s'", (char *)data); | ||
307 | |||
308 | struct swaybar_tray *tray = output->bar->tray; | ||
309 | int idx = list_seq_find(tray->items, cmp_sni_id, data); | ||
310 | |||
311 | if (idx != -1) { | ||
312 | struct swaybar_sni *sni = tray->items->items[idx]; | ||
313 | // guess global position since wayland doesn't expose it | ||
314 | struct swaybar_config *config = tray->bar->config; | ||
315 | int global_x = output->output_x + config->gaps.left + x; | ||
316 | bool top_bar = config->position & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP; | ||
317 | int global_y = output->output_y + (top_bar ? config->gaps.top + y: | ||
318 | (int) output->output_height - config->gaps.bottom - y); | ||
319 | |||
320 | wlr_log(WLR_DEBUG, "Guessing click at (%d, %d)", global_x, global_y); | ||
321 | handle_click(sni, global_x, global_y, button, 1); // TODO get delta from event | ||
322 | return HOTSPOT_IGNORE; | ||
323 | } else { | ||
324 | wlr_log(WLR_DEBUG, "but it doesn't exist"); | ||
325 | } | ||
326 | |||
327 | return HOTSPOT_PROCESS; | ||
328 | } | ||
329 | |||
251 | uint32_t render_sni(cairo_t *cairo, struct swaybar_output *output, double *x, | 330 | uint32_t render_sni(cairo_t *cairo, struct swaybar_output *output, double *x, |
252 | struct swaybar_sni *sni) { | 331 | struct swaybar_sni *sni) { |
253 | uint32_t height = output->height * output->scale; | 332 | uint32_t height = output->height * output->scale; |
@@ -316,5 +395,15 @@ uint32_t render_sni(cairo_t *cairo, struct swaybar_output *output, double *x, | |||
316 | 395 | ||
317 | cairo_surface_destroy(icon); | 396 | cairo_surface_destroy(icon); |
318 | 397 | ||
398 | struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot)); | ||
399 | hotspot->x = *x; | ||
400 | hotspot->y = 0; | ||
401 | hotspot->width = height; | ||
402 | hotspot->height = height; | ||
403 | hotspot->callback = icon_hotspot_callback; | ||
404 | hotspot->destroy = free; | ||
405 | hotspot->data = strdup(sni->watcher_id); | ||
406 | wl_list_insert(&output->hotspots, &hotspot->link); | ||
407 | |||
319 | return output->height; | 408 | return output->height; |
320 | } | 409 | } |