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

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

Merged
merged 1 commit into from Aug 7, 2019
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
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