diff --git a/kitty/cocoa_window.m b/kitty/cocoa_window.m index 8f8903c8e..4f2a01202 100644 --- a/kitty/cocoa_window.m +++ b/kitty/cocoa_window.m @@ -24,8 +24,12 @@ typedef int CGSConnectionID; typedef int CGSWindowID; typedef int CGSWorkspaceID; +typedef enum _CGSSpaceSelector { + kCGSSpaceCurrent = 5, + kCGSSpaceAll = 7 +} CGSSpaceSelector; extern CGSConnectionID _CGSDefaultConnection(void); -extern void CGSGetWindowWorkspace(const CGSConnectionID cid, CGSWindowID wid, CGSWorkspaceID *workspace); +CFArrayRef CGSCopySpacesForWindows(CGSConnectionID Connection, CGSSpaceSelector Type, CFArrayRef Windows); static NSMenuItem* title_menu = NULL; @@ -369,11 +373,20 @@ cocoa_focus_window(void *w) { [window makeKeyWindow]; } -int -cocoa_get_workspace_id(void *w) { +size_t +cocoa_get_workspace_ids(void *w, size_t *workspace_ids, size_t array_sz) { NSWindow *window = (NSWindow*)w; - int ans = -1; - if (window) CGSGetWindowWorkspace(_CGSDefaultConnection(), [window windowNumber], &ans); + if (!window) return 0; + NSArray *window_array = @[ @([window windowNumber]) ]; + CFArrayRef spaces = CGSCopySpacesForWindows(_CGSDefaultConnection(), kCGSSpaceAll, (__bridge CFArrayRef)window_array); + CFIndex ans = CFArrayGetCount(spaces); + if (ans > 0) { + for (CFIndex i = 0; i < MIN(ans, (CFIndex)array_sz); i++) { + NSNumber *s = (NSNumber*)CFArrayGetValueAtIndex(spaces, i); + workspace_ids[i] = [s intValue]; + } + } else ans = 0; + CFRelease(spaces); return ans; } diff --git a/kitty/glfw.c b/kitty/glfw.c index eda64acbd..7b75d57e7 100644 --- a/kitty/glfw.c +++ b/kitty/glfw.c @@ -15,7 +15,7 @@ extern void cocoa_create_global_menu(void); extern void cocoa_set_hide_from_tasks(void); extern void cocoa_set_titlebar_color(void *w, color_type color); extern bool cocoa_alt_option_key_pressed(unsigned long); -extern int cocoa_get_workspace_id(void *w); +extern size_t cocoa_get_workspace_ids(void *w, size_t *workspace_ids, size_t array_sz); #if GLFW_KEY_LAST >= MAX_KEY_COUNT @@ -593,14 +593,29 @@ create_os_window(PyObject UNUSED *self, PyObject *args) { return PyLong_FromUnsignedLongLong(w->id); } +#ifdef __APPLE__ +static inline bool +window_in_same_cocoa_workspace(void *w, size_t *source_workspaces, size_t source_workspace_count) { + static size_t workspaces[64]; + size_t workspace_count = cocoa_get_workspace_ids(w, workspaces, arraysz(workspaces)); + for (size_t i = 0; i < workspace_count; i++) { + for (size_t s = 0; s < source_workspace_count; s++) { + if (source_workspaces[s] == workspaces[i]) return true; + } + } + return false; +} +#endif + void destroy_os_window(OSWindow *w) { #ifdef __APPLE__ - int workspace_id = -1; + static size_t source_workspaces[64]; + size_t source_workspace_count; #endif if (w->handle) { #ifdef __APPLE__ - workspace_id = cocoa_get_workspace_id(glfwGetCocoaWindow(w->handle)); + source_workspace_count = cocoa_get_workspace_ids(glfwGetCocoaWindow(w->handle), source_workspaces, arraysz(source_workspaces)); #endif // Ensure mouse cursor is visible and reset to default shape, needed on macOS show_mouse_cursor(w->handle); @@ -618,7 +633,7 @@ destroy_os_window(OSWindow *w) { if ( c->id != w->id && c->handle && c->shown_once && c->last_focused_counter >= highest_focus_number && - (workspace_id == -1 || cocoa_get_workspace_id(glfwGetCocoaWindow(c->handle)) == workspace_id) + (!source_workspace_count || window_in_same_cocoa_workspace(glfwGetCocoaWindow(c->handle), source_workspaces, source_workspace_count)) ) { highest_focus_number = c->last_focused_counter; window_to_focus = c;