Skip to content
This repository has been archived by the owner on Apr 18, 2023. It is now read-only.

Commit

Permalink
i3bar: Add default bar_id
Browse files Browse the repository at this point in the history
Instead of erroring, request the list of bar configs from i3 and use the
first one.
  • Loading branch information
orestisfl committed Jan 3, 2021
1 parent fb5d2a0 commit c1ec2ad
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 22 deletions.
1 change: 1 addition & 0 deletions RELEASE-NOTES-next
Expand Up @@ -14,6 +14,7 @@ strongly encouraged to upgrade.
• i3-nagbar: position on focused monitor by default
• i3-nagbar: add option to position on primary monitor
• alternate focusing tab/stack children-parent containers by clicking on their titlebars
• i3bar: use first bar config by default

┌────────────────────────────┐
│ Bugfixes │
Expand Down
7 changes: 7 additions & 0 deletions i3bar/include/configuration.h
Expand Up @@ -74,6 +74,13 @@ extern config_t config;
*/
void parse_config_json(char *json);

/**
* Start parsing the received bar configuration list. The only usecase right
* now is to automatically get the first bar id.
*
*/
void parse_get_first_i3bar_config(char *json);

/**
* free()s the color strings as soon as they are not needed anymore.
*
Expand Down
2 changes: 1 addition & 1 deletion i3bar/include/ipc.h
Expand Up @@ -18,7 +18,7 @@
* socket_path must be a valid path to the ipc_socket of i3
*
*/
int init_connection(const char *socket_path);
void init_connection(const char *socket_path);

/*
* Destroy the connection to i3.
Expand Down
25 changes: 21 additions & 4 deletions i3bar/src/config.c
Expand Up @@ -367,14 +367,12 @@ static yajl_callbacks outputs_callbacks = {
*
*/
void parse_config_json(char *json) {
yajl_handle handle;
yajl_status state;
handle = yajl_alloc(&outputs_callbacks, NULL, NULL);
yajl_handle handle = yajl_alloc(&outputs_callbacks, NULL, NULL);

TAILQ_INIT(&(config.bindings));
TAILQ_INIT(&(config.tray_outputs));

state = yajl_parse(handle, (const unsigned char *)json, strlen(json));
yajl_status state = yajl_parse(handle, (const unsigned char *)json, strlen(json));

/* FIXME: Proper error handling for JSON parsing */
switch (state) {
Expand All @@ -390,6 +388,25 @@ void parse_config_json(char *json) {
yajl_free(handle);
}

static int i3bar_config_string_cb(void *params_, const unsigned char *val, size_t _len) {
sasprintf(&config.bar_id, "%.*s", (int)_len, val);
return 0; /* Stop parsing */
}

/*
* Start parsing the received bar configuration list. The only usecase right
* now is to automatically get the first bar id.
*
*/
void parse_get_first_i3bar_config(char *json) {
yajl_callbacks configs_callbacks = {
.yajl_string = i3bar_config_string_cb,
};
yajl_handle handle = yajl_alloc(&configs_callbacks, NULL, NULL);
yajl_parse(handle, (const unsigned char *)json, strlen(json));
yajl_free(handle);
}

/*
* free()s the color strings as soon as they are not needed anymore.
*
Expand Down
17 changes: 15 additions & 2 deletions i3bar/src/ipc.c
Expand Up @@ -85,6 +85,20 @@ static void got_output_reply(char *reply) {
*
*/
static void got_bar_config(char *reply) {
if (!config.bar_id) {
DLOG("Received bar list \"%s\"\n", reply);
parse_get_first_i3bar_config(reply);

if (!config.bar_id) {
ELOG("No bar configuration found, please configure a bar block in your i3 config file.\n");
exit(EXIT_FAILURE);
}

LOG("Using first bar config: %s. Use --bar_id to manually select a different bar configuration.\n", config.bar_id);
i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_BAR_CONFIG, config.bar_id);
return;
}

DLOG("Received bar config \"%s\"\n", reply);
/* We initiate the main function by requesting infos about the outputs and
* workspaces. Everything else (creating the bars, showing the right workspace-
Expand Down Expand Up @@ -328,13 +342,12 @@ int i3_send_msg(uint32_t type, const char *payload) {
* socket_path must be a valid path to the ipc_socket of i3
*
*/
int init_connection(const char *socket_path) {
void init_connection(const char *socket_path) {
sock_path = socket_path;
int sockfd = ipc_connect(socket_path);
i3_connection = smalloc(sizeof(ev_io));
ev_io_init(i3_connection, &got_data, sockfd, EV_READ);
ev_io_start(main_loop, i3_connection);
return 1;
}

/*
Expand Down
22 changes: 9 additions & 13 deletions i3bar/src/main.c
Expand Up @@ -56,9 +56,9 @@ static char *expand_path(char *path) {
}

static void print_usage(char *elf_name) {
printf("Usage: %s -b bar_id [-s sock_path] [-t] [-h] [-v] [-V]\n", elf_name);
printf("Usage: %s [-b bar_id] [-s sock_path] [-t] [-h] [-v] [-V]\n", elf_name);
printf("\n");
printf("-b, --bar_id <bar_id>\tBar ID for which to get the configuration\n");
printf("-b, --bar_id <bar_id>\tBar ID for which to get the configuration, defaults to the first bar from the i3 config\n");
printf("-s, --socket <sock_path>\tConnect to i3 via <sock_path>\n");
printf("-t, --transparency Enable transparency (RGBA colors)\n");
printf("-h, --help Display this help message and exit\n");
Expand Down Expand Up @@ -133,13 +133,6 @@ int main(int argc, char **argv) {
}
}

if (!config.bar_id) {
/* TODO: maybe we want -f which will automatically ask i3 for the first
* configured bar (and error out if there are too many)? */
ELOG("No bar_id passed. Please let i3 start i3bar or specify --bar_id\n");
exit(EXIT_FAILURE);
}

main_loop = ev_default_loop(0); /* needed in init_xcb_early */
char *atom_sock_path = init_xcb_early();

Expand All @@ -166,10 +159,13 @@ int main(int argc, char **argv) {
init_dpi();

init_outputs();
if (init_connection(socket_path)) {
/* Request the bar configuration. When it arrives, we fill the config array. */
i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_BAR_CONFIG, config.bar_id);
}

init_connection(socket_path);
/* Request the bar configuration. When it arrives, we fill the config
* array. In case that config.bar_id is empty, we will receive a list of
* available configs and then request the configuration for the first bar.
* See got_bar_config for more. */
i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_BAR_CONFIG, config.bar_id);
free(socket_path);

/* We listen to SIGTERM/QUIT/INT and try to exit cleanly, by stopping the main loop.
Expand Down
5 changes: 3 additions & 2 deletions man/i3bar.man
Expand Up @@ -9,7 +9,7 @@ i3bar - xcb-based status- and workspace-bar

== SYNOPSIS

*i3bar* *-b* 'bar_id' [*-s* 'sock_path'] [*-t*] [*-h*] [*-v*] [*-V*]
*i3bar* [*-b* 'bar_id'] [*-s* 'sock_path'] [*-t*] [*-h*] [*-v*] [*-V*]

== WARNING

Expand All @@ -25,7 +25,8 @@ You have been warned!
Overwrites the path to the i3 IPC socket.

*-b, --bar_id* 'bar_id'::
Specifies the bar ID for which to get the configuration from i3.
Specifies the bar ID for which to get the configuration from i3. By default,
i3bar will use the first bar block as configured in i3.

*-t, --transparency*::
Enable transparency (RGBA colors)
Expand Down

0 comments on commit c1ec2ad

Please sign in to comment.