Skip to content

Commit

Permalink
fix: normalize behavior of win.setOpacity() for invalid number valu…
Browse files Browse the repository at this point in the history
…es across operating systems (#19535)

* fix: define behavior for out-of-bounds setOpacity

* fix linux issue

* fix getOpacity behaviour

* wrong variable

* normalize more stuff

* docs

* test: use ifdescribe helper

* Update spec-main/api-browser-window-spec.ts

Co-Authored-By: Charles Kerr <ckerr@github.com>

* fixes

* more tests!!!

* Update shell/browser/native_window_views.cc

Co-Authored-By: Charles Kerr <ckerr@github.com>

* Update shell/browser/native_window_mac.mm

Co-Authored-By: Charles Kerr <ckerr@github.com>
  • Loading branch information
erickzhao and ckerr committed Aug 7, 2019
1 parent a0f4632 commit a8a0987
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 22 deletions.
8 changes: 5 additions & 3 deletions docs/api/browser-window.md
Expand Up @@ -1455,11 +1455,13 @@ On Windows and Linux always returns

* `opacity` Number - between 0.0 (fully transparent) and 1.0 (fully opaque)

Sets the opacity of the window. On Linux does nothing.
Sets the opacity of the window. On Linux, does nothing. Out of bound number
values are clamped to the [0, 1] range.

#### `win.getOpacity()` _Windows_ _macOS_
#### `win.getOpacity()`

Returns `Number` - between 0.0 (fully transparent) and 1.0 (fully opaque)
Returns `Number` - between 0.0 (fully transparent) and 1.0 (fully opaque). On
Linux, always returns 1.

#### `win.setShape(rects)` _Windows_ _Linux_ _Experimental_

Expand Down
4 changes: 3 additions & 1 deletion shell/browser/native_window_mac.mm
Expand Up @@ -12,6 +12,7 @@

#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 "components/remote_cocoa/app_shim/native_widget_ns_window_bridge.h"
#include "content/public/browser/browser_accessibility_state.h"
Expand Down Expand Up @@ -1032,7 +1033,8 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
}

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() {
Expand Down
8 changes: 6 additions & 2 deletions shell/browser/native_window_views.cc
Expand Up @@ -13,6 +13,7 @@
#include <utility>
#include <vector>

#include "base/numerics/ranges.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/browser/browser_thread.h"
Expand Down Expand Up @@ -880,16 +881,19 @@ 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);
ex_style |= WS_EX_LAYERED;
::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() {
Expand Down
54 changes: 38 additions & 16 deletions spec-main/api-browser-window-spec.ts
Expand Up @@ -7,12 +7,12 @@ import * as qs from 'querystring'
import * as http from 'http'
import { AddressInfo } from 'net'
import { app, BrowserWindow, BrowserView, ipcMain, OnBeforeSendHeadersListenerDetails, protocol, screen, webContents, session, WebContents } from 'electron'
import { emittedOnce } from './events-helpers';
import { closeWindow } from './window-helpers';
const { expect } = chai

const ifit = (condition: boolean) => (condition ? it : it.skip)
const ifdescribe = (condition: boolean) => (condition ? describe : describe.skip)
import { emittedOnce } from './events-helpers'
import { ifit, ifdescribe } from './spec-helpers'
import { closeWindow } from './window-helpers'

const { expect } = chai

chai.use(chaiAsPromised)

Expand Down Expand Up @@ -1240,22 +1240,44 @@ describe('BrowserWindow module', () => {
})
})


describe('BrowserWindow.setOpacity(opacity)', () => {
afterEach(closeAllWindows)
it('make window with initial opacity', () => {
const w = new BrowserWindow({ show: false, opacity: 0.5 })
expect(w.getOpacity()).to.equal(0.5)
})
it('allows setting the opacity', () => {
const w = new BrowserWindow({ show: false })
expect(() => {
w.setOpacity(0.0)

ifdescribe(process.platform !== 'linux')(('Windows and Mac'), () => {
it('make window with initial opacity', () => {
const w = new BrowserWindow({ show: false, opacity: 0.5 })
expect(w.getOpacity()).to.equal(0.5)
})
it('allows setting the opacity', () => {
const w = new BrowserWindow({ show: false })
expect(() => {
w.setOpacity(0.0)
expect(w.getOpacity()).to.equal(0.0)
w.setOpacity(0.5)
expect(w.getOpacity()).to.equal(0.5)
w.setOpacity(1.0)
expect(w.getOpacity()).to.equal(1.0)
}).to.not.throw()
})

it('clamps opacity to [0.0...1.0]', () => {
const w = new BrowserWindow({ show: false, opacity: 0.5 })
w.setOpacity(100)
expect(w.getOpacity()).to.equal(1.0)
w.setOpacity(-100)
expect(w.getOpacity()).to.equal(0.0)
})
})

ifdescribe(process.platform === 'linux')(('Linux'), () => {
it('sets 1 regardless of parameter', () => {
const w = new BrowserWindow({ show: false })
w.setOpacity(0)
expect(w.getOpacity()).to.equal(1.0)
w.setOpacity(0.5)
expect(w.getOpacity()).to.equal(0.5)
w.setOpacity(1.0)
expect(w.getOpacity()).to.equal(1.0)
}).to.not.throw()
})
})
})

Expand Down

0 comments on commit a8a0987

Please sign in to comment.