diff --git a/CHANGELOG.md b/CHANGELOG.md index abfa42b4..e548a28d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Improved SIP detection logic [#716](https://github.com/koekeishiya/yabai/issues/716) - Windows that do not report a title at all should be treated as having the empty string as its title [#707](https://github.com/koekeishiya/yabai/issues/707) - Allow *SPACE_SEL* to be used instead of *mission-control index* when specifying config options for a specific space [#705](https://github.com/koekeishiya/yabai/issues/705) +- Native fullscreen transitions would freeze on macOS Mojave due to internal API differences between macOS version [#690](https://github.com/koekeishiya/yabai/issues/690) ## [3.3.4] - 2020-11-14 ### Changed diff --git a/src/event.c b/src/event.c index 7a1498e2..4f8f0e50 100644 --- a/src/event.c +++ b/src/event.c @@ -423,18 +423,7 @@ static EVENT_CALLBACK(EVENT_HANDLER_WINDOW_RESIZED) window_manager_purify_window(&g_window_manager, window); } } else if (was_fullscreen && !is_fullscreen) { - uint32_t did = window_display_id(window); - - do { - - // - // NOTE(koekeishiya): Window has exited native-fullscreen mode. - // We need to spin lock until the display is finished animating - // because we are not actually able to interact with the window. - // - - usleep(100000); - } while (display_manager_display_is_animating(did)); + window_manager_wait_for_native_fullscreen_transition(window); if (window_manager_should_manage_window(window) && !window_manager_find_managed_window(&g_window_manager, window)) { struct view *view = space_manager_tile_window_on_space(&g_space_manager, window, window_space(window)); diff --git a/src/window_manager.c b/src/window_manager.c index dcb38794..bc98a154 100644 --- a/src/window_manager.c +++ b/src/window_manager.c @@ -1357,6 +1357,40 @@ void window_manager_toggle_window_shadow(struct space_manager *sm, struct window if (scripting_addition_set_shadow(window->id, shadow)) window->has_shadow = shadow; } +void window_manager_wait_for_native_fullscreen_transition(struct window *window) +{ + if (workspace_is_macos_mojave()) { + while (!space_is_user(space_manager_active_space())) { + + // + // NOTE(koekeishiya): Window has exited native-fullscreen mode. + // We need to spin lock until the display is finished animating + // because we are not actually able to interact with the window. + // + // macOS Mojave freezes fullscreen applications when using the + // display_manager API to check for animation status: + // + // - https://github.com/koekeishiya/yabai/issues/690 + // + + usleep(100000); + } + } else { + uint32_t did = window_display_id(window); + + do { + + // + // NOTE(koekeishiya): Window has exited native-fullscreen mode. + // We need to spin lock until the display is finished animating + // because we are not actually able to interact with the window. + // + + usleep(100000); + } while (display_manager_display_is_animating(did)); + } +} + void window_manager_toggle_window_native_fullscreen(struct space_manager *sm, struct window_manager *wm, struct window *window) { uint32_t sid = window_space(window); diff --git a/src/window_manager.h b/src/window_manager.h index e3051c02..c098dfde 100644 --- a/src/window_manager.h +++ b/src/window_manager.h @@ -181,6 +181,7 @@ void window_manager_toggle_window_native_fullscreen(struct space_manager *sm, st void window_manager_toggle_window_expose(struct window_manager *wm, struct window *window); void window_manager_toggle_window_pip(struct space_manager *sm, struct window_manager *wm, struct window *window); void window_manager_toggle_window_border(struct window_manager *wm, struct window *window); +void window_manager_wait_for_native_fullscreen_transition(struct window *window); void window_manager_validate_and_check_for_windows_on_space(struct space_manager *sm, struct window_manager *wm, uint64_t sid); void window_manager_handle_display_add_and_remove(struct space_manager *sm, struct window_manager *wm, uint32_t did); void window_manager_begin(struct space_manager *sm, struct window_manager *window_manager); diff --git a/src/workspace.h b/src/workspace.h index 408e7a27..784483ef 100644 --- a/src/workspace.h +++ b/src/workspace.h @@ -19,6 +19,7 @@ void workspace_application_observe_finished_launching(void *context, struct proc void workspace_application_observe_activation_policy(void *context, struct process *process); bool workspace_is_macos_bigsur(void); bool workspace_is_macos_catalina(void); +bool workspace_is_macos_mojave(void); bool workspace_is_macos_highsierra(void); #endif diff --git a/src/workspace.m b/src/workspace.m index cc2fb5b6..c32bb99a 100644 --- a/src/workspace.m +++ b/src/workspace.m @@ -113,6 +113,12 @@ bool workspace_is_macos_catalina(void) return version.majorVersion == 10 && version.minorVersion == 15; } +bool workspace_is_macos_mojave(void) +{ + NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion]; + return version.majorVersion == 10 && version.minorVersion == 14; +} + bool workspace_is_macos_highsierra(void) { NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion];