aboutsummaryrefslogtreecommitdiffstats
path: root/swaybar
diff options
context:
space:
mode:
authorLibravatar Ian Fan <ianfan0@gmail.com>2018-12-07 12:39:35 +0000
committerLibravatar Ian Fan <ianfan0@gmail.com>2018-12-31 20:40:18 +0000
commit6becde024680503100c94702ed7d1fbf4d01576e (patch)
treeac261da8b9b0bde710ad819021ddfe542014d968 /swaybar
parentswaybar: implement tray rendering (diff)
downloadsway-6becde024680503100c94702ed7d1fbf4d01576e.tar.gz
sway-6becde024680503100c94702ed7d1fbf4d01576e.tar.zst
sway-6becde024680503100c94702ed7d1fbf4d01576e.zip
swaybar: implement mouse events for tray
Diffstat (limited to 'swaybar')
-rw-r--r--swaybar/bar.c8
-rw-r--r--swaybar/tray/item.c89
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
216static void xdg_output_handle_logical_position(void *data, 216static 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
221static void xdg_output_handle_logical_size(void *data, 223static 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
226static void xdg_output_handle_done(void *data, 230static 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
253static 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
298static 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
303static 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
251uint32_t render_sni(cairo_t *cairo, struct swaybar_output *output, double *x, 330uint32_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}