aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Emerson Ferreira <12075874+nuskorpios@users.noreply.github.com>2017-08-31 20:35:03 +0000
committerLibravatar GitHub <noreply@github.com>2017-08-31 20:35:03 +0000
commit013df6a8a5b99c873cd08e8b1cd6350def2a0b2c (patch)
tree4187dee4d31e39deec32cbf2005e4b6b4b910a84
parentTranslate README to portuguese (diff)
parentMerge pull request #1336 from akokshar/master (diff)
downloadsway-013df6a8a5b99c873cd08e8b1cd6350def2a0b2c.tar.gz
sway-013df6a8a5b99c873cd08e8b1cd6350def2a0b2c.tar.zst
sway-013df6a8a5b99c873cd08e8b1cd6350def2a0b2c.zip
Merge branch 'master' into master
-rw-r--r--include/swaybar/bar.h1
-rw-r--r--include/swaybar/status_line.h10
-rw-r--r--swaybar/bar.c52
-rw-r--r--swaybar/render.c3
-rw-r--r--swaybar/status_line.c81
-rw-r--r--swaygrab/main.c31
6 files changed, 158 insertions, 20 deletions
diff --git a/include/swaybar/bar.h b/include/swaybar/bar.h
index 010e1f84..50d36e76 100644
--- a/include/swaybar/bar.h
+++ b/include/swaybar/bar.h
@@ -14,6 +14,7 @@ struct bar {
14 int ipc_event_socketfd; 14 int ipc_event_socketfd;
15 int ipc_socketfd; 15 int ipc_socketfd;
16 int status_read_fd; 16 int status_read_fd;
17 int status_write_fd;
17 pid_t status_command_pid; 18 pid_t status_command_pid;
18}; 19};
19 20
diff --git a/include/swaybar/status_line.h b/include/swaybar/status_line.h
index 9b77e8a7..0664ddee 100644
--- a/include/swaybar/status_line.h
+++ b/include/swaybar/status_line.h
@@ -13,6 +13,7 @@ struct status_line {
13 list_t *block_line; 13 list_t *block_line;
14 const char *text_line; 14 const char *text_line;
15 command_protocol protocol; 15 command_protocol protocol;
16 bool click_events;
16}; 17};
17 18
18struct status_block { 19struct status_block {
@@ -31,6 +32,10 @@ struct status_block {
31 int border_bottom; 32 int border_bottom;
32 int border_left; 33 int border_left;
33 int border_right; 34 int border_right;
35
36 // Set during rendering
37 int x;
38 int width;
34}; 39};
35 40
36/** 41/**
@@ -44,6 +49,11 @@ struct status_line *init_status_line();
44bool handle_status_line(struct bar *bar); 49bool handle_status_line(struct bar *bar);
45 50
46/** 51/**
52 * Handle mouse clicks.
53 */
54bool status_line_mouse_event(struct bar *bar, int x, int y, uint32_t button);
55
56/**
47 * Free status line struct. 57 * Free status line struct.
48 */ 58 */
49void free_status_line(struct status_line *line); 59void free_status_line(struct status_line *line);
diff --git a/swaybar/bar.c b/swaybar/bar.c
index 5e87eac9..85cb5270 100644
--- a/swaybar/bar.c
+++ b/swaybar/bar.c
@@ -7,6 +7,7 @@
7#include <sys/wait.h> 7#include <sys/wait.h>
8#include <signal.h> 8#include <signal.h>
9#include <poll.h> 9#include <poll.h>
10#include <linux/input-event-codes.h>
10#ifdef ENABLE_TRAY 11#ifdef ENABLE_TRAY
11#include <dbus/dbus.h> 12#include <dbus/dbus.h>
12#include "swaybar/tray/sni_watcher.h" 13#include "swaybar/tray/sni_watcher.h"
@@ -31,16 +32,30 @@ static void bar_init(struct bar *bar) {
31 32
32static void spawn_status_cmd_proc(struct bar *bar) { 33static void spawn_status_cmd_proc(struct bar *bar) {
33 if (bar->config->status_command) { 34 if (bar->config->status_command) {
34 int pipefd[2]; 35 int pipe_read_fd[2];
35 if (pipe(pipefd) != 0) { 36 int pipe_write_fd[2];
36 sway_log(L_ERROR, "Unable to create pipe for status_command fork"); 37
38 if (pipe(pipe_read_fd) != 0) {
39 sway_log(L_ERROR, "Unable to create pipes for status_command fork");
40 return;
41 }
42 if (pipe(pipe_write_fd) != 0) {
43 sway_log(L_ERROR, "Unable to create pipe for status_command fork (write)");
44 close(pipe_read_fd[0]);
45 close(pipe_read_fd[1]);
37 return; 46 return;
38 } 47 }
48
39 bar->status_command_pid = fork(); 49 bar->status_command_pid = fork();
40 if (bar->status_command_pid == 0) { 50 if (bar->status_command_pid == 0) {
41 close(pipefd[0]); 51 close(pipe_read_fd[0]);
42 dup2(pipefd[1], STDOUT_FILENO); 52 dup2(pipe_read_fd[1], STDOUT_FILENO);
43 close(pipefd[1]); 53 close(pipe_read_fd[1]);
54
55 dup2(pipe_write_fd[0], STDIN_FILENO);
56 close(pipe_write_fd[0]);
57 close(pipe_write_fd[1]);
58
44 char *const cmd[] = { 59 char *const cmd[] = {
45 "sh", 60 "sh",
46 "-c", 61 "-c",
@@ -51,9 +66,13 @@ static void spawn_status_cmd_proc(struct bar *bar) {
51 return; 66 return;
52 } 67 }
53 68
54 close(pipefd[1]); 69 close(pipe_read_fd[1]);
55 bar->status_read_fd = pipefd[0]; 70 bar->status_read_fd = pipe_read_fd[0];
56 fcntl(bar->status_read_fd, F_SETFL, O_NONBLOCK); 71 fcntl(bar->status_read_fd, F_SETFL, O_NONBLOCK);
72
73 close(pipe_write_fd[0]);
74 bar->status_write_fd = pipe_write_fd[1];
75 fcntl(bar->status_write_fd, F_SETFL, O_NONBLOCK);
57 } 76 }
58} 77}
59 78
@@ -103,9 +122,22 @@ static void mouse_button_notify(struct window *window, int x, int y,
103 } 122 }
104 } 123 }
105 124
125 switch (button) {
126 case BTN_LEFT:
127 status_line_mouse_event(&swaybar, x, y, 1);
128 break;
129 case BTN_MIDDLE:
130 status_line_mouse_event(&swaybar, x, y, 2);
131 break;
132 case BTN_RIGHT:
133 status_line_mouse_event(&swaybar, x, y, 3);
134 break;
135 }
136
106#ifdef ENABLE_TRAY 137#ifdef ENABLE_TRAY
107 tray_mouse_event(clicked_output, x, y, button, state_w); 138 tray_mouse_event(clicked_output, x, y, button, state_w);
108#endif 139#endif
140
109} 141}
110 142
111static void mouse_scroll_notify(struct window *window, enum scroll_direction direction) { 143static void mouse_scroll_notify(struct window *window, enum scroll_direction direction) {
@@ -318,6 +350,10 @@ void bar_teardown(struct bar *bar) {
318 close(bar->status_read_fd); 350 close(bar->status_read_fd);
319 } 351 }
320 352
353 if (bar->status_write_fd) {
354 close(bar->status_write_fd);
355 }
356
321 if (bar->ipc_socketfd) { 357 if (bar->ipc_socketfd) {
322 close(bar->ipc_socketfd); 358 close(bar->ipc_socketfd);
323 } 359 }
diff --git a/swaybar/render.c b/swaybar/render.c
index 6ec47e79..6fc09078 100644
--- a/swaybar/render.c
+++ b/swaybar/render.c
@@ -94,6 +94,9 @@ static void render_block(struct window *window, struct config *config, struct st
94 94
95 double pos = *x; 95 double pos = *x;
96 96
97 block->x = (int)pos;
98 block->width = (int)block_width;
99
97 // render background 100 // render background
98 if (block->background != 0x0) { 101 if (block->background != 0x0) {
99 cairo_set_source_u32(window->cairo, block->background); 102 cairo_set_source_u32(window->cairo, block->background);
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 {
27static char line[1024]; 27static char line[1024];
28static char line_rest[1024]; 28static char line_rest[1024];
29 29
30static char event_buff[1024];
31
30static void free_status_block(void *item) { 32static 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
396bool 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
394bool handle_status_line(struct bar *bar) { 456bool 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}
diff --git a/swaygrab/main.c b/swaygrab/main.c
index c437653d..6e851899 100644
--- a/swaygrab/main.c
+++ b/swaygrab/main.c
@@ -9,6 +9,7 @@
9#include <stdint.h> 9#include <stdint.h>
10#include <math.h> 10#include <math.h>
11#include <time.h> 11#include <time.h>
12#include <sys/wait.h>
12#include <json-c/json.h> 13#include <json-c/json.h>
13#include "log.h" 14#include "log.h"
14#include "ipc-client.h" 15#include "ipc-client.h"
@@ -47,17 +48,27 @@ void grab_and_apply_magick(const char *file, const char *payload,
47 return; 48 return;
48 } 49 }
49 50
50 const char *fmt = "convert -depth 8 -size %dx%d+0 rgba:- -flip %s"; 51 char size[10 + 1 + 10 + 2 + 1]; // int32_t are max 10 digits
51 char *cmd = malloc(strlen(fmt) - 6 /*args*/ 52 sprintf(size, "%dx%d+0", width, height);
52 + numlen(width) + numlen(height) + strlen(file) + 1);
53 sprintf(cmd, fmt, width, height, file);
54 53
55 FILE *f = popen(cmd, "w"); 54 pid_t child;
56 fwrite(pixels, 1, len, f); 55 int fd[2];
57 fflush(f); 56 pipe(fd);
58 fclose(f); 57
59 free(pixels - 9); 58 if ((child = fork()) < 0) {
60 free(cmd); 59 sway_log(L_ERROR, "Swaygrab failed to fork.");
60 exit(EXIT_FAILURE);
61 } else if (child == 0) {
62 close(fd[1]);
63 write(fd[0], pixels, len);
64 free(pixels - 9);
65 waitpid(child, NULL, 0);
66 } else {
67 close(fd[0]);
68 execlp("convert", "-depth", "8", "-size", size, "rgba:-", "-flip", file, NULL);
69 sway_log(L_ERROR, "Swaygrab could not run convert.");
70 exit(EXIT_FAILURE);
71 }
61} 72}
62 73
63void grab_and_apply_movie_magic(const char *file, const char *payload, 74void grab_and_apply_movie_magic(const char *file, const char *payload,