diff --git a/i3bar/include/child.h b/i3bar/include/child.h index 38132e5d..d1c46890 100644 --- a/i3bar/include/child.h +++ b/i3bar/include/child.h @@ -10,6 +10,8 @@ #ifndef CHILD_H_ #define CHILD_H_ +#include + #define STDIN_CHUNK_SIZE 1024 typedef struct { @@ -21,6 +23,16 @@ typedef struct { * even an int8_t, but still… */ uint32_t version; + + bool stopped; + /** + * The signal requested by the client to inform it of the hidden state of i3bar + */ + int stop_signal; + /** + * The signal requested by the client to inform it of theun hidden state of i3bar + */ + int cont_signal; } i3bar_child; /* diff --git a/i3bar/include/parse_json_header.h b/i3bar/include/parse_json_header.h index 6495eeb1..79efddc6 100644 --- a/i3bar/include/parse_json_header.h +++ b/i3bar/include/parse_json_header.h @@ -13,15 +13,12 @@ #include -/* - * Determines the JSON i3bar protocol version from the given buffer. In case - * the buffer does not contain valid JSON, or no version field is found, this - * function returns -1. The amount of bytes consumed by parsing the header is - * returned in *consumed (if non-NULL). - * - * The return type is an int32_t to avoid machines with different sizes of - * 'int' to allow different values here. It’s highly unlikely we ever exceed - * even an int8_t, but still… +/** + * Parse the JSON protocol header to determine protocol version and features. + * In case the buffer does not contain a valid header (invalid JSON, or no + * version field found), the 'correct' field of the returned header is set to + * false. The amount of bytes consumed by parsing the header is returned in + * *consumed (if non-NULL). * */ void parse_json_header(i3bar_child *child, const unsigned char *buffer, int length, unsigned int *consumed); diff --git a/i3bar/src/child.c b/i3bar/src/child.c index f3832d9c..e4c0f357 100644 --- a/i3bar/src/child.c +++ b/i3bar/src/child.c @@ -251,6 +251,11 @@ void stdin_io_first_line_cb(struct ev_loop *loop, ev_io *watcher, int revents) { * in the future, but for now, we just discard it. */ parse_json_header(&child, buffer, rec, &consumed); if (child.version > 0) { + /* If hide-on-modifier is set, we start of by sending the + * child a SIGSTOP, because the bars aren't mapped at start */ + if (config.hide_on_modifier) { + stop_child(); + } read_json_input(buffer + consumed, rec - consumed); } else { /* In case of plaintext, we just add a single block and change its @@ -330,12 +335,6 @@ void start_child(char *command) { dup2(fd[0], STDIN_FILENO); - /* If hide-on-modifier is set, we start of by sending the - * child a SIGSTOP, because the bars aren't mapped at start */ - if (config.hide_on_modifier) { - stop_child(); - } - break; } } @@ -361,7 +360,8 @@ void start_child(char *command) { */ void kill_child_at_exit(void) { if (child.pid > 0) { - kill(child.pid, SIGCONT); + if (child.cont_signal > 0 && child.stopped) + kill(child.pid, child.cont_signal); kill(child.pid, SIGTERM); } } @@ -373,7 +373,8 @@ void kill_child_at_exit(void) { */ void kill_child(void) { if (child.pid > 0) { - kill(child.pid, SIGCONT); + if (child.cont_signal > 0 && child.stopped) + kill(child.pid, child.cont_signal); kill(child.pid, SIGTERM); int status; waitpid(child.pid, &status, 0); @@ -386,8 +387,9 @@ void kill_child(void) { * */ void stop_child(void) { - if (child.pid > 0) { - kill(child.pid, SIGSTOP); + if (child.stop_signal > 0 && !child.stopped) { + child.stopped = true; + kill(child.pid, child.stop_signal); } } @@ -396,7 +398,8 @@ void stop_child(void) { * */ void cont_child(void) { - if (child.pid > 0) { - kill(child.pid, SIGCONT); + if (child.cont_signal > 0 && child.stopped) { + child.stopped = false; + kill(child.pid, child.cont_signal); } } diff --git a/i3bar/src/parse_json_header.c b/i3bar/src/parse_json_header.c index a3fefb8a..80ec5af8 100644 --- a/i3bar/src/parse_json_header.c +++ b/i3bar/src/parse_json_header.c @@ -29,6 +29,8 @@ static enum { KEY_VERSION, + KEY_STOP_SIGNAL, + KEY_CONT_SIGNAL, NO_KEY } current_key; @@ -43,6 +45,12 @@ static int header_integer(void *ctx, long val) { case KEY_VERSION: child->version = val; break; + case KEY_STOP_SIGNAL: + child->stop_signal = val; + break; + case KEY_CONT_SIGNAL: + child->cont_signal = val; + break; default: break; } @@ -59,6 +67,10 @@ static int header_map_key(void *ctx, const unsigned char *stringval, unsigned in #endif if (CHECK_KEY("version")) { current_key = KEY_VERSION; + } else if (CHECK_KEY("stop_signal")) { + current_key = KEY_STOP_SIGNAL; + } else if (CHECK_KEY("cont_signal")) { + current_key = KEY_CONT_SIGNAL; } return 1; } @@ -79,6 +91,8 @@ static yajl_callbacks version_callbacks = { static void child_init(i3bar_child *child) { child->version = 0; + child->stop_signal = SIGSTOP; + child->cont_signal = SIGCONT; } /*