Bug 1043489 - Fix MacOS X holding screensaver lock with fullscreen video. r=smichaud
authorRalph Giles <giles@mozilla.com>
Tue, 07 Oct 2014 18:20:00 -0700
changeset 232465 0564e5f5037c1f948f8760f9cfa87cc99d4a63a1
parent 232464 f622aedd4348c7b0cff5f166859eee571b010b79
child 232466 a86612eb044a4d5da1d0522bff175107a7340eeb
push id4187
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:29:12 +0000
treeherdermozilla-beta@f23cc6a30c11 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmichaud
bugs1043489, 1063995
milestone35.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1043489 - Fix MacOS X holding screensaver lock with fullscreen video. r=smichaud This ports the fix Chris Pearce made to the windows code in bug 1063995. We just listen for the 'screen' topic and rely on the notification machinery to filter duplicates. This avoids incrementing the lock count on both playback start and fullscreen, and thus waiting until fullscreen exits after playback stops before enabling the screensaver again.
widget/cocoa/nsAppShell.mm
--- a/widget/cocoa/nsAppShell.mm
+++ b/widget/cocoa/nsAppShell.mm
@@ -49,60 +49,49 @@ public:
   NS_DECL_ISUPPORTS;
 
 private:
   ~MacWakeLockListener() {}
 
   IOPMAssertionID mAssertionID = kIOPMNullAssertionID;
 
   NS_IMETHOD Callback(const nsAString& aTopic, const nsAString& aState) {
-    bool isLocked = mLockedTopics.Contains(aTopic);
-    bool shouldLock = aState.EqualsLiteral("locked-foreground");
-    if (isLocked == shouldLock) {
+    if (!aTopic.EqualsASCII("screen")) {
       return NS_OK;
     }
-    if (shouldLock) {
-      if (!mLockedTopics.Count()) {
-        // This is the first topic to request the screen saver be disabled.
-        // Prevent screen saver.
-        CFStringRef cf_topic =
-          ::CFStringCreateWithCharacters(kCFAllocatorDefault,
-                                         reinterpret_cast<const UniChar*>
-                                           (aTopic.Data()),
-                                         aTopic.Length());
-        IOReturn success =
-          ::IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep,
-                                        kIOPMAssertionLevelOn,
-                                        cf_topic,
-                                        &mAssertionID);
-        CFRelease(cf_topic);
-        if (success != kIOReturnSuccess) {
-          NS_WARNING("fail to disable screensaver");
-        }
+    // Note the wake lock code ensures that we're not sent duplicate
+    // "locked-foreground" notifications when multiple wake locks are held.
+    if (aState.EqualsASCII("locked-foreground")) {
+      // Prevent screen saver.
+      CFStringRef cf_topic =
+        ::CFStringCreateWithCharacters(kCFAllocatorDefault,
+                                       reinterpret_cast<const UniChar*>
+                                         (aTopic.Data()),
+                                       aTopic.Length());
+      IOReturn success =
+        ::IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep,
+                                      kIOPMAssertionLevelOn,
+                                      cf_topic,
+                                      &mAssertionID);
+      CFRelease(cf_topic);
+      if (success != kIOReturnSuccess) {
+        NS_WARNING("failed to disable screensaver");
       }
-      mLockedTopics.PutEntry(aTopic);
     } else {
-      mLockedTopics.RemoveEntry(aTopic);
-      if (!mLockedTopics.Count()) {
-        // No other outstanding topics have requested screen saver be disabled.
-        // Re-enable screen saver.
-        if (mAssertionID != kIOPMNullAssertionID) {
-          IOReturn result = ::IOPMAssertionRelease(mAssertionID);
-          if (result != kIOReturnSuccess) {
-            NS_WARNING("fail to release screensaver");
-          }
+      // Re-enable screen saver.
+      NS_WARNING("Releasing screensaver");
+      if (mAssertionID != kIOPMNullAssertionID) {
+        IOReturn result = ::IOPMAssertionRelease(mAssertionID);
+        if (result != kIOReturnSuccess) {
+          NS_WARNING("failed to release screensaver");
         }
       }
     }
     return NS_OK;
   }
-  // Keep track of all the topics that have requested a wake lock. When the
-  // number of topics in the hashtable reaches zero, we can uninhibit the
-  // screensaver again.
-  nsTHashtable<nsStringHashKey> mLockedTopics;
 };
 
 // defined in nsCocoaWindow.mm
 extern int32_t             gXULModalLevel;
 
 static bool gAppShellMethodsSwizzled = false;
 
 @implementation GeckoNSApplication