From 8d06ba429ca826ec34f3035f12668dbf806c9495 Mon Sep 17 00:00:00 2001 From: Felix Kratz Date: Sun, 12 Dec 2021 14:17:29 +0100 Subject: [PATCH] trigger events with environment variables. Closes #105 --- README.md | 7 ++++++- src/bar_item.c | 26 +++++++++++++++++--------- src/bar_item.h | 2 +- src/bar_manager.c | 20 ++++++++++---------- src/bar_manager.h | 2 +- src/message.c | 11 ++++++++++- src/misc/env_vars.h | 7 +++++++ src/misc/helpers.h | 4 ++-- 8 files changed, 54 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 4c54859..439f1eb 100644 --- a/README.md +++ b/README.md @@ -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 +sketchybar -m --trigger [Optional: = ... =] ``` +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. diff --git a/src/bar_item.c b/src/bar_item.c index 4fd0e8b..cbefca3 100644 --- a/src/bar_item.c +++ b/src/bar_item.c @@ -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; } diff --git a/src/bar_item.h b/src/bar_item.h index 311ec19..abb2b51 100644 --- a/src/bar_item.h +++ b/src/bar_item.h @@ -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); diff --git a/src/bar_manager.c b/src/bar_manager.c index 45d49ff..275c9ba 100644 --- a/src/bar_manager.c +++ b/src/bar_manager.c @@ -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) { diff --git a/src/bar_manager.h b/src/bar_manager.h index eddad3a..0701721 100644 --- a/src/bar_manager.h +++ b/src/bar_manager.h @@ -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); diff --git a/src/message.c b/src/message.c index 58633f2..d67f7e6 100644 --- a/src/message.c +++ b/src/message.c @@ -42,7 +42,16 @@ static void handle_domain_subscribe(FILE* rsp, struct token domain, char* messag // Syntax: sketchybar -m --trigger 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 diff --git a/src/misc/env_vars.h b/src/misc/env_vars.h index 66f3ca7..11dd18d 100644 --- a/src/misc/env_vars.h +++ b/src/misc/env_vars.h @@ -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); diff --git a/src/misc/helpers.h b/src/misc/helpers.h index b731f29..b34353d 100644 --- a/src/misc/helpers.h +++ b/src/misc/helpers.h @@ -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