diff options
Diffstat (limited to 'swaybar/status_line.c')
-rw-r--r-- | swaybar/status_line.c | 81 |
1 files changed, 79 insertions, 2 deletions
diff --git a/swaybar/status_line.c b/swaybar/status_line.c index 83e8ce2c..e0564c26 100644 --- a/swaybar/status_line.c +++ b/swaybar/status_line.c | |||
@@ -27,6 +27,8 @@ struct { | |||
27 | static char line[1024]; | 27 | static char line[1024]; |
28 | static char line_rest[1024]; | 28 | static char line_rest[1024]; |
29 | 29 | ||
30 | static char event_buff[1024]; | ||
31 | |||
30 | static void free_status_block(void *item) { | 32 | static void free_status_block(void *item) { |
31 | if (!item) { | 33 | if (!item) { |
32 | return; | 34 | return; |
@@ -391,6 +393,66 @@ static int i3json_handle_fd(struct bar *bar) { | |||
391 | return i3json_parse(bar); | 393 | return i3json_parse(bar); |
392 | } | 394 | } |
393 | 395 | ||
396 | bool status_line_mouse_event(struct bar *bar, int x, int y, uint32_t button) { | ||
397 | sway_log(L_DEBUG, "status_line_mouse_event."); | ||
398 | if (!bar->status->click_events) { | ||
399 | sway_log(L_DEBUG, "click_events are not enabled."); | ||
400 | return false; | ||
401 | } | ||
402 | |||
403 | if (bar->status->protocol == I3BAR) { | ||
404 | sway_log(L_DEBUG, "Sending click event."); | ||
405 | |||
406 | // find clicked block | ||
407 | struct status_block *clicked_block = NULL; | ||
408 | struct status_block *current_block = NULL; | ||
409 | int num_blocks = bar->status->block_line->length; | ||
410 | |||
411 | if (num_blocks == 0) { | ||
412 | return false; | ||
413 | } else { | ||
414 | current_block = bar->status->block_line->items[0]; | ||
415 | if (x < current_block->x) { | ||
416 | return false; | ||
417 | } | ||
418 | } | ||
419 | |||
420 | for (int i = 0; i < num_blocks; i++) { | ||
421 | current_block = bar->status->block_line->items[i]; | ||
422 | if (x < (current_block->x + current_block->width)) { | ||
423 | clicked_block = current_block; | ||
424 | break; | ||
425 | } | ||
426 | } | ||
427 | |||
428 | if (!clicked_block || !clicked_block->name) { | ||
429 | return false; | ||
430 | } | ||
431 | |||
432 | // event example {"name":"capture","instance":"label","button":1,"x":3431,"y":18} | ||
433 | |||
434 | struct json_object *event_json = json_object_new_object(); | ||
435 | json_object_object_add(event_json, "name", json_object_new_string(clicked_block->name)); | ||
436 | if (clicked_block->instance) { | ||
437 | json_object_object_add(event_json, "instance", json_object_new_string(clicked_block->instance)); | ||
438 | } | ||
439 | json_object_object_add(event_json, "button", json_object_new_int(button)); | ||
440 | json_object_object_add(event_json, "x", json_object_new_int(x)); | ||
441 | json_object_object_add(event_json, "y", json_object_new_int(y)); | ||
442 | |||
443 | int len = snprintf(event_buff, sizeof(event_buff), "%s,\n", json_object_to_json_string(event_json)); | ||
444 | |||
445 | json_object_put(event_json); | ||
446 | |||
447 | if (len <= (int)sizeof(event_buff)) { // if not truncated | ||
448 | write(bar->status_write_fd, event_buff, len); | ||
449 | return true; | ||
450 | } | ||
451 | } | ||
452 | |||
453 | return false; | ||
454 | } | ||
455 | |||
394 | bool handle_status_line(struct bar *bar) { | 456 | bool handle_status_line(struct bar *bar) { |
395 | bool dirty = false; | 457 | bool dirty = false; |
396 | 458 | ||
@@ -418,15 +480,29 @@ bool handle_status_line(struct bar *bar) { | |||
418 | if (line[0] == '{') { | 480 | if (line[0] == '{') { |
419 | // detect i3bar json protocol | 481 | // detect i3bar json protocol |
420 | json_object *proto = json_tokener_parse(line); | 482 | json_object *proto = json_tokener_parse(line); |
421 | json_object *version; | ||
422 | if (proto) { | 483 | if (proto) { |
484 | |||
485 | json_object *version; | ||
423 | if (json_object_object_get_ex(proto, "version", &version) | 486 | if (json_object_object_get_ex(proto, "version", &version) |
424 | && json_object_get_int(version) == 1 | 487 | && json_object_get_int(version) == 1 |
425 | ) { | 488 | ) { |
426 | sway_log(L_DEBUG, "Switched to i3bar protocol."); | 489 | sway_log(L_DEBUG, "Switched to i3bar protocol."); |
427 | bar->status->protocol = I3BAR; | 490 | bar->status->protocol = I3BAR; |
428 | i3json_handle_data(bar, line_rest); | ||
429 | } | 491 | } |
492 | |||
493 | json_object *click_events; | ||
494 | if (json_object_object_get_ex(proto, "click_events", &click_events) | ||
495 | && json_object_get_boolean(click_events)) { | ||
496 | |||
497 | sway_log(L_DEBUG, "Enabling click events."); | ||
498 | bar->status->click_events = true; | ||
499 | |||
500 | const char *events_array = "[\n"; | ||
501 | write(bar->status_write_fd, events_array, strlen(events_array)); | ||
502 | } | ||
503 | |||
504 | i3json_handle_data(bar, line_rest); | ||
505 | |||
430 | json_object_put(proto); | 506 | json_object_put(proto); |
431 | } | 507 | } |
432 | } | 508 | } |
@@ -441,6 +517,7 @@ struct status_line *init_status_line() { | |||
441 | line->block_line = create_list(); | 517 | line->block_line = create_list(); |
442 | line->text_line = NULL; | 518 | line->text_line = NULL; |
443 | line->protocol = UNDEF; | 519 | line->protocol = UNDEF; |
520 | line->click_events = false; | ||
444 | 521 | ||
445 | return line; | 522 | return line; |
446 | } | 523 | } |