Browse Source

Workspace notifications support on macOS (#12093)

Clément Beffa 7 years ago
parent
commit
642f5a84d4

+ 8 - 2
atom/browser/api/atom_api_system_preferences.cc

@@ -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)

+ 18 - 5
atom/browser/api/atom_api_system_preferences.h

@@ -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
@@ -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);
@@ -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:

+ 68 - 30
atom/browser/api/atom_api_system_preferences_mac.mm

@@ -30,52 +30,82 @@ std::map<int, id> g_id_map;
 
 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
@@ -97,13 +127,21 @@ int SystemPreferences::DoSubscribeNotification(const std::string& name,
   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);
   }

+ 30 - 6
docs/api/system-preferences.md

@@ -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
@@ -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
@@ -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