Feature: send complete config on barconfig_update
Send all the options in the bar block on the barconfig_update event. This will eventually allow for dynamically updating bar colors with the `reload` command.
This commit is contained in:
parent
ab0fae400b
commit
2f42fe61d9
18
docs/ipc
18
docs/ipc
|
@ -637,7 +637,7 @@ window (3)::
|
||||||
focus or when a window title has been updated.
|
focus or when a window title has been updated.
|
||||||
barconfig_update (4)::
|
barconfig_update (4)::
|
||||||
Sent when the hidden_state or mode field in the barconfig of any bar
|
Sent when the hidden_state or mode field in the barconfig of any bar
|
||||||
instance was updated.
|
instance was updated and when the config is reloaded.
|
||||||
|
|
||||||
*Example:*
|
*Example:*
|
||||||
--------------------------------------------------------------------
|
--------------------------------------------------------------------
|
||||||
|
@ -738,20 +738,8 @@ this point get the window title as "urxvt").
|
||||||
=== barconfig_update event
|
=== barconfig_update event
|
||||||
|
|
||||||
This event consists of a single serialized map reporting on options from the
|
This event consists of a single serialized map reporting on options from the
|
||||||
barconfig of the specified bar_id that were updated in i3. The map always
|
barconfig of the specified bar_id that were updated in i3. This event is the
|
||||||
consists of a property +id (string)+, which specifies to which bar instance the
|
same as a +GET_BAR_CONFIG+ reply for the bar with the given id.
|
||||||
sent config update belongs, a property +hidden_state (string)+, which indicates
|
|
||||||
the hidden_state of an i3bar instance, and a property +mode (string)+, which
|
|
||||||
corresponds to the current mode.
|
|
||||||
|
|
||||||
*Example:*
|
|
||||||
---------------------------
|
|
||||||
{
|
|
||||||
"id": "bar-0",
|
|
||||||
"hidden_state": "hide"
|
|
||||||
"mode": "hide"
|
|
||||||
}
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
== See also (existing libraries)
|
== See also (existing libraries)
|
||||||
|
|
||||||
|
|
|
@ -317,9 +317,9 @@ void ungrab_all_keys(xcb_connection_t *conn);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends the current bar configuration as an event to all barconfig_update listeners.
|
* Sends the current bar configuration as an event to all barconfig_update listeners.
|
||||||
* This update mechnism currently only includes the hidden_state and the mode in the config.
|
|
||||||
*
|
*
|
||||||
*/void update_barconfig();
|
*/
|
||||||
|
void update_barconfig();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Kills the configerror i3-nagbar process, if any.
|
* Kills the configerror i3-nagbar process, if any.
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include "data.h"
|
#include "data.h"
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#include "i3/ipc.h"
|
#include "i3/ipc.h"
|
||||||
|
|
||||||
|
@ -93,3 +94,8 @@ void ipc_send_workspace_focus_event(Con *current, Con *old);
|
||||||
* also the window container, in "container".
|
* also the window container, in "container".
|
||||||
*/
|
*/
|
||||||
void ipc_send_window_event(const char *property, Con *con);
|
void ipc_send_window_event(const char *property, Con *con);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For the barconfig update events, we send the serialized barconfig.
|
||||||
|
*/
|
||||||
|
void ipc_send_barconfig_update_event(Barconfig *barconfig);
|
||||||
|
|
34
src/config.c
34
src/config.c
|
@ -32,44 +32,12 @@ void ungrab_all_keys(xcb_connection_t *conn) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sends the current bar configuration as an event to all barconfig_update listeners.
|
* Sends the current bar configuration as an event to all barconfig_update listeners.
|
||||||
* This update mechnism currently only includes the hidden_state and the mode in the config.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void update_barconfig() {
|
void update_barconfig() {
|
||||||
Barconfig *current;
|
Barconfig *current;
|
||||||
TAILQ_FOREACH(current, &barconfigs, configs) {
|
TAILQ_FOREACH(current, &barconfigs, configs) {
|
||||||
/* Build json message */
|
ipc_send_barconfig_update_event(current);
|
||||||
char *hidden_state;
|
|
||||||
switch (current->hidden_state) {
|
|
||||||
case S_SHOW:
|
|
||||||
hidden_state ="show";
|
|
||||||
break;
|
|
||||||
case S_HIDE:
|
|
||||||
default:
|
|
||||||
hidden_state = "hide";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *mode;
|
|
||||||
switch (current->mode) {
|
|
||||||
case M_HIDE:
|
|
||||||
mode ="hide";
|
|
||||||
break;
|
|
||||||
case M_INVISIBLE:
|
|
||||||
mode ="invisible";
|
|
||||||
break;
|
|
||||||
case M_DOCK:
|
|
||||||
default:
|
|
||||||
mode = "dock";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Send an event to all barconfig listeners*/
|
|
||||||
char *event_msg;
|
|
||||||
sasprintf(&event_msg, "{ \"id\":\"%s\", \"hidden_state\":\"%s\", \"mode\":\"%s\" }", current->id, hidden_state, mode);
|
|
||||||
|
|
||||||
ipc_send_event("barconfig_update", I3_IPC_EVENT_BARCONFIG_UPDATE, event_msg);
|
|
||||||
FREE(event_msg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
278
src/ipc.c
278
src/ipc.c
|
@ -423,6 +423,135 @@ void dump_node(yajl_gen gen, struct Con *con, bool inplace_restart) {
|
||||||
y(map_close);
|
y(map_close);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dump_bar_config(yajl_gen gen, Barconfig *config) {
|
||||||
|
y(map_open);
|
||||||
|
|
||||||
|
ystr("id");
|
||||||
|
ystr(config->id);
|
||||||
|
|
||||||
|
if (config->num_outputs > 0) {
|
||||||
|
ystr("outputs");
|
||||||
|
y(array_open);
|
||||||
|
for (int c = 0; c < config->num_outputs; c++)
|
||||||
|
ystr(config->outputs[c]);
|
||||||
|
y(array_close);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define YSTR_IF_SET(name) \
|
||||||
|
do { \
|
||||||
|
if (config->name) { \
|
||||||
|
ystr( # name); \
|
||||||
|
ystr(config->name); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
YSTR_IF_SET(tray_output);
|
||||||
|
YSTR_IF_SET(socket_path);
|
||||||
|
|
||||||
|
ystr("mode");
|
||||||
|
switch (config->mode) {
|
||||||
|
case M_HIDE:
|
||||||
|
ystr("hide");
|
||||||
|
break;
|
||||||
|
case M_INVISIBLE:
|
||||||
|
ystr("invisible");
|
||||||
|
break;
|
||||||
|
case M_DOCK:
|
||||||
|
default:
|
||||||
|
ystr("dock");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ystr("hidden_state");
|
||||||
|
switch (config->hidden_state) {
|
||||||
|
case S_SHOW:
|
||||||
|
ystr("show");
|
||||||
|
break;
|
||||||
|
case S_HIDE:
|
||||||
|
default:
|
||||||
|
ystr("hide");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ystr("modifier");
|
||||||
|
switch (config->modifier) {
|
||||||
|
case M_CONTROL:
|
||||||
|
ystr("ctrl");
|
||||||
|
break;
|
||||||
|
case M_SHIFT:
|
||||||
|
ystr("shift");
|
||||||
|
break;
|
||||||
|
case M_MOD1:
|
||||||
|
ystr("Mod1");
|
||||||
|
break;
|
||||||
|
case M_MOD2:
|
||||||
|
ystr("Mod2");
|
||||||
|
break;
|
||||||
|
case M_MOD3:
|
||||||
|
ystr("Mod3");
|
||||||
|
break;
|
||||||
|
/*
|
||||||
|
case M_MOD4:
|
||||||
|
ystr("Mod4");
|
||||||
|
break;
|
||||||
|
*/
|
||||||
|
case M_MOD5:
|
||||||
|
ystr("Mod5");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ystr("Mod4");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ystr("position");
|
||||||
|
if (config->position == P_BOTTOM)
|
||||||
|
ystr("bottom");
|
||||||
|
else ystr("top");
|
||||||
|
|
||||||
|
YSTR_IF_SET(status_command);
|
||||||
|
YSTR_IF_SET(font);
|
||||||
|
|
||||||
|
ystr("workspace_buttons");
|
||||||
|
y(bool, !config->hide_workspace_buttons);
|
||||||
|
|
||||||
|
ystr("binding_mode_indicator");
|
||||||
|
y(bool, !config->hide_binding_mode_indicator);
|
||||||
|
|
||||||
|
ystr("verbose");
|
||||||
|
y(bool, config->verbose);
|
||||||
|
|
||||||
|
#undef YSTR_IF_SET
|
||||||
|
#define YSTR_IF_SET(name) \
|
||||||
|
do { \
|
||||||
|
if (config->colors.name) { \
|
||||||
|
ystr( # name); \
|
||||||
|
ystr(config->colors.name); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
ystr("colors");
|
||||||
|
y(map_open);
|
||||||
|
YSTR_IF_SET(background);
|
||||||
|
YSTR_IF_SET(statusline);
|
||||||
|
YSTR_IF_SET(separator);
|
||||||
|
YSTR_IF_SET(focused_workspace_border);
|
||||||
|
YSTR_IF_SET(focused_workspace_bg);
|
||||||
|
YSTR_IF_SET(focused_workspace_text);
|
||||||
|
YSTR_IF_SET(active_workspace_border);
|
||||||
|
YSTR_IF_SET(active_workspace_bg);
|
||||||
|
YSTR_IF_SET(active_workspace_text);
|
||||||
|
YSTR_IF_SET(inactive_workspace_border);
|
||||||
|
YSTR_IF_SET(inactive_workspace_bg);
|
||||||
|
YSTR_IF_SET(inactive_workspace_text);
|
||||||
|
YSTR_IF_SET(urgent_workspace_border);
|
||||||
|
YSTR_IF_SET(urgent_workspace_bg);
|
||||||
|
YSTR_IF_SET(urgent_workspace_text);
|
||||||
|
y(map_close);
|
||||||
|
|
||||||
|
y(map_close);
|
||||||
|
#undef YSTR_IF_SET
|
||||||
|
}
|
||||||
|
|
||||||
IPC_HANDLER(tree) {
|
IPC_HANDLER(tree) {
|
||||||
setlocale(LC_NUMERIC, "C");
|
setlocale(LC_NUMERIC, "C");
|
||||||
yajl_gen gen = ygenalloc();
|
yajl_gen gen = ygenalloc();
|
||||||
|
@ -651,141 +780,19 @@ IPC_HANDLER(get_bar_config) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
y(map_open);
|
|
||||||
|
|
||||||
if (!config) {
|
if (!config) {
|
||||||
/* If we did not find a config for the given ID, the reply will contain
|
/* If we did not find a config for the given ID, the reply will contain
|
||||||
* a null 'id' field. */
|
* a null 'id' field. */
|
||||||
|
y(map_open);
|
||||||
|
|
||||||
ystr("id");
|
ystr("id");
|
||||||
y(null);
|
y(null);
|
||||||
} else {
|
|
||||||
ystr("id");
|
|
||||||
ystr(config->id);
|
|
||||||
|
|
||||||
if (config->num_outputs > 0) {
|
|
||||||
ystr("outputs");
|
|
||||||
y(array_open);
|
|
||||||
for (int c = 0; c < config->num_outputs; c++)
|
|
||||||
ystr(config->outputs[c]);
|
|
||||||
y(array_close);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define YSTR_IF_SET(name) \
|
|
||||||
do { \
|
|
||||||
if (config->name) { \
|
|
||||||
ystr( # name); \
|
|
||||||
ystr(config->name); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
YSTR_IF_SET(tray_output);
|
|
||||||
YSTR_IF_SET(socket_path);
|
|
||||||
|
|
||||||
ystr("mode");
|
|
||||||
switch (config->mode) {
|
|
||||||
case M_HIDE:
|
|
||||||
ystr("hide");
|
|
||||||
break;
|
|
||||||
case M_INVISIBLE:
|
|
||||||
ystr("invisible");
|
|
||||||
break;
|
|
||||||
case M_DOCK:
|
|
||||||
default:
|
|
||||||
ystr("dock");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ystr("hidden_state");
|
|
||||||
switch (config->hidden_state) {
|
|
||||||
case S_SHOW:
|
|
||||||
ystr("show");
|
|
||||||
break;
|
|
||||||
case S_HIDE:
|
|
||||||
default:
|
|
||||||
ystr("hide");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ystr("modifier");
|
|
||||||
switch (config->modifier) {
|
|
||||||
case M_CONTROL:
|
|
||||||
ystr("ctrl");
|
|
||||||
break;
|
|
||||||
case M_SHIFT:
|
|
||||||
ystr("shift");
|
|
||||||
break;
|
|
||||||
case M_MOD1:
|
|
||||||
ystr("Mod1");
|
|
||||||
break;
|
|
||||||
case M_MOD2:
|
|
||||||
ystr("Mod2");
|
|
||||||
break;
|
|
||||||
case M_MOD3:
|
|
||||||
ystr("Mod3");
|
|
||||||
break;
|
|
||||||
/*
|
|
||||||
case M_MOD4:
|
|
||||||
ystr("Mod4");
|
|
||||||
break;
|
|
||||||
*/
|
|
||||||
case M_MOD5:
|
|
||||||
ystr("Mod5");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ystr("Mod4");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ystr("position");
|
|
||||||
if (config->position == P_BOTTOM)
|
|
||||||
ystr("bottom");
|
|
||||||
else ystr("top");
|
|
||||||
|
|
||||||
YSTR_IF_SET(status_command);
|
|
||||||
YSTR_IF_SET(font);
|
|
||||||
|
|
||||||
ystr("workspace_buttons");
|
|
||||||
y(bool, !config->hide_workspace_buttons);
|
|
||||||
|
|
||||||
ystr("binding_mode_indicator");
|
|
||||||
y(bool, !config->hide_binding_mode_indicator);
|
|
||||||
|
|
||||||
ystr("verbose");
|
|
||||||
y(bool, config->verbose);
|
|
||||||
|
|
||||||
#undef YSTR_IF_SET
|
|
||||||
#define YSTR_IF_SET(name) \
|
|
||||||
do { \
|
|
||||||
if (config->colors.name) { \
|
|
||||||
ystr( # name); \
|
|
||||||
ystr(config->colors.name); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
ystr("colors");
|
|
||||||
y(map_open);
|
|
||||||
YSTR_IF_SET(background);
|
|
||||||
YSTR_IF_SET(statusline);
|
|
||||||
YSTR_IF_SET(separator);
|
|
||||||
YSTR_IF_SET(focused_workspace_border);
|
|
||||||
YSTR_IF_SET(focused_workspace_bg);
|
|
||||||
YSTR_IF_SET(focused_workspace_text);
|
|
||||||
YSTR_IF_SET(active_workspace_border);
|
|
||||||
YSTR_IF_SET(active_workspace_bg);
|
|
||||||
YSTR_IF_SET(active_workspace_text);
|
|
||||||
YSTR_IF_SET(inactive_workspace_border);
|
|
||||||
YSTR_IF_SET(inactive_workspace_bg);
|
|
||||||
YSTR_IF_SET(inactive_workspace_text);
|
|
||||||
YSTR_IF_SET(urgent_workspace_border);
|
|
||||||
YSTR_IF_SET(urgent_workspace_bg);
|
|
||||||
YSTR_IF_SET(urgent_workspace_text);
|
|
||||||
y(map_close);
|
y(map_close);
|
||||||
|
} else {
|
||||||
#undef YSTR_IF_SET
|
dump_bar_config(gen, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
y(map_close);
|
|
||||||
|
|
||||||
const unsigned char *payload;
|
const unsigned char *payload;
|
||||||
ylength length;
|
ylength length;
|
||||||
y(get_buf, &payload, &length);
|
y(get_buf, &payload, &length);
|
||||||
|
@ -1091,3 +1098,22 @@ void ipc_send_window_event(const char *property, Con *con) {
|
||||||
y(free);
|
y(free);
|
||||||
setlocale(LC_NUMERIC, "");
|
setlocale(LC_NUMERIC, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For the barconfig update events, we send the serialized barconfig.
|
||||||
|
*/
|
||||||
|
void ipc_send_barconfig_update_event(Barconfig *barconfig) {
|
||||||
|
DLOG("Issue barconfig_update event for id = %s\n", barconfig->id);
|
||||||
|
setlocale(LC_NUMERIC, "C");
|
||||||
|
yajl_gen gen = ygenalloc();
|
||||||
|
|
||||||
|
dump_bar_config(gen, barconfig);
|
||||||
|
|
||||||
|
const unsigned char *payload;
|
||||||
|
ylength length;
|
||||||
|
y(get_buf, &payload, &length);
|
||||||
|
|
||||||
|
ipc_send_event("barconfig_update", I3_IPC_EVENT_BARCONFIG_UPDATE, (const char *)payload);
|
||||||
|
y(free);
|
||||||
|
setlocale(LC_NUMERIC, "");
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue