Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workspace notifications support on macOS #12093

Merged
merged 6 commits into from Mar 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 8 additions & 2 deletions atom/browser/api/atom_api_system_preferences.cc
Expand Up @@ -55,16 +55,22 @@ void SystemPreferences::BuildPrototype(
#elif defined(OS_MACOSX)
.SetMethod("postNotification",
&SystemPreferences::PostNotification)
.SetMethod("postLocalNotification",
&SystemPreferences::PostLocalNotification)
.SetMethod("subscribeNotification",
&SystemPreferences::SubscribeNotification)
.SetMethod("unsubscribeNotification",
&SystemPreferences::UnsubscribeNotification)
.SetMethod("postLocalNotification",
&SystemPreferences::PostLocalNotification)
.SetMethod("subscribeLocalNotification",
&SystemPreferences::SubscribeLocalNotification)
.SetMethod("unsubscribeLocalNotification",
&SystemPreferences::UnsubscribeLocalNotification)
.SetMethod("postWorkspaceNotification",
&SystemPreferences::PostWorkspaceNotification)
.SetMethod("subscribeWorkspaceNotification",
&SystemPreferences::SubscribeWorkspaceNotification)
.SetMethod("unsubscribeWorkspaceNotification",
&SystemPreferences::UnsubscribeWorkspaceNotification)
.SetMethod("registerDefaults", &SystemPreferences::RegisterDefaults)
.SetMethod("getUserDefault", &SystemPreferences::GetUserDefault)
.SetMethod("setUserDefault", &SystemPreferences::SetUserDefault)
Expand Down
23 changes: 18 additions & 5 deletions atom/browser/api/atom_api_system_preferences.h
Expand Up @@ -26,6 +26,14 @@ namespace atom {

namespace api {

#if defined(OS_MACOSX)
enum NotificationCenterKind {
kNSDistributedNotificationCenter = 0,
kNSNotificationCenter,
kNSWorkspaceNotificationCenter,
};
#endif

class SystemPreferences : public mate::EventEmitter<SystemPreferences>
#if defined(OS_WIN)
, public BrowserObserver
Expand Down Expand Up @@ -63,14 +71,19 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences>

void PostNotification(const std::string& name,
const base::DictionaryValue& user_info);
void PostLocalNotification(const std::string& name,
const base::DictionaryValue& user_info);
int SubscribeNotification(const std::string& name,
const NotificationCallback& callback);
void UnsubscribeNotification(int id);
void PostLocalNotification(const std::string& name,
const base::DictionaryValue& user_info);
int SubscribeLocalNotification(const std::string& name,
const NotificationCallback& callback);
void UnsubscribeLocalNotification(int request_id);
void PostWorkspaceNotification(const std::string& name,
const base::DictionaryValue& user_info);
int SubscribeWorkspaceNotification(const std::string& name,
const NotificationCallback& callback);
void UnsubscribeWorkspaceNotification(int request_id);
v8::Local<v8::Value> GetUserDefault(const std::string& name,
const std::string& type);
void RegisterDefaults(mate::Arguments* args);
Expand All @@ -90,11 +103,11 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences>
#if defined(OS_MACOSX)
void DoPostNotification(const std::string& name,
const base::DictionaryValue& user_info,
bool is_local);
NotificationCenterKind kind);
int DoSubscribeNotification(const std::string& name,
const NotificationCallback& callback,
bool is_local);
void DoUnsubscribeNotification(int request_id, bool is_local);
NotificationCenterKind kind);
void DoUnsubscribeNotification(int request_id, NotificationCenterKind kind);
#endif

private:
Expand Down
98 changes: 68 additions & 30 deletions atom/browser/api/atom_api_system_preferences_mac.mm
Expand Up @@ -30,52 +30,82 @@

void SystemPreferences::PostNotification(const std::string& name,
const base::DictionaryValue& user_info) {
DoPostNotification(name, user_info, false);
DoPostNotification(name, user_info, kNSDistributedNotificationCenter);
}

int SystemPreferences::SubscribeNotification(
const std::string& name, const NotificationCallback& callback) {
return DoSubscribeNotification(name, callback, kNSDistributedNotificationCenter);
}

void SystemPreferences::UnsubscribeNotification(int request_id) {
DoUnsubscribeNotification(request_id, kNSDistributedNotificationCenter);
}

void SystemPreferences::PostLocalNotification(const std::string& name,
const base::DictionaryValue& user_info) {
DoPostNotification(name, user_info, true);
DoPostNotification(name, user_info, kNSNotificationCenter);
}

void SystemPreferences::DoPostNotification(const std::string& name,
const base::DictionaryValue& user_info, bool is_local) {
NSNotificationCenter* center = is_local ?
[NSNotificationCenter defaultCenter] :
[NSDistributedNotificationCenter defaultCenter];
[center
postNotificationName:base::SysUTF8ToNSString(name)
object:nil
userInfo:DictionaryValueToNSDictionary(user_info)
];
int SystemPreferences::SubscribeLocalNotification(
const std::string& name, const NotificationCallback& callback) {
return DoSubscribeNotification(name, callback, kNSNotificationCenter);
}

int SystemPreferences::SubscribeNotification(
const std::string& name, const NotificationCallback& callback) {
return DoSubscribeNotification(name, callback, false);
void SystemPreferences::UnsubscribeLocalNotification(int request_id) {
DoUnsubscribeNotification(request_id, kNSNotificationCenter);
}

void SystemPreferences::UnsubscribeNotification(int request_id) {
DoUnsubscribeNotification(request_id, false);
void SystemPreferences::PostWorkspaceNotification(const std::string& name,
const base::DictionaryValue& user_info) {
DoPostNotification(name, user_info, kNSWorkspaceNotificationCenter);
}

int SystemPreferences::SubscribeLocalNotification(
int SystemPreferences::SubscribeWorkspaceNotification(
const std::string& name, const NotificationCallback& callback) {
return DoSubscribeNotification(name, callback, true);
return DoSubscribeNotification(name, callback, kNSWorkspaceNotificationCenter);
}

void SystemPreferences::UnsubscribeLocalNotification(int request_id) {
DoUnsubscribeNotification(request_id, true);
void SystemPreferences::UnsubscribeWorkspaceNotification(int request_id) {
DoUnsubscribeNotification(request_id, kNSWorkspaceNotificationCenter);
}

void SystemPreferences::DoPostNotification(const std::string& name,
const base::DictionaryValue& user_info, NotificationCenterKind kind) {
NSNotificationCenter* center;
switch (kind) {
case kNSDistributedNotificationCenter:
center = [NSDistributedNotificationCenter defaultCenter]; break;
case kNSNotificationCenter:
center = [NSNotificationCenter defaultCenter]; break;
case kNSWorkspaceNotificationCenter:
center = [[NSWorkspace sharedWorkspace] notificationCenter]; break;
default:
break;
}
[center
postNotificationName:base::SysUTF8ToNSString(name)
object:nil
userInfo:DictionaryValueToNSDictionary(user_info)
];
}

int SystemPreferences::DoSubscribeNotification(const std::string& name,
const NotificationCallback& callback, bool is_local) {
const NotificationCallback& callback, NotificationCenterKind kind) {
int request_id = g_next_id++;
__block NotificationCallback copied_callback = callback;
NSNotificationCenter* center = is_local ?
[NSNotificationCenter defaultCenter] :
[NSDistributedNotificationCenter defaultCenter];

NSNotificationCenter* center;
switch (kind) {
case kNSDistributedNotificationCenter:
center = [NSDistributedNotificationCenter defaultCenter]; break;
case kNSNotificationCenter:
center = [NSNotificationCenter defaultCenter]; break;
case kNSWorkspaceNotificationCenter:
center = [[NSWorkspace sharedWorkspace] notificationCenter]; break;
default:
break;
}

g_id_map[request_id] = [center
addObserverForName:base::SysUTF8ToNSString(name)
object:nil
Expand All @@ -97,13 +127,21 @@
return request_id;
}

void SystemPreferences::DoUnsubscribeNotification(int request_id, bool is_local) {
void SystemPreferences::DoUnsubscribeNotification(int request_id, NotificationCenterKind kind) {
auto iter = g_id_map.find(request_id);
if (iter != g_id_map.end()) {
id observer = iter->second;
NSNotificationCenter* center = is_local ?
[NSNotificationCenter defaultCenter] :
[NSDistributedNotificationCenter defaultCenter];
NSNotificationCenter* center;
switch (kind) {
case kNSDistributedNotificationCenter:
center = [NSDistributedNotificationCenter defaultCenter]; break;
case kNSNotificationCenter:
center = [NSNotificationCenter defaultCenter]; break;
case kNSWorkspaceNotificationCenter:
center = [[NSWorkspace sharedWorkspace] notificationCenter]; break;
default:
break;
}
[center removeObserver:observer];
g_id_map.erase(iter);
}
Expand Down
36 changes: 30 additions & 6 deletions docs/api/system-preferences.md
Expand Up @@ -61,6 +61,14 @@ that contains the user information dictionary sent along with the notification.
Posts `event` as native notifications of macOS. The `userInfo` is an Object
that contains the user information dictionary sent along with the notification.

### `systemPreferences.postWorkspaceNotification(event, userInfo)` _macOS_

* `event` String
* `userInfo` Object

Posts `event` as native notifications of macOS. The `userInfo` is an Object
that contains the user information dictionary sent along with the notification.

### `systemPreferences.subscribeNotification(event, callback)` _macOS_

* `event` String
Expand All @@ -84,12 +92,6 @@ example values of `event` are:
* `AppleColorPreferencesChangedNotification`
* `AppleShowScrollBarsSettingChanged`

### `systemPreferences.unsubscribeNotification(id)` _macOS_

* `id` Integer

Removes the subscriber with `id`.

### `systemPreferences.subscribeLocalNotification(event, callback)` _macOS_

* `event` String
Expand All @@ -100,12 +102,34 @@ Removes the subscriber with `id`.
Same as `subscribeNotification`, but uses `NSNotificationCenter` for local defaults.
This is necessary for events such as `NSUserDefaultsDidChangeNotification`.

### `systemPreferences.subscribeWorkspaceNotification(event, callback)` _macOS_

* `event` String
* `callback` Function
* `event` String
* `userInfo` Object

Same as `subscribeNotification`, but uses `NSWorkspace.sharedWorkspace.notificationCenter`.
This is necessary for events such as `NSWorkspaceDidActivateApplicationNotification`.

### `systemPreferences.unsubscribeNotification(id)` _macOS_

* `id` Integer

Removes the subscriber with `id`.

### `systemPreferences.unsubscribeLocalNotification(id)` _macOS_

* `id` Integer

Same as `unsubscribeNotification`, but removes the subscriber from `NSNotificationCenter`.

### `systemPreferences.unsubscribeWorkspaceNotification(id)` _macOS_

* `id` Integer

Same as `unsubscribeNotification`, but removes the subscriber from `NSWorkspace.sharedWorkspace.notificationCenter`.

### `systemPreferences.registerDefaults(defaults)` _macOS_

* `defaults` Object - a dictionary of (`key: value`) user defaults
Expand Down