|
|
|
@ -152,12 +152,12 @@ static bool ipc_parse_config(
|
|
|
|
|
json_object_put(bar_config);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
json_object *markup, *mode, *hidden_bar, *position, *status_command;
|
|
|
|
|
json_object *markup, *mode, *hidden_state, *position, *status_command;
|
|
|
|
|
json_object *font, *bar_height, *wrap_scroll, *workspace_buttons, *strip_workspace_numbers;
|
|
|
|
|
json_object *binding_mode_indicator, *verbose, *colors, *sep_symbol, *outputs;
|
|
|
|
|
json_object *bindings;
|
|
|
|
|
json_object_object_get_ex(bar_config, "mode", &mode);
|
|
|
|
|
json_object_object_get_ex(bar_config, "hidden_bar", &hidden_bar);
|
|
|
|
|
json_object_object_get_ex(bar_config, "hidden_state", &hidden_state);
|
|
|
|
|
json_object_object_get_ex(bar_config, "position", &position);
|
|
|
|
|
json_object_object_get_ex(bar_config, "status_command", &status_command);
|
|
|
|
|
json_object_object_get_ex(bar_config, "font", &font);
|
|
|
|
@ -220,6 +220,14 @@ static bool ipc_parse_config(
|
|
|
|
|
list_add(config->bindings, binding);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (hidden_state) {
|
|
|
|
|
free(config->hidden_state);
|
|
|
|
|
config->hidden_state = strdup(json_object_get_string(hidden_state));
|
|
|
|
|
}
|
|
|
|
|
if (mode) {
|
|
|
|
|
free(config->mode);
|
|
|
|
|
config->mode = strdup(json_object_get_string(mode));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct config_output *output, *tmp;
|
|
|
|
|
wl_list_for_each_safe(output, tmp, &config->outputs, link) {
|
|
|
|
@ -254,7 +262,7 @@ static bool ipc_parse_config(
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ipc_get_workspaces(struct swaybar *bar) {
|
|
|
|
|
bool ipc_get_workspaces(struct swaybar *bar) {
|
|
|
|
|
struct swaybar_output *output;
|
|
|
|
|
wl_list_for_each(output, &bar->outputs, link) {
|
|
|
|
|
free_workspaces(&output->workspaces);
|
|
|
|
@ -266,8 +274,10 @@ void ipc_get_workspaces(struct swaybar *bar) {
|
|
|
|
|
json_object *results = json_tokener_parse(res);
|
|
|
|
|
if (!results) {
|
|
|
|
|
free(res);
|
|
|
|
|
return;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bar->visible_by_urgency = false;
|
|
|
|
|
size_t length = json_object_array_length(results);
|
|
|
|
|
json_object *ws_json;
|
|
|
|
|
json_object *num, *name, *visible, *focused, *out, *urgent;
|
|
|
|
@ -294,12 +304,16 @@ void ipc_get_workspaces(struct swaybar *bar) {
|
|
|
|
|
output->focused = true;
|
|
|
|
|
}
|
|
|
|
|
ws->urgent = json_object_get_boolean(urgent);
|
|
|
|
|
if (ws->urgent) {
|
|
|
|
|
bar->visible_by_urgency = true;
|
|
|
|
|
}
|
|
|
|
|
wl_list_insert(&output->workspaces, &ws->link);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
json_object_put(results);
|
|
|
|
|
free(res);
|
|
|
|
|
return determine_bar_visibility(bar, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void ipc_get_outputs(struct swaybar *bar) {
|
|
|
|
@ -345,10 +359,10 @@ void ipc_execute_binding(struct swaybar *bar, struct swaybar_binding *bind) {
|
|
|
|
|
IPC_COMMAND, bind->command, &len));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ipc_initialize(struct swaybar *bar, const char *bar_id) {
|
|
|
|
|
uint32_t len = strlen(bar_id);
|
|
|
|
|
bool ipc_initialize(struct swaybar *bar) {
|
|
|
|
|
uint32_t len = strlen(bar->id);
|
|
|
|
|
char *res = ipc_single_command(bar->ipc_socketfd,
|
|
|
|
|
IPC_GET_BAR_CONFIG, bar_id, &len);
|
|
|
|
|
IPC_GET_BAR_CONFIG, bar->id, &len);
|
|
|
|
|
if (!ipc_parse_config(bar->config, res)) {
|
|
|
|
|
free(res);
|
|
|
|
|
return false;
|
|
|
|
@ -356,56 +370,108 @@ bool ipc_initialize(struct swaybar *bar, const char *bar_id) {
|
|
|
|
|
free(res);
|
|
|
|
|
ipc_get_outputs(bar);
|
|
|
|
|
|
|
|
|
|
const char *subscribe = "[ \"workspace\", \"mode\" ]";
|
|
|
|
|
len = strlen(subscribe);
|
|
|
|
|
struct swaybar_config *config = bar->config;
|
|
|
|
|
char subscribe[128]; // suitably large buffer
|
|
|
|
|
len = snprintf(subscribe, 128,
|
|
|
|
|
"[ \"barconfig_update\" , \"bar_state_update\" %s %s ]",
|
|
|
|
|
config->binding_mode_indicator ? ", \"mode\"" : "",
|
|
|
|
|
config->workspace_buttons ? ", \"workspace\"" : "");
|
|
|
|
|
free(ipc_single_command(bar->ipc_event_socketfd,
|
|
|
|
|
IPC_SUBSCRIBE, subscribe, &len));
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool handle_bar_state_update(struct swaybar *bar, json_object *event) {
|
|
|
|
|
json_object *json_id;
|
|
|
|
|
json_object_object_get_ex(event, "id", &json_id);
|
|
|
|
|
const char *id = json_object_get_string(json_id);
|
|
|
|
|
if (strcmp(id, bar->id) != 0) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
json_object *visible_by_modifier;
|
|
|
|
|
json_object_object_get_ex(event, "visible_by_modifier", &visible_by_modifier);
|
|
|
|
|
bar->visible_by_modifier = json_object_get_boolean(visible_by_modifier);
|
|
|
|
|
return determine_bar_visibility(bar, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool handle_barconfig_update(struct swaybar *bar,
|
|
|
|
|
json_object *json_config) {
|
|
|
|
|
json_object *json_id;
|
|
|
|
|
json_object_object_get_ex(json_config, "id", &json_id);
|
|
|
|
|
const char *id = json_object_get_string(json_id);
|
|
|
|
|
if (strcmp(id, bar->id) != 0) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct swaybar_config *config = bar->config;
|
|
|
|
|
|
|
|
|
|
json_object *json_state;
|
|
|
|
|
json_object_object_get_ex(json_config, "hidden_state", &json_state);
|
|
|
|
|
const char *new_state = json_object_get_string(json_state);
|
|
|
|
|
char *old_state = config->hidden_state;
|
|
|
|
|
if (strcmp(new_state, old_state) != 0) {
|
|
|
|
|
wlr_log(WLR_DEBUG, "Changing bar hidden state to %s", new_state);
|
|
|
|
|
free(old_state);
|
|
|
|
|
config->hidden_state = strdup(new_state);
|
|
|
|
|
return determine_bar_visibility(bar, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(config->mode);
|
|
|
|
|
json_object *json_mode;
|
|
|
|
|
json_object_object_get_ex(json_config, "mode", &json_mode);
|
|
|
|
|
config->mode = strdup(json_object_get_string(json_mode));
|
|
|
|
|
wlr_log(WLR_DEBUG, "Changing bar mode to %s", config->mode);
|
|
|
|
|
|
|
|
|
|
return determine_bar_visibility(bar, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool handle_ipc_readable(struct swaybar *bar) {
|
|
|
|
|
struct ipc_response *resp = ipc_recv_response(bar->ipc_event_socketfd);
|
|
|
|
|
if (!resp) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
switch (resp->type) {
|
|
|
|
|
case IPC_EVENT_WORKSPACE:
|
|
|
|
|
ipc_get_workspaces(bar);
|
|
|
|
|
break;
|
|
|
|
|
case IPC_EVENT_MODE: {
|
|
|
|
|
|
|
|
|
|
json_object *result = json_tokener_parse(resp->payload);
|
|
|
|
|
if (!result) {
|
|
|
|
|
free_ipc_response(resp);
|
|
|
|
|
wlr_log(WLR_ERROR, "failed to parse payload as json");
|
|
|
|
|
free_ipc_response(resp);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool bar_is_dirty = true;
|
|
|
|
|
switch (resp->type) {
|
|
|
|
|
case IPC_EVENT_WORKSPACE:
|
|
|
|
|
bar_is_dirty = ipc_get_workspaces(bar);
|
|
|
|
|
break;
|
|
|
|
|
case IPC_EVENT_MODE: {
|
|
|
|
|
json_object *json_change, *json_pango_markup;
|
|
|
|
|
if (json_object_object_get_ex(result, "change", &json_change)) {
|
|
|
|
|
const char *change = json_object_get_string(json_change);
|
|
|
|
|
free(bar->config->mode);
|
|
|
|
|
if (strcmp(change, "default") == 0) {
|
|
|
|
|
bar->config->mode = NULL;
|
|
|
|
|
} else {
|
|
|
|
|
bar->config->mode = strdup(change);
|
|
|
|
|
}
|
|
|
|
|
free(bar->mode);
|
|
|
|
|
bar->mode = strcmp(change, "default") != 0 ? strdup(change) : NULL;
|
|
|
|
|
} else {
|
|
|
|
|
wlr_log(WLR_ERROR, "failed to parse response");
|
|
|
|
|
json_object_put(result);
|
|
|
|
|
free_ipc_response(resp);
|
|
|
|
|
return false;
|
|
|
|
|
bar_is_dirty = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (json_object_object_get_ex(result,
|
|
|
|
|
"pango_markup", &json_pango_markup)) {
|
|
|
|
|
bar->config->mode_pango_markup = json_object_get_boolean(
|
|
|
|
|
json_pango_markup);
|
|
|
|
|
bar->mode_pango_markup = json_object_get_boolean(json_pango_markup);
|
|
|
|
|
}
|
|
|
|
|
json_object_put(result);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case IPC_EVENT_BARCONFIG_UPDATE:
|
|
|
|
|
bar_is_dirty = handle_barconfig_update(bar, result);
|
|
|
|
|
break;
|
|
|
|
|
case IPC_EVENT_BAR_STATE_UPDATE:
|
|
|
|
|
bar_is_dirty = handle_bar_state_update(bar, result);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
free_ipc_response(resp);
|
|
|
|
|
return false;
|
|
|
|
|
bar_is_dirty = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
json_object_put(result);
|
|
|
|
|
free_ipc_response(resp);
|
|
|
|
|
return true;
|
|
|
|
|
return bar_is_dirty;
|
|
|
|
|
}
|
|
|
|
|