Browse Source

fix: normalize behavior of `win.setOpacity()` for invalid number values across operating systems (#19724)

* fix: normalize behavior of `win.setOpacity()` for invalid number values across operating systems

* expect -> assert

* assert 2

* fix `this` scoping

* fix equality

* tests
Erick Zhao 5 years ago
parent
commit
1d9c3d7d2a

+ 3 - 1
atom/browser/native_window_mac.mm

@@ -22,6 +22,7 @@
 #include "atom/common/options_switches.h"
 #include "base/mac/mac_util.h"
 #include "base/mac/scoped_cftyperef.h"
+#include "base/numerics/ranges.h"
 #include "base/strings/sys_string_conversions.h"
 #include "content/public/browser/browser_accessibility_state.h"
 #include "native_mate/dictionary.h"
@@ -1037,7 +1038,8 @@ bool NativeWindowMac::HasShadow() {
 }
 
 void NativeWindowMac::SetOpacity(const double opacity) {
-  [window_ setAlphaValue:opacity];
+  const double boundedOpacity = base::ClampToRange(opacity, 0.0, 1.0);
+  [window_ setAlphaValue:boundedOpacity];
 }
 
 double NativeWindowMac::GetOpacity() {

+ 6 - 2
atom/browser/native_window_views.cc

@@ -26,6 +26,7 @@
 #include "atom/common/draggable_region.h"
 #include "atom/common/native_mate_converters/image_converter.h"
 #include "atom/common/options_switches.h"
+#include "base/numerics/ranges.h"
 #include "base/strings/utf_string_conversions.h"
 #include "content/public/browser/browser_thread.h"
 #include "native_mate/dictionary.h"
@@ -849,6 +850,7 @@ bool NativeWindowViews::HasShadow() {
 
 void NativeWindowViews::SetOpacity(const double opacity) {
 #if defined(OS_WIN)
+  const double boundedOpacity = base::ClampToRange(opacity, 0.0, 1.0);
   HWND hwnd = GetAcceleratedWidget();
   if (!layered_) {
     LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
@@ -856,9 +858,11 @@ void NativeWindowViews::SetOpacity(const double opacity) {
     ::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style);
     layered_ = true;
   }
-  ::SetLayeredWindowAttributes(hwnd, 0, opacity * 255, LWA_ALPHA);
+  ::SetLayeredWindowAttributes(hwnd, 0, boundedOpacity * 255, LWA_ALPHA);
+  opacity_ = boundedOpacity;
+#else
+  opacity_ = 1.0;  // setOpacity unsupported on Linux
 #endif
-  opacity_ = opacity;
 }
 
 double NativeWindowViews::GetOpacity() {

+ 42 - 14
spec/api-browser-window-spec.js

@@ -1172,23 +1172,51 @@ describe('BrowserWindow module', () => {
   })
 
   describe('BrowserWindow.setOpacity(opacity)', () => {
-    it('make window with initial opacity', () => {
-      w.destroy()
-      w = new BrowserWindow({
-        show: false,
-        width: 400,
-        height: 400,
-        opacity: 0.5
+    describe('Windows and Mac', () => {
+      before(function () {
+        if (process.platform === 'linux') {
+          this.skip()
+        }
       })
-      assert.strictEqual(w.getOpacity(), 0.5)
-    })
-    it('allows setting the opacity', () => {
-      assert.doesNotThrow(() => {
-        w.setOpacity(0.0)
+
+      it('makes a window with initial opacity', () => {
+        w.destroy()
+        w = new BrowserWindow({ show: false, opacity: 0.5 })
+        assert.strictEqual(w.getOpacity(), 0.5)
+      })
+
+      it('allows setting the opacity', () => {
+        assert.doesNotThrow(() => {
+          w.setOpacity(0.0)
+          assert.strictEqual(w.getOpacity(), 0.0)
+          w.setOpacity(0.5)
+          assert.strictEqual(w.getOpacity(), 0.5)
+          w.setOpacity(1.0)
+          assert.strictEqual(w.getOpacity(), 1.0)
+        })
+      })
+
+      it('clamps opacity to [0.0...1.0]', () => {
+        w.setOpacity(100)
+        assert.strictEqual(w.getOpacity(), 1.0)
+        w.setOpacity(-100)
         assert.strictEqual(w.getOpacity(), 0.0)
+      })
+    })
+
+    describe('Linux', () => {
+      before(function () {
+        if (process.platform !== 'linux') {
+          this.skip()
+        }
+      })
+
+      it('sets 1 regardless of parameter', () => {
+        w.destroy()
+        w = new BrowserWindow({ show: false, opacity: 0.5 })
+        w.setOpacity(0)
+        assert.strictEqual(w.getOpacity(), 1.0)
         w.setOpacity(0.5)
-        assert.strictEqual(w.getOpacity(), 0.5)
-        w.setOpacity(1.0)
         assert.strictEqual(w.getOpacity(), 1.0)
       })
     })