diff --git a/CHANGELOG.md b/CHANGELOG.md index 56a45136..0757e4e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Changed +- No longer necessary to depend on the scripting-addition to focus a window [#102](https://github.com/koekeishiya/yabai/issues/102) ## [1.0.5] - 2019-07-07 ### Changed diff --git a/src/display_manager.c b/src/display_manager.c index 204bf392..af125596 100644 --- a/src/display_manager.c +++ b/src/display_manager.c @@ -227,7 +227,6 @@ void display_manager_focus_display(uint32_t display_id) CGRect bounds; CGPoint point; - uint32_t element_id; AXUIElementRef element_ref; window_list = space_window_list(display_space_id(display_id), &window_count); @@ -237,7 +236,7 @@ void display_manager_focus_display(uint32_t display_id) window = window_manager_find_window(&g_window_manager, window_list[i]); if (!window || !window_is_standard(window)) continue; - window_manager_focus_window_with_raise(window->id); + window_manager_focus_window_with_raise(&window->application->psn, window->id, window->ref); free(window_list); goto out; } @@ -248,15 +247,22 @@ void display_manager_focus_display(uint32_t display_id) bounds = display_bounds(display_id); point = (CGPoint) { bounds.origin.x + bounds.size.width / 2, bounds.origin.y + bounds.size.height / 2 }; element_ref = display_manager_find_element_at_point(point); - element_id = 0; if (element_ref) { - element_id = ax_window_id(element_ref); - CFRelease(element_ref); - } + uint32_t element_id = ax_window_id(element_ref); + + if (element_id) { + int element_connection; + ProcessSerialNumber element_psn; + SLSGetWindowOwner(g_connection, element_id, &element_connection); + SLSGetConnectionPSN(element_connection, &element_psn); + window_manager_focus_window_with_raise(&element_psn, element_id, element_ref); + } else { + CGPostMouseEvent(point, true, 1, true); + CGPostMouseEvent(point, true, 1, false); + } - if (element_id) { - window_manager_focus_window_with_raise(element_id); + CFRelease(element_ref); } else { CGPostMouseEvent(point, true, 1, true); CGPostMouseEvent(point, true, 1, false); diff --git a/src/event.c b/src/event.c index 74768cbd..6bf2a01b 100644 --- a/src/event.c +++ b/src/event.c @@ -963,9 +963,9 @@ static EVENT_CALLBACK(EVENT_HANDLER_MOUSE_MOVED) g_mouse_state.ffm_window_id = window->id; if (g_window_manager.ffm_mode == FFM_AUTOFOCUS) { - window_manager_focus_window_without_raise(window->id); + window_manager_focus_window_without_raise(&window->application->psn, window->id); } else { - window_manager_focus_window_with_raise(window->id); + window_manager_focus_window_with_raise(&window->application->psn, window->id, window->ref); } return EVENT_SUCCESS; diff --git a/src/message.c b/src/message.c index a7892743..6f75bfbe 100644 --- a/src/message.c +++ b/src/message.c @@ -1009,7 +1009,7 @@ static void handle_domain_window(FILE *rsp, struct token domain, char *message) if (window) { struct window *closest_window = window_manager_find_closest_window_in_direction(&g_window_manager, window, DIR_NORTH); if (closest_window) { - window_manager_focus_window_with_raise(closest_window->id); + window_manager_focus_window_with_raise(&closest_window->application->psn, closest_window->id, closest_window->ref); } else { daemon_fail(rsp, "could not locate a northward managed window.\n"); } @@ -1020,7 +1020,7 @@ static void handle_domain_window(FILE *rsp, struct token domain, char *message) if (window) { struct window *closest_window = window_manager_find_closest_window_in_direction(&g_window_manager, window, DIR_EAST); if (closest_window) { - window_manager_focus_window_with_raise(closest_window->id); + window_manager_focus_window_with_raise(&closest_window->application->psn, closest_window->id, closest_window->ref); } else { daemon_fail(rsp, "could not locate a eastward managed window.\n"); } @@ -1031,7 +1031,7 @@ static void handle_domain_window(FILE *rsp, struct token domain, char *message) if (window) { struct window *closest_window = window_manager_find_closest_window_in_direction(&g_window_manager, window, DIR_SOUTH); if (closest_window) { - window_manager_focus_window_with_raise(closest_window->id); + window_manager_focus_window_with_raise(&closest_window->application->psn, closest_window->id, closest_window->ref); } else { daemon_fail(rsp, "could not locate a southward managed window.\n"); } @@ -1042,7 +1042,7 @@ static void handle_domain_window(FILE *rsp, struct token domain, char *message) if (window) { struct window *closest_window = window_manager_find_closest_window_in_direction(&g_window_manager, window, DIR_WEST); if (closest_window) { - window_manager_focus_window_with_raise(closest_window->id); + window_manager_focus_window_with_raise(&closest_window->application->psn, closest_window->id, closest_window->ref); } else { daemon_fail(rsp, "could not locate a westward managed window.\n"); } @@ -1052,7 +1052,7 @@ static void handle_domain_window(FILE *rsp, struct token domain, char *message) } else if (token_equals(value, ARGUMENT_WINDOW_SEL_MOUSE)) { struct window *mouse_window = window_manager_find_window_below_cursor(&g_window_manager); if (mouse_window) { - window_manager_focus_window_with_raise(mouse_window->id); + window_manager_focus_window_with_raise(&mouse_window->application->psn, mouse_window->id, mouse_window->ref); } else { daemon_fail(rsp, "could not locate a window below the cursor.\n"); } @@ -1060,7 +1060,7 @@ static void handle_domain_window(FILE *rsp, struct token domain, char *message) if (window) { struct window *prev_window = window_manager_find_prev_managed_window(&g_space_manager, &g_window_manager, window); if (prev_window) { - window_manager_focus_window_with_raise(prev_window->id); + window_manager_focus_window_with_raise(&prev_window->application->psn, prev_window->id, prev_window->ref); } else { daemon_fail(rsp, "could not locate the prev managed window.\n"); } @@ -1071,7 +1071,7 @@ static void handle_domain_window(FILE *rsp, struct token domain, char *message) if (window) { struct window *next_window = window_manager_find_next_managed_window(&g_space_manager, &g_window_manager, window); if (next_window) { - window_manager_focus_window_with_raise(next_window->id); + window_manager_focus_window_with_raise(&next_window->application->psn, next_window->id, next_window->ref); } else { daemon_fail(rsp, "could not locate the next managed window.\n"); } @@ -1082,7 +1082,7 @@ static void handle_domain_window(FILE *rsp, struct token domain, char *message) if (window) { struct window *first_window = window_manager_find_first_managed_window(&g_space_manager, &g_window_manager); if (first_window) { - window_manager_focus_window_with_raise(first_window->id); + window_manager_focus_window_with_raise(&first_window->application->psn, first_window->id, first_window->ref); } else { daemon_fail(rsp, "could not locate the first managed window.\n"); } @@ -1093,7 +1093,7 @@ static void handle_domain_window(FILE *rsp, struct token domain, char *message) if (window) { struct window *last_window = window_manager_find_last_managed_window(&g_space_manager, &g_window_manager); if (last_window) { - window_manager_focus_window_with_raise(last_window->id); + window_manager_focus_window_with_raise(&last_window->application->psn, last_window->id, last_window->ref); } else { daemon_fail(rsp, "could not locate the last managed window.\n"); } @@ -1103,7 +1103,7 @@ static void handle_domain_window(FILE *rsp, struct token domain, char *message) } else if (token_equals(value, ARGUMENT_COMMON_SEL_RECENT)) { struct window *recent_window = window_manager_find_recent_managed_window(&g_space_manager, &g_window_manager); if (recent_window) { - window_manager_focus_window_with_raise(recent_window->id); + window_manager_focus_window_with_raise(&recent_window->application->psn, recent_window->id, recent_window->ref); } else { daemon_fail(rsp, "could not locate the most recently focused window.\n"); } diff --git a/src/window_manager.c b/src/window_manager.c index 2f3874a2..0ee291e8 100644 --- a/src/window_manager.c +++ b/src/window_manager.c @@ -474,7 +474,7 @@ void window_manager_purify_window(struct window_manager *wm, struct window *wind socket_close(sockfd); } -struct window *window_manager_find_window_on_space_by_rank(struct window_manager *wm, uint64_t sid, int rank) +static struct window *window_manager_find_window_on_space_by_rank(struct window_manager *wm, uint64_t sid, int rank) { int count; uint32_t *window_list = space_window_list(sid, &count); @@ -495,13 +495,6 @@ struct window *window_manager_find_window_on_space_by_rank(struct window_manager return result; } -struct window *window_manager_find_window_on_display_by_rank(struct window_manager *wm, uint32_t did, int rank) -{ - uint32_t sid = display_space_id(did); - struct window *window = window_manager_find_window_on_space_by_rank(wm, sid, rank); - return window; -} - struct window *window_manager_find_window_at_point_filtering_window(struct window_manager *wm, CGPoint point, uint32_t filter_wid) { uint32_t window_id = 0; @@ -697,33 +690,33 @@ static void window_manager_activate_window(ProcessSerialNumber *window_psn, uint SLPSPostEventRecordTo(window_psn, bytes); } -void window_manager_focus_window_without_raise(uint32_t window_id) +void window_manager_focus_window_without_raise(ProcessSerialNumber *window_psn, uint32_t window_id) { - int window_connection; - ProcessSerialNumber window_psn; - pid_t window_pid; + window_manager_defer_window_raise(window_psn, window_id); - SLSGetWindowOwner(g_connection, window_id, &window_connection); - SLSGetConnectionPSN(window_connection, &window_psn); - SLSConnectionGetPID(window_connection, &window_pid); + if (psn_equals(window_psn, &g_window_manager.focused_window_psn)) { + window_manager_deactivate_window(&g_window_manager.focused_window_psn, g_window_manager.focused_window_id); - window_manager_defer_window_raise(&window_psn, window_id); - window_manager_deactivate_window(&g_window_manager.focused_window_psn, g_window_manager.focused_window_id); + // @hack + // Artificially delay the activation by 1ms. This is necessary + // because some applications appear to be confused if both of + // the events appear instantaneously. + usleep(10000); - // @hack - // Artificially delay the activation by 1ms. This is necessary - // because some applications appear to be confused if both of - // the events appear instantaneously. - usleep(10000); + window_manager_activate_window(window_psn, window_id); + } - window_manager_activate_window(&window_psn, window_id); - _SLPSSetFrontProcessWithOptions(&window_psn, window_id, kCPSUserGenerated); - window_manager_make_key_window(&window_psn, window_id); + _SLPSSetFrontProcessWithOptions(window_psn, window_id, kCPSUserGenerated); + window_manager_make_key_window(window_psn, window_id); } -void window_manager_focus_window_with_raise(uint32_t window_id) +void window_manager_focus_window_with_raise(ProcessSerialNumber *window_psn, uint32_t window_id, AXUIElementRef window_ref) { #if 1 + _SLPSSetFrontProcessWithOptions(window_psn, window_id, kCPSUserGenerated); + window_manager_make_key_window(window_psn, window_id); + AXUIElementPerformAction(window_ref, kAXRaiseAction); +#else int sockfd; char message[MAXLEN]; @@ -733,12 +726,6 @@ void window_manager_focus_window_with_raise(uint32_t window_id) socket_wait(sockfd); } socket_close(sockfd); -#else - struct window *window = window_manager_find_window(&g_window_manager, window_id); - if (!window) return; - - AXUIElementPerformAction(window->ref, kAXRaiseAction); - _SLPSSetFrontProcessWithOptions(&window->application->psn, 0, kCPSNoWindows); #endif } @@ -1034,8 +1021,7 @@ void window_manager_send_window_to_display(struct space_manager *sm, struct wind struct window *next = window_manager_find_window_on_space_by_rank(wm, src_sid, 1); if (next) { - AXUIElementPerformAction(next->ref, kAXRaiseAction); - _SLPSSetFrontProcessWithOptions(&next->application->psn, 0, kCPSNoWindows); + window_manager_focus_window_with_raise(&next->application->psn, next->id, next->ref); } else { _SLPSSetFrontProcessWithOptions(&g_process_manager.finder_psn, 0, kCPSNoWindows); } @@ -1065,8 +1051,7 @@ void window_manager_send_window_to_space(struct space_manager *sm, struct window struct window *next = window_manager_find_window_on_space_by_rank(wm, src_sid, 1); if (next) { - AXUIElementPerformAction(next->ref, kAXRaiseAction); - _SLPSSetFrontProcessWithOptions(&next->application->psn, 0, kCPSNoWindows); + window_manager_focus_window_with_raise(&next->application->psn, next->id, next->ref); } else { _SLPSSetFrontProcessWithOptions(&g_process_manager.finder_psn, 0, kCPSNoWindows); } diff --git a/src/window_manager.h b/src/window_manager.h index 2fcf3baa..7a052a04 100644 --- a/src/window_manager.h +++ b/src/window_manager.h @@ -83,8 +83,6 @@ bool window_manager_should_manage_window(struct window *window); void window_manager_tile_window(struct window_manager *wm, struct window *window); void window_manager_move_window(struct window *window, float x, float y); void window_manager_resize_window(struct window *window, float width, float height); -struct window *window_manager_find_window_on_space_by_rank(struct window_manager *wm, uint64_t sid, int rank); -struct window *window_manager_find_window_on_display_by_rank(struct window_manager *wm, uint32_t did, int rank); struct window *window_manager_find_window_at_point_filtering_window(struct window_manager *wm, CGPoint point, uint32_t filter_wid); struct window *window_manager_find_window_at_point(struct window_manager *wm, CGPoint point); struct window *window_manager_find_window_below_cursor(struct window_manager *wm); @@ -95,8 +93,8 @@ struct window *window_manager_find_next_managed_window(struct space_manager *sm, struct window *window_manager_find_first_managed_window(struct space_manager *sm, struct window_manager *wm); struct window *window_manager_find_last_managed_window(struct space_manager *sm, struct window_manager *wm); struct window *window_manager_find_recent_managed_window(struct space_manager *sm, struct window_manager *wm); -void window_manager_focus_window_without_raise(uint32_t window_id); -void window_manager_focus_window_with_raise(uint32_t window_id); +void window_manager_focus_window_without_raise(ProcessSerialNumber *window_psn, uint32_t window_id); +void window_manager_focus_window_with_raise(ProcessSerialNumber *window_psn, uint32_t window_id, AXUIElementRef window_ref); struct window *window_manager_focused_window(struct window_manager *wm); struct application *window_manager_focused_application(struct window_manager *wm); struct view *window_manager_find_managed_window(struct window_manager *wm, struct window *window);