Skip to content

Commit

Permalink
cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
koekeishiya committed Jan 25, 2021
1 parent 853093f commit a5feed0
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 94 deletions.
60 changes: 33 additions & 27 deletions src/application.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,40 @@ static OBSERVER_CALLBACK(application_notification_handler)
{
if (CFEqual(notification, kAXCreatedNotification)) {
event_loop_post(&g_event_loop, WINDOW_CREATED, (void *) CFRetain(element), 0, NULL);
} else if (CFEqual(notification, kAXUIElementDestroyedNotification)) {
uint32_t *window_id_ptr = *(uint32_t **) context;
if (!window_id_ptr) return;

if (!__sync_bool_compare_and_swap((uint32_t **) context, window_id_ptr, NULL)) return;

event_loop_post(&g_event_loop, WINDOW_DESTROYED, (void *)(uintptr_t) *window_id_ptr, 0, NULL);
} else if (CFEqual(notification, kAXFocusedWindowChangedNotification)) {
uint32_t window_id = ax_window_id(element);
if (window_id) event_loop_post(&g_event_loop, WINDOW_FOCUSED, (void *)(intptr_t) window_id, 0, NULL);
event_loop_post(&g_event_loop, WINDOW_FOCUSED, (void *)(intptr_t) ax_window_id(element), 0, NULL);
} else if (CFEqual(notification, kAXWindowMovedNotification)) {
uint32_t window_id = ax_window_id(element);
if (window_id) event_loop_post(&g_event_loop, WINDOW_MOVED, (void *)(intptr_t) window_id, 0, NULL);
event_loop_post(&g_event_loop, WINDOW_MOVED, (void *)(intptr_t) ax_window_id(element), 0, NULL);
} else if (CFEqual(notification, kAXWindowResizedNotification)) {
uint32_t window_id = ax_window_id(element);
if (window_id) event_loop_post(&g_event_loop, WINDOW_RESIZED, (void *)(intptr_t) window_id, 0, NULL);
} else if (CFEqual(notification, kAXWindowMiniaturizedNotification)) {
uint32_t window_id = **((uint32_t **) context);
event_loop_post(&g_event_loop, WINDOW_MINIMIZED, (void *)(intptr_t) window_id, 0, NULL);
} else if (CFEqual(notification, kAXWindowDeminiaturizedNotification)) {
uint32_t window_id = **((uint32_t **) context);
event_loop_post(&g_event_loop, WINDOW_DEMINIMIZED, (void *)(intptr_t) window_id, 0, NULL);
event_loop_post(&g_event_loop, WINDOW_RESIZED, (void *)(intptr_t) ax_window_id(element), 0, NULL);
} else if (CFEqual(notification, kAXTitleChangedNotification)) {
uint32_t window_id = ax_window_id(element);
if (window_id) event_loop_post(&g_event_loop, WINDOW_TITLE_CHANGED, (void *)(intptr_t) window_id, 0, NULL);
event_loop_post(&g_event_loop, WINDOW_TITLE_CHANGED, (void *)(intptr_t) ax_window_id(element), 0, NULL);
} else if (CFEqual(notification, kAXMenuOpenedNotification)) {
uint32_t window_id = ax_window_id(element);
if (window_id) event_loop_post(&g_event_loop, MENU_OPENED, (void *)(intptr_t) window_id, 0, NULL);
event_loop_post(&g_event_loop, MENU_OPENED, (void *)(intptr_t) ax_window_id(element), 0, NULL);
} else if (CFEqual(notification, kAXWindowMiniaturizedNotification)) {
event_loop_post(&g_event_loop, WINDOW_MINIMIZED, context, 0, NULL);
} else if (CFEqual(notification, kAXWindowDeminiaturizedNotification)) {
event_loop_post(&g_event_loop, WINDOW_DEMINIMIZED, context, 0, NULL);
} else if (CFEqual(notification, kAXUIElementDestroyedNotification)) {
struct window *window = context;

//
// NOTE(koekeishiya): Flag events that are already queued, but not yet processed,
// so that they will be ignored; the memory we allocated is still valid and will
// be freed when this event is handled.
//

if (!__sync_bool_compare_and_swap(&window->id_ptr, &window->id, NULL)) return;

//
// NOTE(koekeishiya): Usually we avoid running code off the event-loop thread,
// however in this case it is fine, as we are only touching fields that never
// change after the window allocation and creation code.
//

window_unobserve(window);

event_loop_post(&g_event_loop, WINDOW_DESTROYED, window, 0, NULL);
}
}

Expand All @@ -45,7 +51,7 @@ application_observe_notification(struct application *application, int notificati
application->notification |= 1 << notification;
} else {
if (result == kAXErrorCannotComplete) application->ax_retry = true;
debug("%s: %s failed with error %s\n", __FUNCTION__, ax_application_notification_str[notification], ax_error_str[-result]);
debug("%s: notification %s failed with error %s for %s\n", __FUNCTION__, ax_application_notification_str[notification], ax_error_str[-result], application->name);
}
}

Expand Down Expand Up @@ -86,9 +92,9 @@ void application_unobserve(struct application *application)

uint32_t application_main_window(struct application *application)
{
CFTypeRef window_ref;
bool result = AXUIElementCopyAttributeValue(application->ref, kAXMainWindowAttribute, &window_ref) == kAXErrorSuccess;
if (!result) return 0;
CFTypeRef window_ref = NULL;
AXUIElementCopyAttributeValue(application->ref, kAXMainWindowAttribute, &window_ref);
if (!window_ref) return 0;

uint32_t window_id = ax_window_id(window_ref);
CFRelease(window_ref);
Expand Down
39 changes: 16 additions & 23 deletions src/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ static EVENT_CALLBACK(EVENT_HANDLER_APPLICATION_TERMINATED)

event_signal_push(SIGNAL_WINDOW_DESTROYED, window);
window_manager_remove_window(&g_window_manager, window->id);
window_unobserve(window);
window_destroy(window);
}

Expand Down Expand Up @@ -328,13 +329,9 @@ static EVENT_CALLBACK(EVENT_HANDLER_WINDOW_CREATED)

static EVENT_CALLBACK(EVENT_HANDLER_WINDOW_DESTROYED)
{
uint32_t window_id = (uint32_t)(uintptr_t) context;
struct window *window = window_manager_find_window(&g_window_manager, window_id);
if (!window) return EVENT_FAILURE;

assert(!*window->id_ptr);
struct window *window = context;
debug("%s: %s %d\n", __FUNCTION__, window->application->name, window->id);
window_unobserve(window);
assert(!window->id_ptr);

struct view *view = window_manager_find_managed_window(&g_window_manager, window);
if (view) {
Expand Down Expand Up @@ -362,7 +359,7 @@ static EVENT_CALLBACK(EVENT_HANDLER_WINDOW_FOCUSED)
return EVENT_FAILURE;
}

if (!__sync_bool_compare_and_swap(window->id_ptr, &window->id, &window->id)) {
if (!__sync_bool_compare_and_swap(&window->id_ptr, &window->id, &window->id)) {
debug("%s: %d has been marked invalid by the system, ignoring event..\n", __FUNCTION__, window_id);
return EVENT_FAILURE;
}
Expand Down Expand Up @@ -395,7 +392,7 @@ static EVENT_CALLBACK(EVENT_HANDLER_WINDOW_MOVED)
struct window *window = window_manager_find_window(&g_window_manager, window_id);
if (!window) return EVENT_FAILURE;

if (!__sync_bool_compare_and_swap(window->id_ptr, &window->id, &window->id)) {
if (!__sync_bool_compare_and_swap(&window->id_ptr, &window->id, &window->id)) {
debug("%s: %d has been marked invalid by the system, ignoring event..\n", __FUNCTION__, window_id);
return EVENT_FAILURE;
}
Expand All @@ -417,7 +414,7 @@ static EVENT_CALLBACK(EVENT_HANDLER_WINDOW_RESIZED)
struct window *window = window_manager_find_window(&g_window_manager, window_id);
if (!window) return EVENT_FAILURE;

if (!__sync_bool_compare_and_swap(window->id_ptr, &window->id, &window->id)) {
if (!__sync_bool_compare_and_swap(&window->id_ptr, &window->id, &window->id)) {
debug("%s: %d has been marked invalid by the system, ignoring event..\n", __FUNCTION__, window_id);
return EVENT_FAILURE;
}
Expand Down Expand Up @@ -467,12 +464,10 @@ static EVENT_CALLBACK(EVENT_HANDLER_WINDOW_RESIZED)

static EVENT_CALLBACK(EVENT_HANDLER_WINDOW_MINIMIZED)
{
uint32_t window_id = (uint32_t)(intptr_t) context;
struct window *window = window_manager_find_window(&g_window_manager, window_id);
if (!window) return EVENT_FAILURE;
struct window *window = context;

if (!__sync_bool_compare_and_swap(window->id_ptr, &window->id, &window->id)) {
debug("%s: %d has been marked invalid by the system, ignoring event..\n", __FUNCTION__, window_id);
if (!__sync_bool_compare_and_swap(&window->id_ptr, &window->id, &window->id)) {
debug("%s: %d has been marked invalid by the system, ignoring event..\n", __FUNCTION__, window->id);
return EVENT_FAILURE;
}

Expand All @@ -496,13 +491,11 @@ static EVENT_CALLBACK(EVENT_HANDLER_WINDOW_MINIMIZED)

static EVENT_CALLBACK(EVENT_HANDLER_WINDOW_DEMINIMIZED)
{
uint32_t window_id = (uint32_t)(intptr_t) context;
struct window *window = window_manager_find_window(&g_window_manager, window_id);
if (!window) return EVENT_FAILURE;
struct window *window = context;

if (!__sync_bool_compare_and_swap(window->id_ptr, &window->id, &window->id)) {
debug("%s: %d has been marked invalid by the system, ignoring event..\n", __FUNCTION__, window_id);
window_manager_remove_lost_focused_event(&g_window_manager, window_id);
if (!__sync_bool_compare_and_swap(&window->id_ptr, &window->id, &window->id)) {
debug("%s: %d has been marked invalid by the system, ignoring event..\n", __FUNCTION__, window->id);
window_manager_remove_lost_focused_event(&g_window_manager, window->id);
return EVENT_FAILURE;
}

Expand Down Expand Up @@ -535,7 +528,7 @@ static EVENT_CALLBACK(EVENT_HANDLER_WINDOW_TITLE_CHANGED)
struct window *window = window_manager_find_window(&g_window_manager, window_id);
if (!window) return EVENT_FAILURE;

if (!__sync_bool_compare_and_swap(window->id_ptr, &window->id, &window->id)) {
if (!__sync_bool_compare_and_swap(&window->id_ptr, &window->id, &window->id)) {
debug("%s: %d has been marked invalid by the system, ignoring event..\n", __FUNCTION__, window_id);
return EVENT_FAILURE;
}
Expand Down Expand Up @@ -681,7 +674,7 @@ static EVENT_CALLBACK(EVENT_HANDLER_MOUSE_UP)
if (g_mission_control_active) goto out;
if (!g_mouse_state.window) goto out;

if (!__sync_bool_compare_and_swap(g_mouse_state.window->id_ptr, &g_mouse_state.window->id, &g_mouse_state.window->id)) {
if (!__sync_bool_compare_and_swap(&g_mouse_state.window->id_ptr, &g_mouse_state.window->id, &g_mouse_state.window->id)) {
debug("%s: %d has been marked invalid by the system, ignoring event..\n", __FUNCTION__, g_mouse_state.window->id);
goto err;
}
Expand Down Expand Up @@ -757,7 +750,7 @@ static EVENT_CALLBACK(EVENT_HANDLER_MOUSE_DRAGGED)
if (g_mission_control_active) goto out;
if (!g_mouse_state.window) goto out;

if (!__sync_bool_compare_and_swap(g_mouse_state.window->id_ptr, &g_mouse_state.window->id, &g_mouse_state.window->id)) {
if (!__sync_bool_compare_and_swap(&g_mouse_state.window->id_ptr, &g_mouse_state.window->id, &g_mouse_state.window->id)) {
debug("%s: %d has been marked invalid by the system, ignoring event..\n", __FUNCTION__, g_mouse_state.window->id);
g_mouse_state.window = NULL;
g_mouse_state.current_action = MOUSE_MODE_NONE;
Expand Down
89 changes: 46 additions & 43 deletions src/window.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,17 @@ extern int g_normal_window_level;
extern int g_floating_window_level;
extern int g_connection;

static void
window_observe_notification(struct window *window, int notification)
static void window_observe_notification(struct window *window, int notification)
{
AXError result = AXObserverAddNotification(window->application->observer_ref, window->ref, ax_window_notification[notification], window->id_ptr);
AXError result = AXObserverAddNotification(window->application->observer_ref, window->ref, ax_window_notification[notification], window);
if (result == kAXErrorSuccess || result == kAXErrorNotificationAlreadyRegistered) {
window->notification |= 1 << notification;
} else {
debug("%s: %s failed with error %s\n", __FUNCTION__, ax_window_notification_str[notification], ax_error_str[-result]);
}
}

static void
window_unobserve_notification(struct window *window, int notification)
static void window_unobserve_notification(struct window *window, int notification)
{
AXObserverRemoveNotification(window->application->observer_ref, window->ref, ax_window_notification[notification]);
window->notification &= ~(1 << notification);
Expand Down Expand Up @@ -94,6 +92,7 @@ uint64_t *window_space_list(struct window *window, int *count)
if (!*count) goto out;

space_list = ts_alloc(*count * sizeof(uint64_t));

for (int i = 0; i < *count; ++i) {
CFNumberRef id_ref = CFArrayGetValueAtIndex(space_list_ref, i);
CFNumberGetValue(id_ref, CFNumberGetType(id_ref), space_list + i);
Expand All @@ -118,9 +117,10 @@ void window_serialize(FILE *rsp, struct window *window)
int display = display_arrangement(space_display_id(sid));
bool is_topmost = window_is_topmost(window);
bool is_minimized = window_is_minimized(window);
bool visible = !is_minimized && (window->is_sticky || space_is_visible(sid));
bool visible = !is_minimized && !window->application->is_hidden && (window->is_sticky || space_is_visible(sid));
bool border = window->border.id ? 1 : 0;
float opacity = window_opacity(window);
bool grabbed = window == g_mouse_state.window;

CFStringRef cfrole = window_role(window);
if (cfrole) {
Expand Down Expand Up @@ -150,55 +150,58 @@ void window_serialize(FILE *rsp, struct window *window)
"\t\"app\":\"%s\",\n"
"\t\"title\":\"%s\",\n"
"\t\"frame\":{\n\t\t\"x\":%.4f,\n\t\t\"y\":%.4f,\n\t\t\"w\":%.4f,\n\t\t\"h\":%.4f\n\t},\n"
"\t\"level\":%d,\n"
"\t\"role\":\"%s\",\n"
"\t\"subrole\":\"%s\",\n"
"\t\"movable\":%d,\n"
"\t\"resizable\":%d,\n"
"\t\"display\":%d,\n"
"\t\"space\":%d,\n"
"\t\"visible\":%d,\n"
"\t\"focused\":%d,\n"
"\t\"split\":\"%s\",\n"
"\t\"floating\":%d,\n"
"\t\"sticky\":%d,\n"
"\t\"minimized\":%d,\n"
"\t\"topmost\":%d,\n"
"\t\"level\":%d,\n"
"\t\"opacity\":%.4f,\n"
"\t\"shadow\":%d,\n"
"\t\"border\":%d,\n"
"\t\"split-type\":\"%s\",\n"
"\t\"stack-index\":%d,\n"
"\t\"zoom-parent\":%d,\n"
"\t\"zoom-fullscreen\":%d,\n"
"\t\"native-fullscreen\":%d\n"
"\t\"can-move\":%s,\n"
"\t\"can-resize\":%s,\n"
"\t\"has-focus\":%s,\n"
"\t\"has-shadow\":%s,\n"
"\t\"has-border\":%s,\n"
"\t\"has-parent-zoom\":%s,\n"
"\t\"has-fullscreen-zoom\":%s,\n"
"\t\"is-native-fullscreen\":%s,\n"
"\t\"is-visible\":%s,\n"
"\t\"is-minimized\":%s,\n"
"\t\"is-hidden\":%s,\n"
"\t\"is-floating\":%s,\n"
"\t\"is-sticky\":%s,\n"
"\t\"is-topmost\":%s,\n"
"\t\"is-grabbed\":%s\n"
"}",
window->id,
window->application->pid,
window->application->name,
escaped_title ? escaped_title : title,
frame.origin.x, frame.origin.y,
frame.size.width, frame.size.height,
window_level(window),
frame.origin.x, frame.origin.y, frame.size.width, frame.size.height,
role ? role : "",
subrole ? subrole : "",
window_can_move(window),
window_can_resize(window),
display,
space,
visible,
window->id == g_window_manager.focused_window_id,
split,
window->is_floating,
window->is_sticky,
is_minimized,
is_topmost,
window_level(window),
opacity,
window->has_shadow,
border,
split,
stack_index,
zoom_parent,
zoom_fullscreen,
window_is_fullscreen(window));
json_bool(window_can_move(window)),
json_bool(window_can_resize(window)),
json_bool(window->id == g_window_manager.focused_window_id),
json_bool(window->has_shadow),
json_bool(border),
json_bool(zoom_parent),
json_bool(zoom_fullscreen),
json_bool(window_is_fullscreen(window)),
json_bool(visible),
json_bool(window->is_floating),
json_bool(window->is_sticky),
json_bool(is_minimized),
json_bool(window->application->is_hidden),
json_bool(is_topmost),
json_bool(grabbed));
}

char *window_title(struct window *window)
Expand Down Expand Up @@ -231,12 +234,12 @@ CGRect window_ax_frame(struct window *window)
AXUIElementCopyAttributeValue(window->ref, kAXPositionAttribute, &position_ref);
AXUIElementCopyAttributeValue(window->ref, kAXSizeAttribute, &size_ref);

if (position_ref != NULL) {
if (position_ref) {
AXValueGetValue(position_ref, kAXValueTypeCGPoint, &frame.origin);
CFRelease(position_ref);
}

if (size_ref != NULL) {
if (size_ref) {
AXValueGetValue(size_ref, kAXValueTypeCGSize, &frame.size);
CFRelease(size_ref);
}
Expand Down Expand Up @@ -303,10 +306,12 @@ bool window_is_fullscreen(struct window *window)
{
Boolean result = 0;
CFTypeRef value;

if (AXUIElementCopyAttributeValue(window->ref, kAXFullscreenAttribute, &value) == kAXErrorSuccess) {
result = CFBooleanGetValue(value);
CFRelease(value);
}

return result;
}

Expand Down Expand Up @@ -454,8 +459,7 @@ struct window *window_create(struct application *application, AXUIElementRef win
window->is_minimized = window_is_minimized(window);
window->is_fullscreen = window_is_fullscreen(window) || space_is_fullscreen(window_space(window));
window->is_sticky = window_is_sticky(window);
window->id_ptr = malloc(sizeof(uint32_t *));
*window->id_ptr = &window->id;
window->id_ptr = &window->id;
window->has_shadow = true;

if (g_window_manager.enable_window_border) border_create(window);
Expand All @@ -467,6 +471,5 @@ void window_destroy(struct window *window)
{
border_destroy(window);
CFRelease(window->ref);
free(window->id_ptr);
free(window);
}
2 changes: 1 addition & 1 deletion src/window.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ struct window
AXUIElementRef ref;
int connection;
uint32_t id;
uint32_t **volatile id_ptr;
uint32_t *volatile id_ptr;
uint8_t notification;
bool has_shadow;
bool is_fullscreen;
Expand Down

0 comments on commit a5feed0

Please sign in to comment.