i3bar: Add default bar_id

Instead of erroring, request the list of bar configs from i3 and use the
first one.
This commit is contained in:
Orestis Floros
2020-10-27 22:01:36 +01:00
parent fb5d2a05c2
commit c1ec2ad19b
7 changed files with 57 additions and 22 deletions

View File

@ -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.
*

View File

@ -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.

View File

@ -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) {
@ -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.
*

View File

@ -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-
@ -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;
}
/*

View File

@ -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");
@ -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();
@ -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.