Skip to content

Commit

Permalink
reduce calls to AX API
Browse files Browse the repository at this point in the history
  • Loading branch information
koekeishiya committed May 27, 2022
1 parent 70e9b2a commit 2e3fb4a
Show file tree
Hide file tree
Showing 11 changed files with 80 additions and 23 deletions.
2 changes: 2 additions & 0 deletions src/application.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ struct application *application_create(struct process *process)
application->pid = process->pid;
application->name = process->name;
application->is_hidden = application_is_hidden(application);
SLSGetConnectionIDForPSN(g_connection, &application->psn, &application->connection);

return application;
}

Expand Down
1 change: 1 addition & 0 deletions src/application.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ static CFStringRef ax_application_notification[] =
struct application
{
AXUIElementRef ref;
int connection;
ProcessSerialNumber psn;
uint32_t pid;
char *name;
Expand Down
2 changes: 1 addition & 1 deletion src/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ static EVENT_CALLBACK(EVENT_HANDLER_APPLICATION_LAUNCHED)

debug("%s: %s (%d)\n", __FUNCTION__, process->name, process->pid);
window_manager_add_application(&g_window_manager, application);
window_manager_add_application_windows(&g_space_manager, &g_window_manager, application);
window_manager_add_application_windows(&g_space_manager, &g_window_manager, application, -1);
event_signal_push(SIGNAL_APPLICATION_LAUNCHED, application);

int window_count;
Expand Down
1 change: 1 addition & 0 deletions src/misc/extern.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ 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 SLSGetConnectionIDForPSN(int cid, ProcessSerialNumber *psn, int *psn_cid);
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);
Expand Down
6 changes: 3 additions & 3 deletions src/space.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ uint32_t space_display_id(uint64_t sid)
return id;
}

uint32_t *space_window_list_for_connection(uint64_t sid, int cid, int *count, bool include_minimized)
uint32_t *space_window_list_for_connection(uint64_t *space_list, int space_count, int cid, int *count, bool include_minimized)
{
uint32_t *window_list = NULL;
uint64_t set_tags = 0;
uint64_t clear_tags = 0;
uint32_t options = include_minimized ? 0x7 : 0x2;

CFArrayRef space_list_ref = cfarray_of_cfnumbers(&sid, sizeof(uint64_t), 1, kCFNumberSInt64Type);
CFArrayRef space_list_ref = cfarray_of_cfnumbers(space_list, sizeof(uint64_t), space_count, kCFNumberSInt64Type);
CFArrayRef window_list_ref = SLSCopyWindowsWithOptionsAndTags(g_connection, cid, space_list_ref, options, &set_tags, &clear_tags);
if (!window_list_ref) goto err;

Expand All @@ -49,7 +49,7 @@ uint32_t *space_window_list_for_connection(uint64_t sid, int cid, int *count, bo

uint32_t *space_window_list(uint64_t sid, int *count, bool include_minimized)
{
return space_window_list_for_connection(sid, 0, count, include_minimized);
return space_window_list_for_connection(&sid, 1, 0, count, include_minimized);
}

CFStringRef space_uuid(uint64_t sid)
Expand Down
2 changes: 1 addition & 1 deletion src/space.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

CFStringRef space_display_uuid(uint64_t sid);
uint32_t space_display_id(uint64_t sid);
uint32_t *space_window_list_for_connection(uint64_t sid, int cid, int *count, bool include_minimized);
uint32_t *space_window_list_for_connection(uint64_t *space_list, int space_count, int cid, int *count, bool include_minimized);
uint32_t *space_window_list(uint64_t sid, int *count, bool include_minimized);
CFStringRef space_uuid(uint64_t sid);
int space_type(uint64_t sid);
Expand Down
16 changes: 7 additions & 9 deletions src/space_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -914,16 +914,14 @@ void space_manager_mark_spaces_invalid(struct space_manager *sm)

bool space_manager_refresh_application_windows(struct space_manager *sm)
{
int refresh_count = buf_len(g_window_manager.applications_to_refresh);
if (!refresh_count) return false;

int window_count = g_window_manager.window.count;
for (int i = 0; i < g_window_manager.application.capacity; ++i) {
struct bucket *bucket = g_window_manager.application.buckets[i];
while (bucket) {
if (bucket->value) {
struct application *application = bucket->value;
window_manager_add_application_windows(sm, &g_window_manager, application);
}
bucket = bucket->next;
}
for (int i = 0; i < refresh_count; ++i) {
struct application *application = g_window_manager.applications_to_refresh[i];
debug("%s: %s has windows that are not yet resolved\n", __FUNCTION__, application->name);
window_manager_add_application_windows(sm, &g_window_manager, application, i);
}

return window_count != g_window_manager.window.count;
Expand Down
1 change: 0 additions & 1 deletion src/window.c
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,6 @@ struct window *window_create(struct application *application, AXUIElementRef win
window->ref = window_ref;
window->id = window_id;
window->id_ptr = &window->id;
SLSGetWindowOwner(g_connection, window->id, &window->connection);
window->frame = window_ax_frame(window);
window_set_flag(window, WINDOW_SHADOW);

Expand Down
1 change: 0 additions & 1 deletion src/window.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ struct window
{
struct application *application;
AXUIElementRef ref;
int connection;
uint32_t id;
uint32_t *volatile id_ptr;
CGRect frame;
Expand Down
68 changes: 62 additions & 6 deletions src/window_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -1043,20 +1043,74 @@ struct window *window_manager_create_and_add_window(struct space_manager *sm, st
return window;
}

void window_manager_add_application_windows(struct space_manager *sm, struct window_manager *wm, struct application *application)
static uint32_t *window_manager_application_window_list(struct application *application, int *window_count)
{
uint32_t display_count;
uint32_t *display_list = display_manager_active_display_list(&display_count);
if (!display_list) return NULL;

int space_count = 0;
uint64_t *space_list = NULL;

for (int i = 0; i < display_count; ++i) {
int count;
uint64_t *list = display_space_list(display_list[i], &count);
if (!list) continue;

//
// NOTE(koekeishiya): display_space_list(..) uses a linear allocator,
// and so we only need to track the beginning of the first list along
// with the total number of windows that have been allocated.
//

if (!space_list) space_list = list;
space_count += count;
}

return space_list ? space_window_list_for_connection(space_list, space_count, application->connection, window_count, false) : NULL;
}

void window_manager_add_application_windows(struct space_manager *sm, struct window_manager *wm, struct application *application, int refresh_index)
{
int global_window_count;
uint32_t *global_window_list = window_manager_application_window_list(application, &global_window_count);
if (!global_window_list) return;

CFArrayRef window_list_ref = application_window_list(application);
if (!window_list_ref) return;
int window_count = window_list_ref ? CFArrayGetCount(window_list_ref) : 0;

int window_count = CFArrayGetCount(window_list_ref);
for (int i = 0; i < window_count; ++i) {
AXUIElementRef window_ref = CFArrayGetValueAtIndex(window_list_ref, i);
uint32_t window_id = ax_window_id(window_ref);
if (!window_id || window_manager_find_window(wm, window_id)) continue;
window_manager_create_and_add_window(sm, wm, application, CFRetain(window_ref), window_id);
}

CFRelease(window_list_ref);
if (global_window_count == window_count) {
if (refresh_index != -1) {
debug("%s: all windows for %s are now resolved\n", __FUNCTION__, application->name);
buf_del(g_window_manager.applications_to_refresh, refresh_index);
}
} else {
bool missing_window = false;
for (int i = 0; i < global_window_count; ++i) {
struct window *window = window_manager_find_window(&g_window_manager, global_window_list[i]);
if (!window) {
missing_window = true;
break;
}
}

if (refresh_index == -1 && missing_window) {
debug("%s: %s has windows that are not yet resolved\n", __FUNCTION__, application->name);
buf_push(g_window_manager.applications_to_refresh, application);
} else if (refresh_index != -1 && !missing_window) {
debug("%s: all windows for %s are now resolved\n", __FUNCTION__, application->name);
buf_del(g_window_manager.applications_to_refresh, refresh_index);
}
}

if (window_list_ref) CFRelease(window_list_ref);
}

enum window_op_error window_manager_set_window_insertion(struct space_manager *sm, struct window_manager *wm, struct window *window, int direction)
Expand Down Expand Up @@ -1428,7 +1482,7 @@ void window_manager_toggle_window_shadow(struct space_manager *sm, struct window

void window_manager_wait_for_native_fullscreen_transition(struct window *window)
{
if (workspace_is_macos_mojave()) {
if (workspace_is_macos_mojave() || workspace_is_macos_monterey()) {
while (!space_is_user(space_manager_active_space())) {

//
Expand All @@ -1441,6 +1495,8 @@ void window_manager_wait_for_native_fullscreen_transition(struct window *window)
//
// - https://github.com/koekeishiya/yabai/issues/690
//
// The display_manager API does not work on macOS Monterey.
//

usleep(100000);
}
Expand Down Expand Up @@ -1701,7 +1757,7 @@ void window_manager_begin(struct space_manager *sm, struct window_manager *wm)

if (application_observe(application)) {
window_manager_add_application(wm, application);
window_manager_add_application_windows(sm, wm, application);
window_manager_add_application_windows(sm, wm, application, -1);
} else {
application_unobserve(application);
application_destroy(application);
Expand Down
3 changes: 2 additions & 1 deletion src/window_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ struct window_manager
struct table window_lost_focused_event;
struct table application_lost_front_switched_event;
struct rule *rules;
struct application **applications_to_refresh;
uint32_t focused_window_id;
ProcessSerialNumber focused_window_psn;
uint32_t last_window_id;
Expand Down Expand Up @@ -167,7 +168,7 @@ enum window_op_error window_manager_deminimize_window(struct window *window);
bool window_manager_close_window(struct window *window);
void window_manager_send_window_to_space(struct space_manager *sm, struct window_manager *wm, struct window *window, uint64_t sid, bool moved_by_rule);
struct window *window_manager_create_and_add_window(struct space_manager *sm, struct window_manager *wm, struct application *application, AXUIElementRef window_ref, uint32_t window_id);
void window_manager_add_application_windows(struct space_manager *sm, struct window_manager *wm, struct application *application);
void window_manager_add_application_windows(struct space_manager *sm, struct window_manager *wm, struct application *application, int refresh_index);
enum window_op_error window_manager_apply_grid(struct space_manager *sm, struct window_manager *wm, struct window *window, unsigned r, unsigned c, unsigned x, unsigned y, unsigned w, unsigned h);
void window_manager_purify_window(struct window_manager *wm, struct window *window);
void window_manager_make_window_floating(struct space_manager *sm, struct window_manager *wm, struct window *window, bool should_float);
Expand Down

0 comments on commit 2e3fb4a

Please sign in to comment.