better internal event logic

.

.
This commit is contained in:
Felix Kratz 2023-07-19 16:57:08 +02:00
parent 9bcbb81b22
commit c3cd790565
24 changed files with 83 additions and 264 deletions

View file

@ -13,7 +13,7 @@ SRC = src
_OBJ = alias.o background.o bar_item.o custom_events.o event.o graph.o \
image.o mouse.o shadow.o font.o text.o message.o mouse.o bar.o color.o \
window.o bar_manager.o display.o event_loop.o group.o mach.o popup.o \
window.o bar_manager.o display.o group.o mach.o popup.o \
animation.o workspace.om volume.o slider.o power.o wifi.om media.om \
hotload.o

View file

@ -2,8 +2,8 @@
#include "event.h"
static ANIMATOR_CALLBACK(animator_handler) {
struct event *event = event_create(&g_event_loop, ANIMATOR_REFRESH, NULL);
event_loop_post(&g_event_loop, event);
struct event event = { NULL, 0, ANIMATOR_REFRESH };
event_post(&event);
}
struct animation* animation_create() {

View file

@ -100,8 +100,6 @@ struct animation {
struct animation* animation_create();
void animation_setup(struct animation* animation, void* target, animator_function* update_function, int initial_value, int final_value, uint32_t duration, char interp_function);
extern struct event_loop g_event_loop;
#define ANIMATOR_CALLBACK(name) void name(CFRunLoopTimerRef timer, void *context)
typedef ANIMATOR_CALLBACK(animator_callback);

View file

@ -1,7 +1,6 @@
#include "bar.h"
#include "bar_manager.h"
#include "event.h"
#include "event_loop.h"
#include "display.h"
#include "misc/helpers.h"
#include "window.h"

View file

@ -1,6 +1,5 @@
#include "bar_item.h"
#include "bar_manager.h"
#include "event_loop.h"
#include "event.h"
#include "volume.h"
#include "power.h"

View file

@ -1,19 +1,17 @@
#include "bar_manager.h"
#include "bar_item.h"
#include "event.h"
#include "event_loop.h"
#include "misc/env_vars.h"
#include "misc/helpers.h"
#include "wifi.h"
#include "volume.h"
#include "power.h"
extern struct event_loop g_event_loop;
extern void forced_front_app_event();
static CLOCK_CALLBACK(clock_handler) {
struct event *event = event_create(&g_event_loop, SHELL_REFRESH, NULL);
event_loop_post(&g_event_loop, event);
struct event event = { NULL, 0, SHELL_REFRESH };
event_post(&event);
}
void bar_manager_init(struct bar_manager* bar_manager) {

View file

@ -1,7 +1,6 @@
#include "display.h"
extern int workspace_display_notch_height(uint32_t did);
extern struct event_loop g_event_loop;
extern int g_connection;
extern bool g_brightness_events;
@ -13,11 +12,8 @@ static void brightness_handler(void* notification_center, uint32_t did, void* na
DisplayServicesGetBrightness(did, brightness);
if (g_last_brightness < *brightness - 1e-2 || g_last_brightness > *brightness + 1e-2) {
g_last_brightness = *brightness;
struct event *event = event_create(&g_event_loop,
BRIGHTNESS_CHANGED,
(void *) brightness);
event_loop_post(&g_event_loop, event);
struct event event = { (void*) brightness, 0, BRIGHTNESS_CHANGED };
event_post(&event);
} else {
free(brightness);
}
@ -25,33 +21,23 @@ static void brightness_handler(void* notification_center, uint32_t did, void* na
static DISPLAY_EVENT_HANDLER(display_handler) {
if (flags & kCGDisplayAddFlag) {
struct event *event = event_create(&g_event_loop,
DISPLAY_ADDED,
(void *)(intptr_t) did);
struct event event = { (void *)(intptr_t) did, 0, DISPLAY_ADDED };
event_post(&event);
event_loop_post(&g_event_loop, event);
if (g_brightness_events && DisplayServicesCanChangeBrightness(did))
DisplayServicesRegisterForBrightnessChangeNotifications(did, did, (void*)brightness_handler);
} else if (flags & kCGDisplayRemoveFlag) {
struct event *event = event_create(&g_event_loop,
DISPLAY_REMOVED,
(void *)(intptr_t) did);
struct event event = { (void *)(intptr_t) did, 0, DISPLAY_REMOVED };
event_post(&event);
event_loop_post(&g_event_loop, event);
if (g_brightness_events && DisplayServicesCanChangeBrightness(did))
DisplayServicesUnregisterForBrightnessChangeNotifications(did, did);
} else if (flags & kCGDisplayMovedFlag) {
struct event *event = event_create(&g_event_loop,
DISPLAY_MOVED,
(void *)(intptr_t) did);
event_loop_post(&g_event_loop, event);
struct event event = { (void *)(intptr_t) did, 0, DISPLAY_MOVED };
event_post(&event);
} else if (flags & kCGDisplayDesktopShapeChangedFlag) {
struct event *event = event_create(&g_event_loop,
DISPLAY_RESIZED,
(void *)(intptr_t) did);
event_loop_post(&g_event_loop, event);
struct event event = { (void *)(intptr_t) did, 0, DISPLAY_RESIZED };
event_post(&event);
}
}

View file

@ -1,6 +1,5 @@
#pragma once
#include "event.h"
#include "event_loop.h"
#include "misc/helpers.h"
#define DISPLAY_EVENT_HANDLER(name) void name(uint32_t did, CGDisplayChangeSummaryFlags flags, void *context)

View file

@ -1,8 +1,6 @@
#include "event.h"
#include "event_loop.h"
#include "hotload.h"
extern struct event_loop g_event_loop;
extern struct bar_manager g_bar_manager;
extern int g_connection;
@ -13,12 +11,9 @@ enum event_type event_type_from_string(const char *str) {
return EVENT_TYPE_UNKNOWN;
}
struct event *event_create(struct event_loop *event_loop, enum event_type type, void *context) {
struct event *event = memory_pool_push(&event_loop->pool, struct event);
event->type = type;
event->context = context;
event->info = 0;
return event;
void event_post(struct event *event) {
event_handler[event->type](event->context);
windows_unfreeze();
}
EVENT_CALLBACK(EVENT_HANDLER_DISTRIBUTED_NOTIFICATION) {

View file

@ -4,8 +4,6 @@
#include "bar_manager.h"
#include "message.h"
struct event_loop;
#define EVENT_CALLBACK(name) uint32_t name(void *context)
typedef EVENT_CALLBACK(event_callback);
@ -35,15 +33,8 @@ EVENT_CALLBACK(EVENT_HANDLER_MEDIA_CHANGED);
EVENT_CALLBACK(EVENT_HANDLER_DISTRIBUTED_NOTIFICATION);
EVENT_CALLBACK(EVENT_HANDLER_HOTLOAD);
#define EVENT_QUEUED 0x0
#define EVENT_PROCESSED 0x1
#define EVENT_SUCCESS 0x0
#define EVENT_FAILURE 0x1
#define EVENT_MOUSE_IGNORE 0x2
#define event_status(e) ((e) & 0x1)
#define event_result(e) ((e) >> 0x1)
enum event_type {
EVENT_TYPE_UNKNOWN,
@ -143,6 +134,5 @@ struct event {
enum event_type type;
};
struct event *event_create(struct event_loop *event_loop, enum event_type type, void *context);
void event_destroy(struct event_loop *event_loop, struct event *event);
enum event_type event_type_from_string(const char *str);
void event_post(struct event *event);

View file

@ -1,87 +0,0 @@
#include "event_loop.h"
#include "event.h"
static bool queue_init(struct queue *queue) {
if (!memory_pool_init(&queue->pool, QUEUE_POOL_SIZE)) return false;
queue->head = memory_pool_push(&queue->pool, struct queue_item);
queue->head->data = NULL;
queue->head->next = NULL;
queue->tail = queue->head;
return true;
};
static void queue_push(struct queue *queue, struct event *event) {
bool success;
struct queue_item *tail, *new_tail;
new_tail = memory_pool_push(&queue->pool, struct queue_item);
new_tail->data = event;
new_tail->next = NULL;
__asm__ __volatile__ ("" ::: "memory");
do {
tail = queue->tail;
success = __sync_bool_compare_and_swap(&tail->next, NULL, new_tail);
if (!success) __sync_bool_compare_and_swap(&queue->tail, tail, tail->next);
} while (!success);
__sync_bool_compare_and_swap(&queue->tail, tail, new_tail);
}
static struct event *queue_pop(struct queue *queue) {
struct queue_item *head;
do {
head = queue->head;
if (!head->next) return NULL;
} while (!__sync_bool_compare_and_swap(&queue->head, head, head->next));
return head->next->data;
}
static void *event_loop_run(void *context) {
struct event_loop *event_loop = (struct event_loop *) context;
struct queue *queue = (struct queue *) &event_loop->queue;
while (event_loop->is_running) {
struct event *event = queue_pop(queue);
if (event) {
uint32_t result = event_handler[event->type](event->context);
windows_unfreeze();
if (event->info) *event->info = (result << 0x1) | EVENT_PROCESSED;
} else {
sem_wait(event_loop->semaphore);
}
}
return NULL;
}
void event_loop_post(struct event_loop *event_loop, struct event *event) {
assert(event_loop->is_running);
queue_push(&event_loop->queue, event);
sem_post(event_loop->semaphore);
}
bool event_loop_init(struct event_loop *event_loop) {
if (!queue_init(&event_loop->queue)) return false;
if (!memory_pool_init(&event_loop->pool, EVENT_POOL_SIZE)) return false;
event_loop->is_running = false;
event_loop->semaphore = sem_open("skybar_event_loop_semaphore", O_CREAT, 0600, 0);
sem_unlink("skybar_event_loop_semaphore");
return event_loop->semaphore != SEM_FAILED;
}
bool event_loop_begin(struct event_loop *event_loop) {
if (event_loop->is_running) return false;
event_loop->is_running = true;
pthread_create(&event_loop->thread, NULL, &event_loop_run, event_loop);
return true;
}
bool event_loop_end(struct event_loop *event_loop) {
if (!event_loop->is_running) return false;
event_loop->is_running = false;
pthread_join(event_loop->thread, NULL);
return true;
}

View file

@ -1,36 +0,0 @@
#pragma once
#include <semaphore.h>
#include <pthread.h>
#include "misc/memory_pool.h"
struct event;
#define EVENT_POOL_SIZE KILOBYTES(128)
#define EVENT_MAX_COUNT ((EVENT_POOL_SIZE) / (sizeof(struct event)))
#define QUEUE_POOL_SIZE KILOBYTES(16)
#define QUEUE_MAX_COUNT ((QUEUE_POOL_SIZE) / (sizeof(struct queue_item)))
struct queue_item {
struct event *data;
struct queue_item *next;
};
struct queue {
struct memory_pool pool;
struct queue_item *head;
struct queue_item *tail;
};
struct event_loop {
bool is_running;
pthread_t thread;
sem_t *semaphore;
struct queue queue;
struct memory_pool pool;
};
bool event_loop_init(struct event_loop *event_loop);
bool event_loop_begin(struct event_loop *event_loop);
bool event_loop_end(struct event_loop *event_loop);
void event_loop_post(struct event_loop *event_loop, struct event *event);

View file

@ -75,8 +75,8 @@ static void handler(ConstFSEventStreamRef stream,
const FSEventStreamEventFlags* flags,
const FSEventStreamEventId* ids) {
if (g_hotload && count > 0) {
struct event *event = event_create(&g_event_loop, HOTLOAD, NULL);
event_loop_post(&g_event_loop, event);
struct event event = { NULL, 0, HOTLOAD };
event_post(&event);
}
}

View file

@ -1,7 +1,4 @@
#include "event.h"
#include "event_loop.h"
extern struct event_loop g_event_loop;
extern void MRMediaRemoteRegisterForNowPlayingNotifications(dispatch_queue_t queue);
extern void MRMediaRemoteGetNowPlayingInfo(dispatch_queue_t queue, void (^block)(NSDictionary* dict));
@ -80,10 +77,8 @@ bool g_media_events = false;
char* payload_info = malloc(info_len);
memcpy(payload_info, info, info_len);
struct event *event = event_create(&g_event_loop,
MEDIA_CHANGED,
payload_info );
event_loop_post(&g_event_loop, event);
struct event event = { payload_info, 0, MEDIA_CHANGED };
event_post(&event);
}
}
}

View file

@ -2,7 +2,6 @@
#include "misc/defines.h"
#include "hotload.h"
extern struct event_loop g_event_loop;
extern struct bar_manager g_bar_manager;
static struct bar_item** get_bar_items_for_regex(struct token reg, FILE* rsp, uint32_t* count) {
@ -714,8 +713,8 @@ void handle_message_mach(struct mach_buffer* buffer) {
free(rbr_msg);
if (reload) {
struct event *event = event_create(&g_event_loop, HOTLOAD, NULL);
event_loop_post(&g_event_loop, event);
struct event event = { NULL, 0, HOTLOAD };
event_post(&event);
}
} else {
char* rbr_msg = get_batch_line(&message);
@ -745,6 +744,6 @@ void handle_message_mach(struct mach_buffer* buffer) {
}
MACH_HANDLER(mach_message_handler) {
struct event *event = event_create(&g_event_loop, MACH_MESSAGE, message);
event_loop_post(&g_event_loop, event);
struct event event = { message, 0, MACH_MESSAGE };
event_post(&event);
}

View file

@ -10,7 +10,6 @@
#include "slider.h"
#include "mach.h"
#include "event.h"
#include "event_loop.h"
#include "misc/helpers.h"
#include "misc/defines.h"

View file

@ -1,8 +1,6 @@
#include <Carbon/Carbon.h>
#include "mouse.h"
extern struct event_loop g_event_loop;
static const EventTypeSpec mouse_events [] = {
{ kEventClassMouse, kEventMouseDown },
{ kEventClassMouse, kEventMouseUp },
@ -16,41 +14,47 @@ static const EventTypeSpec mouse_events [] = {
static pascal OSStatus mouse_handler(EventHandlerCallRef next, EventRef e, void *data) {
switch (GetEventKind(e)) {
case kEventMouseUp: {
struct event *event = event_create(&g_event_loop,
MOUSE_UP,
(void *) CFRetain(CopyEventCGEvent(e)));
struct event event = { (void *) CopyEventCGEvent(e),
0,
MOUSE_UP };
event_loop_post(&g_event_loop, event);
event_post(&event);
break;
}
case kEventMouseDragged: {
struct event *event = event_create(&g_event_loop,
MOUSE_DRAGGED,
(void *) CFRetain(CopyEventCGEvent(e)));
CGEventRef cg_event = CopyEventCGEvent(e);
struct event event = { (void *) cg_event,
0,
MOUSE_DRAGGED };
event_loop_post(&g_event_loop, event);
event_post(&event);
break;
}
case kEventMouseEntered: {
struct event *event = event_create(&g_event_loop,
MOUSE_ENTERED,
(void *) CFRetain(CopyEventCGEvent(e)));
CGEventRef cg_event = CopyEventCGEvent(e);
struct event event = { (void *) cg_event,
0,
MOUSE_ENTERED };
event_loop_post(&g_event_loop, event);
event_post(&event);
break;
}
case kEventMouseExited: {
struct event *event = event_create(&g_event_loop,
MOUSE_EXITED,
(void *) CFRetain(CopyEventCGEvent(e)));
event_loop_post(&g_event_loop, event);
CGEventRef cg_event = CopyEventCGEvent(e);
struct event event = { (void *) cg_event,
0,
MOUSE_EXITED };
event_post(&event);
break;
}
case kEventMouseWheelMoved: {
struct event *event = event_create(&g_event_loop,
MOUSE_SCROLLED,
(void *) CFRetain(CopyEventCGEvent(e)));
event_loop_post(&g_event_loop, event);
CGEventRef cg_event = CopyEventCGEvent(e);
struct event event = { (void *) cg_event,
0,
MOUSE_SCROLLED };
event_post(&event);
break;
}
default:

View file

@ -1,5 +1,4 @@
#pragma once
#include "event_loop.h"
#include "event.h"
void mouse_begin(void);

View file

@ -12,22 +12,17 @@ void power_handler(void* context) {
g_power_source = POWER_AC;
char* source = malloc(sizeof(char)*8);
snprintf(source, 8, "AC");
struct event *event = event_create(&g_event_loop,
POWER_SOURCE_CHANGED,
(void *) source);
event_loop_post(&g_event_loop, event);
struct event event = { (void*) source, 0, POWER_SOURCE_CHANGED };
event_post(&event);
}
} else if (CFStringCompare(type, POWER_BATTERY_KEY, 0) == 0) {
if (g_power_source != POWER_BATTERY) {
g_power_source = POWER_BATTERY;
char* source = malloc(sizeof(char)*8);
snprintf(source, 8, "BATTERY");
struct event *event = event_create(&g_event_loop,
POWER_SOURCE_CHANGED,
(void *) source);
event_loop_post(&g_event_loop, event);
struct event event = { (void*) source, 0, POWER_SOURCE_CHANGED };
event_post(&event);
}
}
CFRelease(info);

View file

@ -1,6 +1,5 @@
#include "bar_manager.h"
#include "workspace.h"
#include "event_loop.h"
#include "mach.h"
#include "mouse.h"
#include "message.h"
@ -37,7 +36,6 @@ int g_connection;
CFTypeRef g_transaction;
struct bar_manager g_bar_manager;
struct event_loop g_event_loop;
struct mach_server g_mach_server;
void *g_workspace_context;
@ -182,9 +180,6 @@ int main(int argc, char **argv) {
init_misc_settings();
acquire_lockfile();
if (!event_loop_init(&g_event_loop))
error("%s: could not initialize event_loop! abort..\n", g_name);
SLSRegisterNotifyProc((void*)system_events, 904, NULL);
SLSRegisterNotifyProc((void*)system_events, 905, NULL);
SLSRegisterNotifyProc((void*)system_events, 1401, NULL);
@ -194,7 +189,6 @@ int main(int argc, char **argv) {
workspace_event_handler_init(&g_workspace_context);
bar_manager_init(&g_bar_manager);
event_loop_begin(&g_event_loop);
mouse_begin();
display_begin();
workspace_event_handler_begin(&g_workspace_context);

View file

@ -83,11 +83,8 @@ static OSStatus handler(AudioObjectID id, uint32_t address_count, const AudioObj
if (*volume > g_last_volume + 1e-2 || *volume < g_last_volume - 1e-2) {
g_last_volume = *volume;
struct event *event = event_create(&g_event_loop,
VOLUME_CHANGED,
(void *) volume);
event_loop_post(&g_event_loop, event);
struct event event = { (void*) volume, 0, VOLUME_CHANGED };
event_post(&event);
} else {
free(volume);
}

View file

@ -2,7 +2,6 @@
#include <SystemConfiguration/SystemConfiguration.h>
#include "wifi.h"
#include "event.h"
#include "event_loop.h"
char* g_current_ssid = NULL;
void update_ssid(SCDynamicStoreRef store, CFArrayRef keys, void* info) {
@ -16,11 +15,8 @@ void update_ssid(SCDynamicStoreRef store, CFArrayRef keys, void* info) {
if (g_current_ssid) free(g_current_ssid);
g_current_ssid = string_copy(ssid);
struct event *event = event_create(&g_event_loop,
WIFI_CHANGED,
(void *) ssid );
event_loop_post(&g_event_loop, event);
struct event event = { (void*) ssid, 0, WIFI_CHANGED };
event_post(&event);
} else {
free(ssid);
}

View file

@ -1,6 +1,5 @@
#pragma once
#include "event.h"
#include "event_loop.h"
void workspace_create_custom_observer (void **context, char* notification);
void workspace_event_handler_init(void **context);

View file

@ -8,8 +8,6 @@
- (void)addCustomObserver:(NSString *)name;
@end
extern struct event_loop g_event_loop;
void workspace_event_handler_init(void **context) {
workspace_context *ws_context = [workspace_context alloc];
*context = ws_context;
@ -54,8 +52,11 @@ void forced_front_app_event() {
@autoreleasepool {
NSString* name = [[[NSWorkspace sharedWorkspace] frontmostApplication] localizedName];
const char* front_app = [name cStringUsingEncoding:NSUTF8StringEncoding];
struct event *event = event_create(&g_event_loop, APPLICATION_FRONT_SWITCHED, string_copy((char*)front_app));
event_loop_post(&g_event_loop, event);
struct event event = { string_copy((char*)front_app),
0,
APPLICATION_FRONT_SWITCHED };
event_post(&event);
}
}
@ -129,19 +130,19 @@ CGImageRef workspace_icon_for_app(char* app) {
}
}
struct event *event = event_create(&g_event_loop, DISTRIBUTED_NOTIFICATION, notification);
event_loop_post(&g_event_loop, event);
struct event event = { notification, 0, DISTRIBUTED_NOTIFICATION };
event_post(&event);
}
}
- (void)willSleep:(NSNotification *)notification {
struct event *event = event_create(&g_event_loop, SYSTEM_WILL_SLEEP, NULL);
event_loop_post(&g_event_loop, event);
struct event event = { NULL, 0, SYSTEM_WILL_SLEEP };
event_post(&event);
}
- (void)didWake:(NSNotification *)notification {
struct event *event = event_create(&g_event_loop, SYSTEM_WOKE, NULL);
event_loop_post(&g_event_loop, event);
struct event event = { NULL, 0, SYSTEM_WOKE };
event_post(&event);
}
- (void)appSwitched:(NSNotification *)notification {
@ -151,24 +152,24 @@ CGImageRef workspace_icon_for_app(char* app) {
NSRunningApplication* app = [notification.userInfo objectForKey:NSWorkspaceApplicationKey];
if (app) name = string_copy((char*)[[app localizedName] UTF8String]);
}
struct event *event = event_create(&g_event_loop, APPLICATION_FRONT_SWITCHED, name);
event_loop_post(&g_event_loop, event);
struct event event = { name, 0, APPLICATION_FRONT_SWITCHED };
event_post(&event);
}
}
- (void)didChangeMenuBarHiding:(NSNotification *)notification {
struct event *event = event_create(&g_event_loop, MENU_BAR_HIDDEN_CHANGED, NULL);
event_loop_post(&g_event_loop, event);
struct event event = { NULL, 0, MENU_BAR_HIDDEN_CHANGED };
event_post(&event);
}
- (void)activeDisplayDidChange:(NSNotification *)notification {
struct event *event = event_create(&g_event_loop, DISPLAY_CHANGED, NULL);
event_loop_post(&g_event_loop, event);
struct event event = { NULL, 0, DISPLAY_CHANGED };
event_post(&event);
}
- (void)activeSpaceDidChange:(NSNotification *)notification {
struct event *event = event_create(&g_event_loop, SPACE_CHANGED, NULL);
event_loop_post(&g_event_loop, event);
struct event event = { NULL, 0, SPACE_CHANGED };
event_post(&event);
}
@end