trigger events with environment variables. Closes #105

This commit is contained in:
Felix Kratz 2021-12-12 14:17:29 +01:00
parent ab4de8651d
commit 8d06ba429c
8 changed files with 54 additions and 25 deletions

View file

@ -401,8 +401,13 @@ to create more responsive items.
### Triggering custom events
This triggers a custom event that has been added before
```bash
sketchybar -m --trigger <event>
sketchybar -m --trigger <event> [Optional: <envvar>=<value> ... <envvar>=<value>]
```
Optionaly you can add environment variables to the trigger command witch are passed to the script, e.g.:
```bash
sketchybar -m --trigger demo VAR=Test
```
will trigger the demo event and `$VAR` will be available as an environment variable in the scripts that this event invokes.
This could be used to link the powerful event system of yabai to sketchybar by triggering the custom action via a yabai event.

View file

@ -49,6 +49,11 @@ void bar_item_inherit_from_item(struct bar_item* bar_item, struct bar_item* ance
bar_item_set_script(bar_item, string_copy(ancestor->script));
bar_item_set_click_script(bar_item, string_copy(ancestor->click_script));
if (bar_item->type == BAR_COMPONENT_SPACE) {
env_vars_set(&bar_item->signal_args.env_vars, string_copy("SID"), string_copy(env_vars_get_value_for_key(&ancestor->signal_args.env_vars, "DID")));
env_vars_set(&bar_item->signal_args.env_vars, string_copy("DID"), string_copy(env_vars_get_value_for_key(&ancestor->signal_args.env_vars, "DID")));
}
}
void bar_item_init(struct bar_item* bar_item, struct bar_item* default_item) {
@ -87,10 +92,10 @@ void bar_item_init(struct bar_item* bar_item, struct bar_item* default_item) {
text_init(&bar_item->icon);
text_init(&bar_item->label);
background_init(&bar_item->background);
env_vars_init(&bar_item->signal_args.env_vars);
if (default_item) bar_item_inherit_from_item(bar_item, default_item);
env_vars_init(&bar_item->signal_args.env_vars);
env_vars_set(&bar_item->signal_args.env_vars, string_copy("SELECTED"), string_copy("false"));
}
@ -136,7 +141,7 @@ void bar_item_reset_associated_bar(struct bar_item* bar_item) {
bar_item_remove_bounding_rect_for_display(bar_item, adid);
}
bool bar_item_update(struct bar_item* bar_item, char* sender, bool forced) {
bool bar_item_update(struct bar_item* bar_item, char* sender, bool forced, struct env_vars* env_vars) {
if ((!bar_item->updates || (bar_item->update_frequency == 0 && !sender)) && !forced) return false;
bar_item->counter++;
@ -148,9 +153,12 @@ bool bar_item_update(struct bar_item* bar_item, char* sender, bool forced) {
// Script Update
if (strlen(bar_item->script) > 0) {
if (sender) env_vars_set(&bar_item->signal_args.env_vars, string_copy("SENDER"), string_copy(sender));
else env_vars_set(&bar_item->signal_args.env_vars, string_copy("SENDER"), string_copy(forced ? "forced" : "routine"));
fork_exec(bar_item->script, &bar_item->signal_args);
if (!env_vars) env_vars = &bar_item->signal_args.env_vars;
else env_vars_set(env_vars, string_copy("NAME"), string_copy(bar_item->name));
if (sender) env_vars_set(env_vars, string_copy("SENDER"), string_copy(sender));
else env_vars_set(env_vars, string_copy("SENDER"), string_copy(forced ? "forced" : "routine"));
fork_exec(bar_item->script, env_vars);
}
// Alias Update
@ -237,19 +245,19 @@ void bar_item_on_click(struct bar_item* bar_item, uint32_t type, uint32_t modifi
env_vars_set(&bar_item->signal_args.env_vars, string_copy("MODIFIER"), string_copy(get_modifier_description(modifier)));
if (strlen(bar_item->click_script) > 0)
fork_exec(bar_item->click_script, &bar_item->signal_args);
fork_exec(bar_item->click_script, &bar_item->signal_args.env_vars);
if (bar_item->update_mask & UPDATE_MOUSE_CLICKED)
bar_item_update(bar_item, COMMAND_SUBSCRIBE_MOUSE_CLICKED, true);
bar_item_update(bar_item, COMMAND_SUBSCRIBE_MOUSE_CLICKED, true, NULL);
}
void bar_item_mouse_entered(struct bar_item* bar_item) {
bar_item->mouse_over = true;
if (bar_item->update_mask & UPDATE_MOUSE_ENTERED)
bar_item_update(bar_item, COMMAND_SUBSCRIBE_MOUSE_ENTERED, true);
bar_item_update(bar_item, COMMAND_SUBSCRIBE_MOUSE_ENTERED, true, NULL);
}
void bar_item_mouse_exited(struct bar_item* bar_item) {
if (bar_item->mouse_over && (bar_item->update_mask & UPDATE_MOUSE_EXITED)) bar_item_update(bar_item, COMMAND_SUBSCRIBE_MOUSE_EXITED, true);
if (bar_item->mouse_over && (bar_item->update_mask & UPDATE_MOUSE_EXITED)) bar_item_update(bar_item, COMMAND_SUBSCRIBE_MOUSE_EXITED, true, NULL);
bar_item->mouse_over = false;
}

View file

@ -71,7 +71,7 @@ void bar_item_destroy(struct bar_item* bar_item);
void bar_item_serialize(struct bar_item* bar_item, FILE* rsp);
bool bar_item_update(struct bar_item* bar_item, char* sender, bool forced);
bool bar_item_update(struct bar_item* bar_item, char* sender, bool forced, struct env_vars* env_vars);
bool bar_item_is_shown(struct bar_item* bar_item);
void bar_item_append_associated_space(struct bar_item* bar_item, uint32_t bit);

View file

@ -284,7 +284,7 @@ void bar_manager_destroy_item(struct bar_manager* bar_manager, struct bar_item*
void bar_manager_update_alias_components(struct bar_manager* bar_manager, bool forced) {
for (int i = 0; i < bar_manager->bar_item_count; i++) {
if ((!bar_item_is_shown(bar_manager->bar_items[i]) && !forced) || bar_manager->bar_items[i]->type != BAR_COMPONENT_ALIAS) continue;
bar_item_update(bar_manager->bar_items[i], NULL, forced);
bar_item_update(bar_manager->bar_items[i], NULL, forced, NULL);
}
}
@ -322,7 +322,7 @@ void bar_manager_update(struct bar_manager* bar_manager, bool forced) {
if ((bar_manager->frozen && !forced) || bar_manager->sleeps) return;
bool needs_refresh = false;
for (int i = 0; i < bar_manager->bar_item_count; i++) {
needs_refresh |= bar_item_update(bar_manager->bar_items[i], NULL, forced);
needs_refresh |= bar_item_update(bar_manager->bar_items[i], NULL, forced, NULL);
}
if (needs_refresh) bar_manager_refresh(bar_manager, false);
}
@ -359,13 +359,13 @@ struct bar_item* bar_manager_get_item_by_point(struct bar_manager* bar_manager,
return NULL;
}
void bar_manager_custom_events_trigger(struct bar_manager* bar_manager, char* name) {
void bar_manager_custom_events_trigger(struct bar_manager* bar_manager, char* name, struct env_vars* env_vars) {
uint64_t flag = custom_events_get_flag_for_name(&bar_manager->custom_events, name);
for (int i = 0; i < bar_manager->bar_item_count; i++) {
struct bar_item* bar_item = bar_manager->bar_items[i];
if (bar_item->update_mask & flag)
bar_item_update(bar_item, name, false);
bar_item_update(bar_item, name, false, env_vars);
}
}
@ -391,29 +391,29 @@ void bar_manager_handle_mouse_exited(struct bar_manager* bar_manager) {
}
void bar_manager_handle_front_app_switch(struct bar_manager* bar_manager) {
bar_manager_custom_events_trigger(bar_manager, COMMAND_SUBSCRIBE_FRONT_APP_SWITCHED);
bar_manager_custom_events_trigger(bar_manager, COMMAND_SUBSCRIBE_FRONT_APP_SWITCHED, NULL);
}
void bar_manager_handle_space_change(struct bar_manager* bar_manager) {
for (int i = 0; i < bar_manager->bar_count; i++) bar_manager->bars[i]->sid = mission_control_index(display_space_id(bar_manager->bars[i]->did));
bar_manager_update_space_components(bar_manager, false);
bar_manager_custom_events_trigger(bar_manager, COMMAND_SUBSCRIBE_SPACE_CHANGE);
bar_manager_custom_events_trigger(bar_manager, COMMAND_SUBSCRIBE_SPACE_CHANGE, NULL);
bar_manager_refresh(bar_manager, true);
}
void bar_manager_handle_display_change(struct bar_manager* bar_manager) {
bar_manager_custom_events_trigger(bar_manager, COMMAND_SUBSCRIBE_DISPLAY_CHANGE);
bar_manager_custom_events_trigger(bar_manager, COMMAND_SUBSCRIBE_DISPLAY_CHANGE, NULL);
}
void bar_manager_handle_system_will_sleep(struct bar_manager* bar_manager) {
bar_manager_custom_events_trigger(bar_manager, COMMAND_SUBSCRIBE_SYSTEM_WILL_SLEEP);
bar_manager_custom_events_trigger(bar_manager, COMMAND_SUBSCRIBE_SYSTEM_WILL_SLEEP, NULL);
bar_manager->sleeps = true;
}
void bar_manager_handle_system_woke(struct bar_manager* bar_manager) {
bar_manager->sleeps = false;
bar_manager_update_space_components(bar_manager, false);
bar_manager_custom_events_trigger(bar_manager, COMMAND_SUBSCRIBE_SYSTEM_WOKE);
bar_manager_custom_events_trigger(bar_manager, COMMAND_SUBSCRIBE_SYSTEM_WOKE, NULL);
bar_manager_refresh(bar_manager, true);
}
@ -421,7 +421,7 @@ void bar_manager_handle_notification(struct bar_manager* bar_manager, char* cont
char* name = custom_events_get_name_for_notification(&bar_manager->custom_events, context);
free(context);
if (!name) return;
bar_manager_custom_events_trigger(bar_manager, name);
bar_manager_custom_events_trigger(bar_manager, name, NULL);
}
void bar_manager_serialize(struct bar_manager* bar_manager, FILE* rsp) {

View file

@ -37,7 +37,7 @@ struct bar_manager {
};
int bar_manager_get_item_index_for_name(struct bar_manager* bar_manager, char* name);
void bar_manager_custom_events_trigger(struct bar_manager* bar_manager, char* name);
void bar_manager_custom_events_trigger(struct bar_manager* bar_manager, char* name, struct env_vars* env_vars);
struct bar_item* bar_manager_create_item(struct bar_manager* bar_manager);

View file

@ -42,7 +42,16 @@ static void handle_domain_subscribe(FILE* rsp, struct token domain, char* messag
// Syntax: sketchybar -m --trigger <event>
static void handle_domain_trigger(FILE* rsp, struct token domain, char* message) {
struct token event = get_token(&message);
bar_manager_custom_events_trigger(&g_bar_manager, event.text);
struct env_vars env_vars;
env_vars_init(&env_vars);
struct token token = get_token(&message);
while (token.text && token.length > 0) {
struct key_value_pair key_value_pair = get_key_value_pair(token.text, '=');
env_vars_set(&env_vars, string_copy(key_value_pair.key), string_copy(key_value_pair.value));
token = get_token(&message);
}
bar_manager_custom_events_trigger(&g_bar_manager, event.text, &env_vars);
env_vars_destroy(&env_vars);
}
// Syntax: sketchybar -m --push <name> <y>

View file

@ -59,6 +59,13 @@ void env_vars_set(struct env_vars* env_vars, char* key, char* value) {
env_vars->vars[env_vars->count - 1]->value = value;
}
char* env_vars_get_value_for_key(struct env_vars* env_vars, char* key) {
for (int i = 0; i < env_vars->count; i++) {
if (strcmp(env_vars->vars[i]->key, key) == 0) return env_vars->vars[i]->value;
}
return NULL;
}
void env_vars_destroy(struct env_vars* env_vars) {
for (int i = 0; i < env_vars->count; i++) {
if (env_vars->vars[i]->key) free(env_vars->vars[i]->key);

View file

@ -315,13 +315,13 @@ static bool sync_exec(char *command, struct env_vars *env_vars) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
static bool fork_exec(char *command, struct signal_args *args) {
static bool fork_exec(char *command, struct env_vars* env_vars) {
int pid = vfork();
if (pid == -1) return false;
if (pid != 0) return true;
alarm(FORK_TIMEOUT);
exit(sync_exec(command, &args->env_vars));
exit(sync_exec(command, env_vars));
}
#pragma clang diagnostic pop