Skip to content

Commit

Permalink
#2240 macOS14.5: moving windows to spaces require SIP to be disabled
Browse files Browse the repository at this point in the history
  • Loading branch information
koekeishiya committed May 15, 2024
1 parent 0bfaa2d commit 7bacdd5
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 4 deletions.
3 changes: 2 additions & 1 deletion src/osax/common.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef SA_COMMON_H
#define SA_COMMON_H

#define OSAX_VERSION "2.1.7"
#define OSAX_VERSION "2.1.8"

#define OSAX_ATTRIB_DOCK_SPACES 0x01
#define OSAX_ATTRIB_DPPM 0x02
Expand Down Expand Up @@ -38,6 +38,7 @@ enum sa_opcode
SA_OPCODE_WINDOW_SWAP_PROXY_OUT = 0x0F,
SA_OPCODE_WINDOW_ORDER = 0x10,
SA_OPCODE_WINDOW_ORDER_IN = 0x11,
SA_OPCODE_WINDOW_MOVE_SPACE = 0x12,
};

#endif
36 changes: 36 additions & 0 deletions src/osax/payload.m
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
extern CGError SLSGetWindowTransform(int cid, uint32_t wid, CGAffineTransform *t);
extern CGError SLSSetWindowTransform(int cid, uint32_t wid, CGAffineTransform t);
extern CGError SLSOrderWindow(int cid, uint32_t wid, int order, uint32_t rel_wid);
extern void SLSMoveWindowsToManagedSpace(int cid, CFArrayRef window_list, uint64_t sid);
extern void SLSManagedDisplaySetCurrentSpace(int cid, CFStringRef display_ref, uint64_t sid);
extern uint64_t SLSManagedDisplayGetCurrentSpace(int cid, CFStringRef display_ref);
extern CFStringRef SLSCopyManagedDisplayForSpace(int cid, uint64_t sid);
Expand Down Expand Up @@ -869,6 +870,38 @@ static void do_window_order_in(char *message)
CFRelease(transaction);
}


static inline CFArrayRef cfarray_of_cfnumbers(void *values, size_t size, int count, CFNumberType type)
{
CFNumberRef temp[count];

for (int i = 0; i < count; ++i) {
temp[i] = CFNumberCreate(NULL, type, ((char *)values) + (size * i));
}

CFArrayRef result = CFArrayCreate(NULL, (const void **)temp, count, &kCFTypeArrayCallBacks);

for (int i = 0; i < count; ++i) {
CFRelease(temp[i]);
}

return result;
}

static void do_window_move_space(char *message)
{
uint32_t wid;
unpack(wid);
if (!wid) return;

uint64_t sid;
unpack(sid);

CFArrayRef window_list_ref = cfarray_of_cfnumbers(&wid, sizeof(uint32_t), 1, kCFNumberSInt32Type);
SLSMoveWindowsToManagedSpace(SLSMainConnectionID(), window_list_ref, sid);
CFRelease(window_list_ref);
}

static void do_handshake(int sockfd)
{
uint32_t attrib = 0;
Expand Down Expand Up @@ -949,6 +982,9 @@ static void handle_message(int sockfd, char *message)
case SA_OPCODE_WINDOW_ORDER_IN: {
do_window_order_in(message);
} break;
case SA_OPCODE_WINDOW_MOVE_SPACE: {
do_window_move_space(message);
} break;
}
}

Expand Down
1 change: 1 addition & 0 deletions src/sa.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ bool scripting_addition_swap_window_proxy_in(struct window_animation *animation_
bool scripting_addition_swap_window_proxy_out(struct window_animation *animation_list, int animation_count);
bool scripting_addition_order_window(uint32_t a_wid, int order, uint32_t b_wid);
bool scripting_addition_order_window_in(uint32_t *window_list, int window_count);
bool scripting_addition_move_window_to_space(uint32_t wid, uint64_t sid);

#endif
8 changes: 8 additions & 0 deletions src/sa.m
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,14 @@ bool scripting_addition_order_window_in(uint32_t *window_list, int window_count)
return sa_payload_send(SA_OPCODE_WINDOW_ORDER_IN);
}

bool scripting_addition_move_window_to_space(uint32_t wid, uint64_t sid)
{
sa_payload_init();
pack(wid);
pack(sid);
return sa_payload_send(SA_OPCODE_WINDOW_MOVE_SPACE);
}

#undef sa_payload_init
#undef pack
#undef sa_payload_send
10 changes: 7 additions & 3 deletions src/space_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -696,9 +696,13 @@ uint64_t space_manager_active_space(void)

void space_manager_move_window_to_space(uint64_t sid, struct window *window)
{
CFArrayRef window_list_ref = cfarray_of_cfnumbers(&window->id, sizeof(uint32_t), 1, kCFNumberSInt32Type);
SLSMoveWindowsToManagedSpace(g_connection, window_list_ref, sid);
CFRelease(window_list_ref);
if (workspace_is_macos_sonoma14_5_or_newer()) {
scripting_addition_move_window_to_space(window->id, sid);
} else {
CFArrayRef window_list_ref = cfarray_of_cfnumbers(&window->id, sizeof(uint32_t), 1, kCFNumberSInt32Type);
SLSMoveWindowsToManagedSpace(g_connection, window_list_ref, sid);
CFRelease(window_list_ref);
}
}

static inline uint64_t space_manager_find_first_user_space_for_display(uint32_t did)
Expand Down
1 change: 1 addition & 0 deletions src/workspace.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@ void workspace_application_observe_activation_policy(void *context, struct proce
int workspace_display_notch_height(uint32_t did);
pid_t workspace_get_dock_pid(void);
bool workspace_event_handler_begin(void **context);
bool workspace_is_macos_sonoma14_5_or_newer(void);

#endif
11 changes: 11 additions & 0 deletions src/workspace.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,17 @@ bool workspace_event_handler_begin(void **context)
return true;
}

bool workspace_is_macos_sonoma14_5_or_newer(void)
{
NSOperatingSystemVersion os_version = [[NSProcessInfo processInfo] operatingSystemVersion];

if (os_version.majorVersion > 14) return true;

if (os_version.majorVersion == 14 && os_version.minorVersion >= 5) return true;

return false;
}

void *workspace_application_create_running_ns_application(struct process *process)
{
return [[NSRunningApplication runningApplicationWithProcessIdentifier:process->pid] retain];
Expand Down

0 comments on commit 7bacdd5

Please sign in to comment.