mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-16 13:03:31 +08:00
fix: request macOS notifications from the main queue
The Rust command now keeps the synchronous bridge wait off the invoke thread, but the Objective-C bridge still initiated UserNotifications authorization from that worker. In a packaged app that path could fail immediately and the settings UI collapsed the error into an unsupported environment. Start notification settings reads, authorization requests, and delivery submissions on the macOS main queue while keeping the blocking wait on the worker thread. This preserves foreground-safe notification delivery without deadlocking the UI or losing the system permission prompt. Constraint: UserNotifications APIs are UI-adjacent and should be initiated on the app main queue. Rejected: Only change the unsupported status copy | it would keep the authorization path broken. Confidence: high Scope-risk: narrow Directive: Keep UserNotifications calls main-queue initiated while the synchronous wait remains off the main thread. Tested: cd desktop/src-tauri && cargo test Tested: bun run check:native Tested: SKIP_INSTALL=1 ./scripts/build-macos-arm64.sh Tested: codesign --verify --deep --strict --verbose=2 desktop/build-artifacts/macos-arm64/Claude Code Haha.app Tested: hdiutil verify desktop/build-artifacts/macos-arm64/Claude Code Haha_0.2.1_aarch64.dmg Tested: Computer Use opened /Users/nanmi/workspace/myself_code/claude-code-haha/desktop/build-artifacts/macos-arm64/Claude Code Haha.app and verified Settings -> General shows notifications as authorized after disable/enable. Not-tested: Fresh first-time system notification prompt on a machine that has never granted this bundle identifier.
This commit is contained in:
parent
de9d044bdb
commit
7796fec691
@ -78,6 +78,15 @@ static void cchh_copy_error(char *buffer, uintptr_t buffer_len, NSString *messag
|
||||
buffer[max_len] = '\0';
|
||||
}
|
||||
|
||||
static void cchh_run_on_main_sync(dispatch_block_t block) {
|
||||
if ([NSThread isMainThread]) {
|
||||
block();
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch_sync(dispatch_get_main_queue(), block);
|
||||
}
|
||||
|
||||
void cchh_set_notification_response_callback(CCHHNotificationResponseCallback callback) {
|
||||
cchhNotificationResponseCallback = callback;
|
||||
}
|
||||
@ -116,10 +125,12 @@ int cchh_notification_authorization_status(char *error_buffer, uintptr_t error_b
|
||||
__block NSInteger status = UNAuthorizationStatusNotDetermined;
|
||||
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
|
||||
|
||||
[cchh_notification_center() getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings *settings) {
|
||||
status = settings.authorizationStatus;
|
||||
dispatch_semaphore_signal(semaphore);
|
||||
}];
|
||||
cchh_run_on_main_sync(^{
|
||||
[cchh_notification_center() getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings *settings) {
|
||||
status = settings.authorizationStatus;
|
||||
dispatch_semaphore_signal(semaphore);
|
||||
}];
|
||||
});
|
||||
|
||||
if (dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC)) != 0) {
|
||||
cchh_copy_error(error_buffer, error_buffer_len, @"Timed out while reading macOS notification permission");
|
||||
@ -143,11 +154,13 @@ bool cchh_request_notification_authorization(char *error_buffer, uintptr_t error
|
||||
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
|
||||
UNAuthorizationOptions options = UNAuthorizationOptionAlert | UNAuthorizationOptionSound;
|
||||
|
||||
[cchh_notification_center() requestAuthorizationWithOptions:options completionHandler:^(BOOL isGranted, NSError *error) {
|
||||
granted = isGranted;
|
||||
requestError = error;
|
||||
dispatch_semaphore_signal(semaphore);
|
||||
}];
|
||||
cchh_run_on_main_sync(^{
|
||||
[cchh_notification_center() requestAuthorizationWithOptions:options completionHandler:^(BOOL isGranted, NSError *error) {
|
||||
granted = isGranted;
|
||||
requestError = error;
|
||||
dispatch_semaphore_signal(semaphore);
|
||||
}];
|
||||
});
|
||||
|
||||
if (dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 30 * NSEC_PER_SEC)) != 0) {
|
||||
cchh_copy_error(error_buffer, error_buffer_len, @"Timed out while requesting macOS notification permission");
|
||||
@ -195,10 +208,12 @@ bool cchh_send_user_notification(const char *title, const char *body, const char
|
||||
__block NSError *deliveryError = nil;
|
||||
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
|
||||
|
||||
[cchh_notification_center() addNotificationRequest:request withCompletionHandler:^(NSError *error) {
|
||||
deliveryError = error;
|
||||
dispatch_semaphore_signal(semaphore);
|
||||
}];
|
||||
cchh_run_on_main_sync(^{
|
||||
[cchh_notification_center() addNotificationRequest:request withCompletionHandler:^(NSError *error) {
|
||||
deliveryError = error;
|
||||
dispatch_semaphore_signal(semaphore);
|
||||
}];
|
||||
});
|
||||
|
||||
if (dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC)) != 0) {
|
||||
cchh_copy_error(error_buffer, error_buffer_len, @"Timed out while delivering macOS notification");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user