diff --git a/RELEASE-NOTES-next b/RELEASE-NOTES-next index cc617f5a4..8f5abd9d1 100644 --- a/RELEASE-NOTES-next +++ b/RELEASE-NOTES-next @@ -24,3 +24,6 @@ strongly encouraged to upgrade. • fix workspaces not moving to assigned output after output becomes available • fix duplicate bindcode after i3-config-wizard • clear pixmap before drawing to prevent visual grabage in clients using 'Shape' + • i3bar: properly close file descriptors + • i3bar: properly restart status command after config change + • i3bar: exit with 1 when a wrong command line argument is used diff --git a/i3bar/include/child.h b/i3bar/include/child.h index adc638bed..ae523bc0f 100644 --- a/i3bar/include/child.h +++ b/i3bar/include/child.h @@ -42,6 +42,12 @@ typedef struct { bool click_events_init; } i3bar_child; +/* + * Remove all blocks from the given statusline. + * If free_resources is set, the fields of each status block will be free'd. + */ +void clear_statusline(struct statusline_head *head, bool free_resources); + /* * Start a child process with the specified command and reroute stdin. * We actually start a $SHELL to execute the command so we don't have to care diff --git a/i3bar/src/child.c b/i3bar/src/child.c index bece314f2..df4c66016 100644 --- a/i3bar/src/child.c +++ b/i3bar/src/child.c @@ -27,7 +27,7 @@ #include /* Global variables for child_*() */ -i3bar_child child; +i3bar_child child = {0}; #define DLOG_CHILD DLOG("%s: pid=%ld stopped=%d stop_signal=%d cont_signal=%d click_events=%d click_events_init=%d\n", \ __func__, (long)child.pid, child.stopped, child.stop_signal, child.cont_signal, child.click_events, child.click_events_init) @@ -66,7 +66,7 @@ int child_stdin; * Remove all blocks from the given statusline. * If free_resources is set, the fields of each status block will be free'd. */ -static void clear_statusline(struct statusline_head *head, bool free_resources) { +void clear_statusline(struct statusline_head *head, bool free_resources) { struct status_block *first; while (!TAILQ_EMPTY(head)) { first = TAILQ_FIRST(head); @@ -139,6 +139,10 @@ static void cleanup(void) { if (stdin_io != NULL) { ev_io_stop(main_loop, stdin_io); FREE(stdin_io); + close(stdin_fd); + stdin_fd = 0; + close(child_stdin); + child_stdin = 0; } if (child_sig != NULL) { diff --git a/i3bar/src/config.c b/i3bar/src/config.c index 0376017ea..78f53d9f1 100644 --- a/i3bar/src/config.c +++ b/i3bar/src/config.c @@ -184,7 +184,6 @@ static int config_string_cb(void *params_, const unsigned char *val, size_t _len if (!strcmp(cur_key, "status_command")) { DLOG("command = %.*s\n", len, val); - FREE(config.command); sasprintf(&config.command, "%.*s", len, val); return 1; } diff --git a/i3bar/src/ipc.c b/i3bar/src/ipc.c index ec5fc06a7..0e12eafa7 100644 --- a/i3bar/src/ipc.c +++ b/i3bar/src/ipc.c @@ -155,9 +155,6 @@ static void got_workspace_event(char *event) { static void got_output_event(char *event) { DLOG("Got output event!\n"); i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_OUTPUTS, NULL); - if (!config.disable_ws) { - i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_WORKSPACES, NULL); - } } /* @@ -170,6 +167,15 @@ static void got_mode_event(char *event) { draw_bars(false); } +static bool strings_differ(char *a, char *b) { + const bool a_null = (a == NULL); + const bool b_null = (b == NULL); + if (a_null != b_null) { + return true; + } + return strcmp(a, b) != 0; +} + /* * Called, when a barconfig_update event arrives (i.e. i3 changed the bar hidden_state or mode) * @@ -190,8 +196,11 @@ static void got_bar_config_update(char *event) { /* update the configuration with the received settings */ DLOG("Received bar config update \"%s\"\n", event); - char *old_command = config.command ? sstrdup(config.command) : NULL; + + char *old_command = config.command; + config.command = NULL; bar_display_mode_t old_mode = config.hide_on_modifier; + parse_config_json(event); if (old_mode != config.hide_on_modifier) { reconfig_windows(true); @@ -202,8 +211,9 @@ static void got_bar_config_update(char *event) { init_colors(&(config.colors)); /* restart status command process */ - if (old_command && strcmp(old_command, config.command) != 0) { + if (strings_differ(old_command, config.command)) { kill_child(); + clear_statusline(&statusline_head, true); start_child(config.command); } free(old_command); diff --git a/i3bar/src/main.c b/i3bar/src/main.c index 5d7a2b995..4e93bb027 100644 --- a/i3bar/src/main.c +++ b/i3bar/src/main.c @@ -128,11 +128,13 @@ int main(int argc, char **argv) { break; default: print_usage(argv[0]); - exit(EXIT_SUCCESS); + exit(EXIT_FAILURE); break; } } + LOG("i3bar version " I3_VERSION "\n"); + main_loop = ev_default_loop(0); /* needed in init_xcb_early */ char *atom_sock_path = init_xcb_early();