make custom events more powerful (optional)

This commit is contained in:
FelixKratz 2021-08-27 21:57:48 +02:00
parent 7f7539872c
commit 3c948d2659
11 changed files with 96 additions and 11 deletions

View file

@ -176,8 +176,11 @@ where the events are:
### Creating custom events
This allows to define events which are triggered by a different application (see Trigger custom events). Items can also subscribe to these events for their script execution.
```bash
sketchybar -m add event <name>
sketchybar -m add event <name> [optional: <NSDistributedNotificationName>]
```
Optional: You can hook the notifications sent to the NSDistributedNotificationCenter e.g.
the notification Spotify sends on track change: "com.spotify.client.PlaybackStateChanged"
to create more responsive items
### Triggering custom events
This triggers a custom event that has been added before

View file

@ -159,10 +159,12 @@ sketchybar -m set network_up graph_color 0xff48aa2a
sketchybar -m default label_padding_right 15
sketchybar -m default icon_padding_right 4
sketchybar -m add event spotify_change "com.spotify.client.PlaybackStateChanged"
sketchybar -m add item spotifyIndicator center
sketchybar -m set spotifyIndicator update_freq 10
sketchybar -m set spotifyIndicator script "~/.config/sketchybar/plugins/spotifyIndicator.sh"
sketchybar -m set spotifyIndicator click_script "osascript -e 'tell application \"Spotify\" to pause'"
sketchybar -m subscribe spotifyIndicator spotify_change
sketchybar -m update

View file

@ -181,3 +181,10 @@ void bar_manager_handle_system_woke(struct bar_manager* bar_manager) {
bar_manager_check_bar_items_for_update_pattern(bar_manager, UPDATE_SYSTEM_WOKE);
}
void bar_manager_handle_notification(struct bar_manager* bar_manager, char* context) {
char* name = custom_events_get_name_for_notification(&bar_manager->custom_events, context);
if (!name) return;
bar_manager_custom_events_trigger(bar_manager, name);
free(context);
}

View file

@ -30,6 +30,7 @@ void bar_manager_custom_events_trigger(struct bar_manager* bar_manager, char* na
struct bar_item* bar_manager_create_item(struct bar_manager* bar_manager);
void bar_manager_handle_notification(struct bar_manager* bar_manager, char* context);
void bar_manager_script_update(struct bar_manager* bar_manager, bool forced);
void bar_manager_update_components(struct bar_manager* bar_manager, uint32_t did, uint32_t sid);

View file

@ -1,19 +1,44 @@
struct custom_event* custom_event_create(void) {
return malloc(sizeof(struct custom_event));
}
void custom_event_init(struct custom_event* custom_event, char* name, char* notification) {
custom_event->name = name;
custom_event->notification = notification;
}
void custom_events_init(struct custom_events* custom_events) {
custom_events->flag_offset = 4;
custom_events->count = 0;
}
void custom_events_append(struct custom_events* custom_events, char* name) {
void custom_events_append(struct custom_events* custom_events, char* name, char* notification) {
custom_events->count++;
custom_events->names = (char**) realloc(custom_events->names, sizeof(char*) * custom_events->count);
custom_events->names[custom_events->count - 1] = name;
custom_events->events = (struct custom_event**) realloc(custom_events->events, sizeof(struct custom_event*) * custom_events->count);
custom_events->events[custom_events->count - 1] = custom_event_create();
custom_events->events[custom_events->count - 1]->name = name;
custom_events->events[custom_events->count - 1]->notification = notification;
if (notification)
workspace_create_custom_observer(&g_workspace_context, notification);
}
uint32_t custom_events_get_flag_for_name(struct custom_events* custom_events, char* name) {
for (int i = 0; i < custom_events->count; i++) {
if (strcmp(name, custom_events->names[i]) == 0) {
if (strcmp(name, custom_events->events[i]->name) == 0) {
return 1 << (i + custom_events->flag_offset);
}
}
return 0;
}
char* custom_events_get_name_for_notification(struct custom_events* custom_events, char* notification) {
for (int i = 0; i < custom_events->count; i++) {
if (!custom_events->events[i]->notification) continue;
if (strcmp(notification, custom_events->events[i]->notification) == 0) {
return custom_events->events[i]->name;
}
}
return NULL;
}

View file

@ -1,16 +1,24 @@
#ifndef CUSTOM_EVENT_H
#define CUSTOM_EVENT_H
extern void* g_workspace_context;
struct custom_event {
char* name;
char* notification;
};
struct custom_events {
// How many events are reserved for system events
uint32_t flag_offset;
uint32_t count;
char** names;
struct custom_event** events;
};
void custom_event_init(struct custom_event* custom_event, char* name, char* notification);
void custom_events_init(struct custom_events* custom_events);
void custom_events_append(struct custom_events* custom_events, char* name);
void custom_events_trigger(struct custom_events* custom_events, char* name);
void custom_events_append(struct custom_events* custom_events, char* name, char* notification);
uint32_t custom_events_get_flag_for_name(struct custom_events* custom_events, char* name);
char* custom_events_get_name_for_notification(struct custom_events* custom_events, char* notification);
#endif

View file

@ -36,6 +36,14 @@ struct event *event_create_p1(struct event_loop *event_loop, enum event_type typ
return event;
}
static EVENT_CALLBACK(EVENT_HANDLER_DISTRIBUTED_NOTIFICATION)
{
debug("%s\n", context);
bar_manager_handle_notification(&g_bar_manager, context);
return EVENT_SUCCESS;
}
static EVENT_CALLBACK(EVENT_HANDLER_APPLICATION_FRONT_SWITCHED)
{
debug("%s\n", __FUNCTION__);

View file

@ -18,7 +18,7 @@ static EVENT_CALLBACK(EVENT_HANDLER_SYSTEM_WOKE);
static EVENT_CALLBACK(EVENT_HANDLER_SHELL_REFRESH);
static EVENT_CALLBACK(EVENT_HANDLER_DAEMON_MESSAGE);
static EVENT_CALLBACK(EVENT_HANDLER_MOUSE_UP);
static EVENT_CALLBACK(EVENT_HANDLER_DISTRIBUTED_NOTIFICATION);
#define EVENT_QUEUED 0x0
#define EVENT_PROCESSED 0x1
@ -44,6 +44,7 @@ enum event_type
SHELL_REFRESH,
DAEMON_MESSAGE,
MOUSE_UP,
DISTRIBUTED_NOTIFICATION,
EVENT_TYPE_COUNT
};
@ -64,6 +65,7 @@ static const char *event_type_str[] =
[SHELL_REFRESH] = "shell_refresh",
[DAEMON_MESSAGE] = "daemon_message",
[MOUSE_UP] = "mouse_up",
[DISTRIBUTED_NOTIFICATION] = "distributed_notification",
[EVENT_TYPE_COUNT] = "event_type_count"
};
@ -78,6 +80,7 @@ static event_callback *event_handler[] =
[DISPLAY_RESIZED] = EVENT_HANDLER_DISPLAY_RESIZED,
[DISPLAY_CHANGED] = EVENT_HANDLER_DISPLAY_CHANGED,
[MOUSE_UP] = EVENT_HANDLER_MOUSE_UP,
[DISTRIBUTED_NOTIFICATION] = EVENT_HANDLER_DISTRIBUTED_NOTIFICATION,
[MENU_BAR_HIDDEN_CHANGED] = EVENT_HANDLER_MENU_BAR_HIDDEN_CHANGED,
[SYSTEM_WOKE] = EVENT_HANDLER_SYSTEM_WOKE,

View file

@ -253,7 +253,13 @@ static void handle_domain_add(FILE* rsp, struct token domain, char* message) {
if (token_equals(command, COMMAND_ADD_EVENT)) {
struct token event = get_token(&message);
custom_events_append(&g_bar_manager.custom_events, string_copy(token_to_string(event)));
if (message != NULL) {
struct token notification = get_token(&message);
custom_events_append(&g_bar_manager.custom_events, string_copy(token_to_string(event)), string_copy(token_to_string(notification)));
}
else
custom_events_append(&g_bar_manager.custom_events, string_copy(token_to_string(event)), NULL);
return;
}

View file

@ -4,8 +4,10 @@
@interface workspace_context : NSObject {
}
- (id)init;
- (void)addCustomObserver:(NSString *)name;
@end
void workspace_create_custom_observer (void **context, char* notification);
void workspace_event_handler_init(void **context);
void workspace_event_handler_begin(void **context);
void workspace_event_handler_end(void *context);

View file

@ -1,4 +1,5 @@
#include "workspace.h"
#include "misc/helpers.h"
extern struct event_loop g_event_loop;
@ -20,6 +21,11 @@ void workspace_event_handler_end(void *context)
[ws_context dealloc];
}
void workspace_create_custom_observer (void **context, char* notification) {
workspace_context *ws_context = *context;
[ws_context addCustomObserver:@(notification)];
}
@implementation workspace_context
- (id)init
{
@ -49,6 +55,13 @@ void workspace_event_handler_end(void *context)
return self;
}
- (void)addCustomObserver:(NSString *)name {
[[NSDistributedNotificationCenter defaultCenter] addObserver:self
selector:@selector(allDistributedNotifications:)
name:name
object:nil];
}
- (void)dealloc
{
[[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self];
@ -57,6 +70,13 @@ void workspace_event_handler_end(void *context)
[super dealloc];
}
- (void) allDistributedNotifications:(NSNotification *)note
{
char* name = (char*)[[note name] UTF8String];
struct event *event = event_create(&g_event_loop, DISTRIBUTED_NOTIFICATION, string_copy(name));
event_loop_post(&g_event_loop, event);
}
- (void)didWake:(NSNotification *)notification
{
struct event *event = event_create(&g_event_loop, SYSTEM_WOKE, NULL);