mirror of
https://github.com/FelixKratz/SketchyBar
synced 2024-11-27 13:50:33 +00:00
delete A LOT of unneeded bulk
This commit is contained in:
parent
127824f012
commit
2a0dadef49
12 changed files with 4 additions and 611 deletions
|
@ -1,95 +0,0 @@
|
|||
#include "application.h"
|
||||
|
||||
extern struct event_loop g_event_loop;
|
||||
|
||||
static OBSERVER_CALLBACK(application_notification_handler)
|
||||
{
|
||||
if (CFEqual(notification, kAXFocusedWindowChangedNotification)) {
|
||||
uint32_t window_id = ax_window_id(element);
|
||||
if (!window_id) return;
|
||||
|
||||
struct event *event = event_create(&g_event_loop, WINDOW_FOCUSED, (void *)(intptr_t) window_id);
|
||||
event_loop_post(&g_event_loop, event);
|
||||
} else if (CFEqual(notification, kAXTitleChangedNotification)) {
|
||||
uint32_t window_id = ax_window_id(element);
|
||||
if (!window_id) return;
|
||||
|
||||
struct event *event = event_create(&g_event_loop, WINDOW_TITLE_CHANGED, (void *)(intptr_t) window_id);
|
||||
event_loop_post(&g_event_loop, event);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
application_observe_notification(struct application *application, int notification)
|
||||
{
|
||||
AXError result = AXObserverAddNotification(application->observer_ref, application->ref, ax_application_notification[notification], application);
|
||||
if (result == kAXErrorSuccess || result == kAXErrorNotificationAlreadyRegistered) {
|
||||
application->notification |= 1 << notification;
|
||||
} else if (result != kAXErrorNotImplemented) {
|
||||
application->retry = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
application_unobserve_notification(struct application *application, int notification)
|
||||
{
|
||||
AXObserverRemoveNotification(application->observer_ref, application->ref, ax_application_notification[notification]);
|
||||
application->notification &= ~(1 << notification);
|
||||
}
|
||||
|
||||
bool application_observe(struct application *application)
|
||||
{
|
||||
if (AXObserverCreate(application->pid, application_notification_handler, &application->observer_ref) == kAXErrorSuccess) {
|
||||
for (int i = 0; i < array_count(ax_application_notification); ++i) {
|
||||
application_observe_notification(application, i);
|
||||
}
|
||||
|
||||
application->is_observing = true;
|
||||
CFRunLoopAddSource(CFRunLoopGetMain(), AXObserverGetRunLoopSource(application->observer_ref), kCFRunLoopDefaultMode);
|
||||
}
|
||||
|
||||
return (application->notification & AX_APPLICATION_ALL) == AX_APPLICATION_ALL;
|
||||
}
|
||||
|
||||
void application_unobserve(struct application *application)
|
||||
{
|
||||
if (application->is_observing) {
|
||||
for (int i = 0; i < array_count(ax_application_notification); ++i) {
|
||||
if (!(application->notification & (1 << i))) continue;
|
||||
application_unobserve_notification(application, i);
|
||||
}
|
||||
|
||||
application->is_observing = false;
|
||||
CFRunLoopSourceInvalidate(AXObserverGetRunLoopSource(application->observer_ref));
|
||||
CFRelease(application->observer_ref);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t application_focused_window(struct application *application)
|
||||
{
|
||||
CFTypeRef window_ref = NULL;
|
||||
AXUIElementCopyAttributeValue(application->ref, kAXFocusedWindowAttribute, &window_ref);
|
||||
if (!window_ref) return 0;
|
||||
|
||||
uint32_t window_id = ax_window_id(window_ref);
|
||||
CFRelease(window_ref);
|
||||
|
||||
return window_id;
|
||||
}
|
||||
|
||||
struct application *application_create(struct process *process)
|
||||
{
|
||||
struct application *application = malloc(sizeof(struct application));
|
||||
memset(application, 0, sizeof(struct application));
|
||||
application->ref = AXUIElementCreateApplication(process->pid);
|
||||
application->psn = process->psn;
|
||||
application->pid = process->pid;
|
||||
application->name = process->name;
|
||||
return application;
|
||||
}
|
||||
|
||||
void application_destroy(struct application *application)
|
||||
{
|
||||
CFRelease(application->ref);
|
||||
free(application);
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
#ifndef APPLICATION_H
|
||||
#define APPLICATION_H
|
||||
|
||||
#define OBSERVER_CALLBACK(name) void name(AXObserverRef observer, AXUIElementRef element, CFStringRef notification, void *context)
|
||||
typedef OBSERVER_CALLBACK(observer_callback);
|
||||
|
||||
#define AX_APPLICATION_WINDOW_FOCUSED_INDEX 0
|
||||
#define AX_APPLICATION_WINDOW_TITLE_CHANGED_INDEX 1
|
||||
|
||||
#define AX_APPLICATION_WINDOW_FOCUSED (1 << AX_APPLICATION_WINDOW_FOCUSED_INDEX)
|
||||
#define AX_APPLICATION_WINDOW_TITLE_CHANGED (1 << AX_APPLICATION_WINDOW_TITLE_CHANGED_INDEX)
|
||||
#define AX_APPLICATION_ALL (AX_APPLICATION_WINDOW_FOCUSED |\
|
||||
AX_APPLICATION_WINDOW_TITLE_CHANGED)
|
||||
static CFStringRef ax_application_notification[] =
|
||||
{
|
||||
[AX_APPLICATION_WINDOW_FOCUSED_INDEX] = kAXFocusedWindowChangedNotification,
|
||||
[AX_APPLICATION_WINDOW_TITLE_CHANGED_INDEX] = kAXTitleChangedNotification,
|
||||
};
|
||||
|
||||
struct application
|
||||
{
|
||||
AXUIElementRef ref;
|
||||
ProcessSerialNumber psn;
|
||||
uint32_t pid;
|
||||
char *name;
|
||||
AXObserverRef observer_ref;
|
||||
uint8_t notification;
|
||||
bool is_observing;
|
||||
bool retry;
|
||||
};
|
||||
|
||||
uint32_t application_focused_window(struct application *application);
|
||||
bool application_observe(struct application *application);
|
||||
void application_unobserve(struct application *application);
|
||||
struct application *application_create(struct process *process);
|
||||
void application_destroy(struct application *application);
|
||||
|
||||
#endif
|
|
@ -1,81 +0,0 @@
|
|||
#include "application_manager.h"
|
||||
|
||||
extern struct process_manager g_process_manager;
|
||||
extern struct mouse_state g_mouse_state;
|
||||
extern char g_sa_socket_file[MAXLEN];
|
||||
|
||||
static TABLE_HASH_FUNC(hash_application)
|
||||
{
|
||||
unsigned long result = *(uint32_t *) key;
|
||||
result = (result + 0x7ed55d16) + (result << 12);
|
||||
result = (result ^ 0xc761c23c) ^ (result >> 19);
|
||||
result = (result + 0x165667b1) + (result << 5);
|
||||
result = (result + 0xd3a2646c) ^ (result << 9);
|
||||
result = (result + 0xfd7046c5) + (result << 3);
|
||||
result = (result ^ 0xb55a4f09) ^ (result >> 16);
|
||||
return result;
|
||||
}
|
||||
|
||||
static TABLE_COMPARE_FUNC(compare_application)
|
||||
{
|
||||
return *(uint32_t *) key_a == *(uint32_t *) key_b;
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
struct application *application_manager_focused_application(struct application_manager *application_manager)
|
||||
{
|
||||
ProcessSerialNumber psn = {};
|
||||
_SLPSGetFrontProcess(&psn);
|
||||
|
||||
pid_t pid;
|
||||
GetProcessPID(&psn, &pid);
|
||||
|
||||
return application_manager_find_application(application_manager, pid);
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
struct application *application_manager_find_application(struct application_manager *application_manager, pid_t pid)
|
||||
{
|
||||
return table_find(&application_manager->application, &pid);
|
||||
}
|
||||
|
||||
void application_manager_remove_application(struct application_manager *application_manager, pid_t pid)
|
||||
{
|
||||
table_remove(&application_manager->application, &pid);
|
||||
}
|
||||
|
||||
void application_manager_add_application(struct application_manager *application_manager, struct application *application)
|
||||
{
|
||||
table_add(&application_manager->application, &application->pid, application);
|
||||
}
|
||||
|
||||
void application_manager_init(struct application_manager *application_manager)
|
||||
{
|
||||
application_manager->system_element = AXUIElementCreateSystemWide();
|
||||
AXUIElementSetMessagingTimeout(application_manager->system_element, 1.0);
|
||||
|
||||
table_init(&application_manager->application, 150, hash_application, compare_application);
|
||||
}
|
||||
|
||||
void application_manager_begin(struct application_manager *application_manager)
|
||||
{
|
||||
for (int process_index = 0; process_index < g_process_manager.process.capacity; ++process_index) {
|
||||
struct bucket *bucket = g_process_manager.process.buckets[process_index];
|
||||
while (bucket) {
|
||||
if (bucket->value) {
|
||||
struct process *process = bucket->value;
|
||||
struct application *application = application_create(process);
|
||||
|
||||
if (application_observe(application)) {
|
||||
application_manager_add_application(application_manager, application);
|
||||
} else {
|
||||
application_unobserve(application);
|
||||
application_destroy(application);
|
||||
}
|
||||
}
|
||||
|
||||
bucket = bucket->next;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
#ifndef APPLICATION_MANAGER_H
|
||||
#define APPLICATION_MANAGER_H
|
||||
|
||||
extern CFTypeRef SLSWindowQueryWindows(int cid, CFArrayRef windows, int count);
|
||||
extern CFTypeRef SLSWindowQueryResultCopyWindows(CFTypeRef window_query);
|
||||
extern CGError SLSWindowIteratorAdvance(CFTypeRef iterator);
|
||||
extern uint32_t SLSWindowIteratorGetParentID(CFTypeRef iterator);
|
||||
extern uint32_t SLSWindowIteratorGetWindowID(CFTypeRef iterator);
|
||||
extern OSStatus _SLPSGetFrontProcess(ProcessSerialNumber *psn);
|
||||
extern CGError SLSGetWindowOwner(int cid, uint32_t wid, int *wcid);
|
||||
extern CGError SLSGetConnectionPSN(int cid, ProcessSerialNumber *psn);
|
||||
extern CGError SLSConnectionGetPID(int cid, pid_t *pid);
|
||||
extern CGError _SLPSSetFrontProcessWithOptions(ProcessSerialNumber *psn, uint32_t wid, uint32_t mode);
|
||||
extern CGError SLPSPostEventRecordTo(ProcessSerialNumber *psn, uint8_t *bytes);
|
||||
extern OSStatus SLSFindWindowByGeometry(int cid, int zero, int one, int zero_again, CGPoint *screen_point, CGPoint *window_point, uint32_t *wid, int *wcid);
|
||||
extern CGError SLSGetCurrentCursorLocation(int cid, CGPoint *point);
|
||||
|
||||
#define kCPSAllWindows 0x100
|
||||
#define kCPSUserGenerated 0x200
|
||||
#define kCPSNoWindows 0x400
|
||||
|
||||
struct application_manager
|
||||
{
|
||||
AXUIElementRef system_element;
|
||||
struct table application;
|
||||
};
|
||||
|
||||
struct application *application_manager_focused_application(struct application_manager *application_manager);
|
||||
struct application *application_manager_find_application(struct application_manager *application_manager, pid_t pid);
|
||||
void application_manager_remove_application(struct application_manager *application_manager, pid_t pid);
|
||||
void application_manager_add_application(struct application_manager *application_manager, struct application *application);
|
||||
void application_manager_begin(struct application_manager *application_manager);
|
||||
void application_manager_init(struct application_manager *application_manager);
|
||||
|
||||
#endif
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef DISPLAY_MANAGER_H
|
||||
#define DISPLAY_MANAGER_H
|
||||
|
||||
extern CFStringRef SLSCopyBestManagedDisplayForRect(int cid, CGRect rect);
|
||||
extern CGError SLSGetCurrentCursorLocation(int cid, CGPoint *point);
|
||||
extern CFStringRef SLSCopyActiveMenuBarDisplayIdentifier(int cid);
|
||||
extern CFStringRef SLSCopyBestManagedDisplayForPoint(int cid, CGPoint point);
|
||||
extern bool SLSManagedDisplayIsAnimating(int cid, CFStringRef uuid);
|
||||
|
|
68
src/event.c
68
src/event.c
|
@ -4,7 +4,6 @@ extern struct event_loop g_event_loop;
|
|||
extern struct process_manager g_process_manager;
|
||||
extern struct display_manager g_display_manager;
|
||||
extern struct bar_manager g_bar_manager;
|
||||
extern struct application_manager g_application_manager;
|
||||
extern struct mouse_state g_mouse_state;
|
||||
extern struct window_manager g_window_manager;
|
||||
extern int g_connection;
|
||||
|
@ -46,73 +45,6 @@ struct event *event_create_p1(struct event_loop *event_loop, enum event_type typ
|
|||
return event;
|
||||
}
|
||||
|
||||
void event_destroy(struct event_loop *event_loop, struct event *event)
|
||||
{
|
||||
switch (event->type) {
|
||||
default: break;
|
||||
case APPLICATION_TERMINATED: {
|
||||
process_destroy(event->context);
|
||||
} break;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
uint64_t count = __sync_sub_and_fetch(&event_loop->count, 1);
|
||||
assert(count >= 0 && count < EVENT_MAX_COUNT);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static EVENT_CALLBACK(EVENT_HANDLER_APPLICATION_LAUNCHED)
|
||||
{
|
||||
struct process *process = context;
|
||||
debug("%s: %s\n", __FUNCTION__, process->name);
|
||||
|
||||
if ((process->terminated) || (kill(process->pid, 0) == -1)) {
|
||||
debug("%s: %s terminated during launch\n", __FUNCTION__, process->name);
|
||||
return EVENT_FAILURE;
|
||||
}
|
||||
|
||||
struct application *application = application_create(process);
|
||||
if (application_observe(application)) {
|
||||
application_manager_add_application(&g_application_manager, application);
|
||||
|
||||
return EVENT_SUCCESS;
|
||||
} else {
|
||||
bool retry_ax = application->retry;
|
||||
application_unobserve(application);
|
||||
application_destroy(application);
|
||||
debug("%s: could not observe %s (%d)\n", __FUNCTION__, process->name, retry_ax);
|
||||
|
||||
if (retry_ax) {
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.01f * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
|
||||
struct event *event = event_create(&g_event_loop, APPLICATION_LAUNCHED, process);
|
||||
event_loop_post(&g_event_loop, event);
|
||||
});
|
||||
}
|
||||
|
||||
return EVENT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
static EVENT_CALLBACK(EVENT_HANDLER_APPLICATION_TERMINATED)
|
||||
{
|
||||
struct process *process = context;
|
||||
struct application *application = application_manager_find_application(&g_application_manager, process->pid);
|
||||
|
||||
if (!application) {
|
||||
debug("%s: %s (not observed)\n", __FUNCTION__, process->name);
|
||||
return EVENT_FAILURE;
|
||||
}
|
||||
|
||||
debug("%s: %s\n", __FUNCTION__, process->name);
|
||||
application_manager_remove_application(&g_application_manager, application->pid);
|
||||
|
||||
application_unobserve(application);
|
||||
application_destroy(application);
|
||||
|
||||
return EVENT_SUCCESS;
|
||||
}
|
||||
|
||||
static EVENT_CALLBACK(EVENT_HANDLER_APPLICATION_FRONT_SWITCHED)
|
||||
{
|
||||
debug("%s\n", __FUNCTION__);
|
||||
|
|
10
src/event.h
10
src/event.h
|
@ -1,11 +1,11 @@
|
|||
#ifndef EVENT_LOOP_EVENT_H
|
||||
#define EVENT_LOOP_EVENT_H
|
||||
|
||||
extern OSStatus SLSFindWindowByGeometry(int cid, int zero, int one, int zero_again, CGPoint *screen_point, CGPoint *window_point, uint32_t *wid, int *wcid);
|
||||
|
||||
#define EVENT_CALLBACK(name) uint32_t name(void *context, int param1)
|
||||
typedef EVENT_CALLBACK(event_callback);
|
||||
|
||||
static EVENT_CALLBACK(EVENT_HANDLER_APPLICATION_LAUNCHED);
|
||||
static EVENT_CALLBACK(EVENT_HANDLER_APPLICATION_TERMINATED);
|
||||
static EVENT_CALLBACK(EVENT_HANDLER_APPLICATION_FRONT_SWITCHED);
|
||||
static EVENT_CALLBACK(EVENT_HANDLER_WINDOW_FOCUSED);
|
||||
static EVENT_CALLBACK(EVENT_HANDLER_WINDOW_TITLE_CHANGED);
|
||||
|
@ -34,8 +34,6 @@ static EVENT_CALLBACK(EVENT_HANDLER_MOUSE_UP);
|
|||
enum event_type
|
||||
{
|
||||
EVENT_TYPE_UNKNOWN,
|
||||
APPLICATION_LAUNCHED,
|
||||
APPLICATION_TERMINATED,
|
||||
APPLICATION_FRONT_SWITCHED,
|
||||
WINDOW_FOCUSED,
|
||||
WINDOW_TITLE_CHANGED,
|
||||
|
@ -58,8 +56,6 @@ static const char *event_type_str[] =
|
|||
{
|
||||
[EVENT_TYPE_UNKNOWN] = "event_type_unknown",
|
||||
|
||||
[APPLICATION_LAUNCHED] = "application_launched",
|
||||
[APPLICATION_TERMINATED] = "application_terminated",
|
||||
[APPLICATION_FRONT_SWITCHED] = "application_front_switched",
|
||||
[WINDOW_FOCUSED] = "window_focused",
|
||||
[WINDOW_TITLE_CHANGED] = "window_title_changed",
|
||||
|
@ -80,8 +76,6 @@ static const char *event_type_str[] =
|
|||
|
||||
static event_callback *event_handler[] =
|
||||
{
|
||||
[APPLICATION_LAUNCHED] = EVENT_HANDLER_APPLICATION_LAUNCHED,
|
||||
[APPLICATION_TERMINATED] = EVENT_HANDLER_APPLICATION_TERMINATED,
|
||||
[APPLICATION_FRONT_SWITCHED] = EVENT_HANDLER_APPLICATION_FRONT_SWITCHED,
|
||||
[WINDOW_FOCUSED] = EVENT_HANDLER_WINDOW_FOCUSED,
|
||||
[WINDOW_TITLE_CHANGED] = EVENT_HANDLER_WINDOW_TITLE_CHANGED,
|
||||
|
|
|
@ -105,7 +105,6 @@ static void *event_loop_run(void *context)
|
|||
#endif
|
||||
if (event->info) *event->info = (result << 0x1) | EVENT_PROCESSED;
|
||||
|
||||
event_destroy(event_loop, event);
|
||||
} else {
|
||||
sem_wait(event_loop->semaphore);
|
||||
}
|
||||
|
|
|
@ -40,10 +40,7 @@
|
|||
#include "workspace.h"
|
||||
#include "message.h"
|
||||
#include "display.h"
|
||||
#include "process_manager.h"
|
||||
#include "application.h"
|
||||
#include "display_manager.h"
|
||||
#include "application_manager.h"
|
||||
#include "bar.h"
|
||||
#include "graph_data.h"
|
||||
#include "bar_item.h"
|
||||
|
@ -56,13 +53,10 @@
|
|||
#include "workspace.m"
|
||||
#include "message.c"
|
||||
#include "display.c"
|
||||
#include "process_manager.c"
|
||||
#include "application.c"
|
||||
#include "display_manager.c"
|
||||
#include "bar.c"
|
||||
#include "graph_data.c"
|
||||
#include "bar_item.c"
|
||||
#include "bar_manager.c"
|
||||
#include "application_manager.c"
|
||||
|
||||
#include "sketchybar.c"
|
||||
|
|
|
@ -1,222 +0,0 @@
|
|||
#include "process_manager.h"
|
||||
|
||||
extern struct event_loop g_event_loop;
|
||||
|
||||
static TABLE_HASH_FUNC(hash_psn)
|
||||
{
|
||||
unsigned long result = ((ProcessSerialNumber*) key)->lowLongOfPSN;
|
||||
result = (result + 0x7ed55d16) + (result << 12);
|
||||
result = (result ^ 0xc761c23c) ^ (result >> 19);
|
||||
result = (result + 0x165667b1) + (result << 5);
|
||||
result = (result + 0xd3a2646c) ^ (result << 9);
|
||||
result = (result + 0xfd7046c5) + (result << 3);
|
||||
result = (result ^ 0xb55a4f09) ^ (result >> 16);
|
||||
return result;
|
||||
}
|
||||
|
||||
static TABLE_COMPARE_FUNC(compare_psn)
|
||||
{
|
||||
return psn_equals(key_a, key_b);
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
struct process *process_create(ProcessSerialNumber psn)
|
||||
{
|
||||
struct process *process = malloc(sizeof(struct process));
|
||||
memset(process, 0, sizeof(struct process));
|
||||
|
||||
CFStringRef process_name_ref;
|
||||
if (CopyProcessName(&psn, &process_name_ref) == noErr) {
|
||||
process->name = cfstring_copy(process_name_ref);
|
||||
CFRelease(process_name_ref);
|
||||
} else {
|
||||
process->name = string_copy("<unknown>");
|
||||
}
|
||||
|
||||
ProcessInfoRec process_info = {};
|
||||
process_info.processInfoLength = sizeof(ProcessInfoRec);
|
||||
GetProcessInformation(&psn, &process_info);
|
||||
|
||||
process->psn = psn;
|
||||
GetProcessPID(&process->psn, &process->pid);
|
||||
process->background = (process_info.processMode & modeOnlyBackground) != 0;
|
||||
process->xpc = process_info.processType == 'XPC!';
|
||||
|
||||
CFDictionaryRef process_dict = ProcessInformationCopyDictionary(&psn, kProcessDictionaryIncludeAllInformationMask);
|
||||
if (process_dict) {
|
||||
CFBooleanRef process_lsuielement = CFDictionaryGetValue(process_dict, CFSTR("LSUIElement"));
|
||||
if (process_lsuielement) process->lsuielement = CFBooleanGetValue(process_lsuielement);
|
||||
CFBooleanRef process_lsbackground = CFDictionaryGetValue(process_dict, CFSTR("LSBackgroundOnly"));
|
||||
if (process_lsbackground) process->lsbackground = CFBooleanGetValue(process_lsbackground);
|
||||
CFRelease(process_dict);
|
||||
}
|
||||
|
||||
return process;
|
||||
}
|
||||
|
||||
void process_destroy(struct process *process)
|
||||
{
|
||||
free(process->name);
|
||||
free(process);
|
||||
}
|
||||
|
||||
static bool process_is_observable(struct process *process)
|
||||
{
|
||||
if (process->lsbackground) {
|
||||
debug("%s: %s was marked as background only! ignoring..\n", __FUNCTION__, process->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (process->lsuielement) {
|
||||
debug("%s: %s was marked as agent! ignoring..\n", __FUNCTION__, process->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (process->background) {
|
||||
debug("%s: %s was marked as daemon! ignoring..\n", __FUNCTION__, process->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (process->xpc) {
|
||||
debug("%s: %s was marked as xpc service! ignoring..\n", __FUNCTION__, process->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static PROCESS_EVENT_HANDLER(process_handler)
|
||||
{
|
||||
struct process_manager *pm = (struct process_manager *) user_data;
|
||||
|
||||
ProcessSerialNumber psn;
|
||||
if (GetEventParameter(event, kEventParamProcessID, typeProcessSerialNumber, NULL, sizeof(psn), NULL, &psn) != noErr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (GetEventKind(event)) {
|
||||
case kEventAppLaunched: {
|
||||
struct process *process = process_create(psn);
|
||||
if (!process) return noErr;
|
||||
|
||||
if (process_is_observable(process)) {
|
||||
struct event *event = event_create(&g_event_loop, APPLICATION_LAUNCHED, process);
|
||||
event_loop_post(&g_event_loop, event);
|
||||
process_manager_add_process(pm, process);
|
||||
} else {
|
||||
process_destroy(process);
|
||||
}
|
||||
} break;
|
||||
case kEventAppTerminated: {
|
||||
struct process *process = process_manager_find_process(pm, &psn);
|
||||
if (!process) return noErr;
|
||||
|
||||
process->terminated = true;
|
||||
process_manager_remove_process(pm, &psn);
|
||||
|
||||
struct event *event = event_create(&g_event_loop, APPLICATION_TERMINATED, process);
|
||||
event_loop_post(&g_event_loop, event);
|
||||
} break;
|
||||
case kEventAppFrontSwitched: {
|
||||
struct process *process = process_manager_find_process(pm, &psn);
|
||||
if (!process) return noErr;
|
||||
|
||||
struct event *event = event_create(&g_event_loop, APPLICATION_FRONT_SWITCHED, process);
|
||||
event_loop_post(&g_event_loop, event);
|
||||
} break;
|
||||
}
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
static void
|
||||
process_manager_add_running_processes(struct process_manager *pm)
|
||||
{
|
||||
ProcessSerialNumber psn = { kNoProcess, kNoProcess };
|
||||
while (GetNextProcess(&psn) == noErr) {
|
||||
struct process *process = process_create(psn);
|
||||
if (!process) continue;
|
||||
|
||||
if (process_is_observable(process)) {
|
||||
if (string_equals(process->name, "Finder")) {
|
||||
debug("%s: %s was found! caching psn..\n", __FUNCTION__, process->name);
|
||||
pm->finder_psn = psn;
|
||||
}
|
||||
|
||||
process_manager_add_process(pm, process);
|
||||
} else {
|
||||
process_destroy(process);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
struct process *process_manager_find_process(struct process_manager *pm, ProcessSerialNumber *psn)
|
||||
{
|
||||
return table_find(&pm->process, psn);
|
||||
}
|
||||
|
||||
void process_manager_remove_process(struct process_manager *pm, ProcessSerialNumber *psn)
|
||||
{
|
||||
table_remove(&pm->process, psn);
|
||||
}
|
||||
|
||||
void process_manager_add_process(struct process_manager *pm, struct process *process)
|
||||
{
|
||||
table_add(&pm->process, &process->psn, process);
|
||||
}
|
||||
|
||||
#if 0
|
||||
bool process_manager_next_process(ProcessSerialNumber *next_psn)
|
||||
{
|
||||
CFArrayRef applications =_LSCopyApplicationArrayInFrontToBackOrder(0xFFFFFFFE, 1);
|
||||
if (!applications) return false;
|
||||
|
||||
bool found_front_psn = false;
|
||||
ProcessSerialNumber front_psn;
|
||||
_SLPSGetFrontProcess(&front_psn);
|
||||
|
||||
for (int i = 0; i < CFArrayGetCount(applications); ++i) {
|
||||
CFTypeRef asn = CFArrayGetValueAtIndex(applications, i);
|
||||
assert(CFGetTypeID(asn) == _LSASNGetTypeID());
|
||||
_LSASNExtractHighAndLowParts(asn, &next_psn->highLongOfPSN, &next_psn->lowLongOfPSN);
|
||||
if (found_front_psn) break;
|
||||
found_front_psn = psn_equals(&front_psn, next_psn);
|
||||
}
|
||||
|
||||
CFRelease(applications);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void process_manager_init(struct process_manager *pm)
|
||||
{
|
||||
pm->target = GetApplicationEventTarget();
|
||||
pm->handler = NewEventHandlerUPP(process_handler);
|
||||
pm->type[0].eventClass = kEventClassApplication;
|
||||
pm->type[0].eventKind = kEventAppLaunched;
|
||||
pm->type[1].eventClass = kEventClassApplication;
|
||||
pm->type[1].eventKind = kEventAppTerminated;
|
||||
pm->type[2].eventClass = kEventClassApplication;
|
||||
pm->type[2].eventKind = kEventAppFrontSwitched;
|
||||
table_init(&pm->process, 125, hash_psn, compare_psn);
|
||||
process_manager_add_running_processes(pm);
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
bool process_manager_begin(struct process_manager *pm)
|
||||
{
|
||||
ProcessSerialNumber front_psn;
|
||||
_SLPSGetFrontProcess(&front_psn);
|
||||
GetProcessPID(&front_psn, &g_process_manager.front_pid);
|
||||
g_process_manager.last_front_pid = g_process_manager.front_pid;
|
||||
return InstallEventHandler(pm->target, pm->handler, 3, pm->type, pm, &pm->ref) == noErr;
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
bool process_manager_end(struct process_manager *pm)
|
||||
{
|
||||
return RemoveEventHandler(pm->ref) == noErr;
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
#ifndef PROCESS_MANAGER_H
|
||||
#define PROCESS_MANAGER_H
|
||||
|
||||
extern OSStatus _SLPSGetFrontProcess(ProcessSerialNumber *psn);
|
||||
extern CFStringRef SLSCopyBestManagedDisplayForRect(int cid, CGRect rect);
|
||||
extern CGError SLSGetCurrentCursorLocation(int cid, CGPoint *point);
|
||||
|
||||
#if 0
|
||||
extern CFArrayRef _LSCopyApplicationArrayInFrontToBackOrder(int negative_one, int one);
|
||||
extern void _LSASNExtractHighAndLowParts(const void *asn, uint32_t *high, uint32_t *low);
|
||||
extern CFTypeID _LSASNGetTypeID(void);
|
||||
#endif
|
||||
|
||||
#define PROCESS_EVENT_HANDLER(name) OSStatus name(EventHandlerCallRef ref, EventRef event, void *user_data)
|
||||
typedef PROCESS_EVENT_HANDLER(process_event_handler);
|
||||
|
||||
struct process
|
||||
{
|
||||
ProcessSerialNumber psn;
|
||||
pid_t pid;
|
||||
char *name;
|
||||
bool background;
|
||||
bool lsuielement;
|
||||
bool lsbackground;
|
||||
bool xpc;
|
||||
bool volatile terminated;
|
||||
};
|
||||
|
||||
struct process_manager
|
||||
{
|
||||
struct table process;
|
||||
EventTargetRef target;
|
||||
EventHandlerUPP handler;
|
||||
EventTypeSpec type[3];
|
||||
EventHandlerRef ref;
|
||||
pid_t front_pid;
|
||||
pid_t last_front_pid;
|
||||
ProcessSerialNumber finder_psn;
|
||||
};
|
||||
|
||||
void process_destroy(struct process *process);
|
||||
struct process *process_create(ProcessSerialNumber psn);
|
||||
struct process *process_manager_find_process(struct process_manager *pm, ProcessSerialNumber *psn);
|
||||
void process_manager_remove_process(struct process_manager *pm, ProcessSerialNumber *psn);
|
||||
void process_manager_add_process(struct process_manager *pm, struct process *process);
|
||||
// bool process_manager_next_process(ProcessSerialNumber *next_psn);
|
||||
void process_manager_init(struct process_manager *pm);
|
||||
bool process_manager_begin(struct process_manager *pm);
|
||||
bool process_manager_end(struct process_manager *pm);
|
||||
|
||||
#endif
|
|
@ -23,9 +23,7 @@ extern CGError SLSRegisterConnectionNotifyProc(int cid, connection_callback *han
|
|||
|
||||
struct event_loop g_event_loop;
|
||||
void *g_workspace_context;
|
||||
struct process_manager g_process_manager;
|
||||
struct display_manager g_display_manager;
|
||||
struct application_manager g_application_manager;
|
||||
struct daemon g_daemon;
|
||||
struct bar_manager g_bar_manager;
|
||||
struct mouse_state g_mouse_state;
|
||||
|
@ -248,16 +246,12 @@ int main(int argc, char **argv)
|
|||
error("sketchybar: could not initialize event_loop! abort..\n");
|
||||
}
|
||||
|
||||
process_manager_init(&g_process_manager);
|
||||
workspace_event_handler_init(&g_workspace_context);
|
||||
application_manager_init(&g_application_manager);
|
||||
bar_manager_init(&g_bar_manager);
|
||||
|
||||
event_loop_begin(&g_event_loop);
|
||||
display_manager_begin(&g_display_manager);
|
||||
process_manager_begin(&g_process_manager);
|
||||
workspace_event_handler_begin(&g_workspace_context);
|
||||
application_manager_begin(&g_application_manager);
|
||||
bar_manager_begin(&g_bar_manager);
|
||||
event_tap_begin(&g_event_tap, EVENT_MASK_MOUSE, mouse_handler);
|
||||
SLSRegisterConnectionNotifyProc(g_connection, connection_handler, 1204, NULL);
|
||||
|
|
Loading…
Reference in a new issue