Skip to content

Commit

Permalink
feat: programmatically modify traffic light positioning (#22533)
Browse files Browse the repository at this point in the history
* setter

* getter

* specs and docs

* fixup

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
  • Loading branch information
MarshallOfSound and MarshallOfSound committed Mar 5, 2020
1 parent 1811751 commit 3e2cec8
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 5 deletions.
11 changes: 11 additions & 0 deletions docs/api/browser-window.md
Expand Up @@ -1750,6 +1750,17 @@ will remove the vibrancy effect on the window.
Note that `appearance-based`, `light`, `dark`, `medium-light`, and `ultra-dark` have been
deprecated and will be removed in an upcoming version of macOS.

#### `win.setTrafficLightPosition(position)` _macOS_

* `position` [Point](structures/point.md)

Set a custom position for the traffic light buttons. Can only be used with `titleBarStyle` set to `hidden`.

#### `win.getTrafficLightPosition()` _macOS_

Returns `Point` - The current position for the traffic light buttons. Can only be used with `titleBarStyle`
set to `hidden`.

#### `win.setTouchBar(touchBar)` _macOS_ _Experimental_

* `touchBar` TouchBar | null
Expand Down
16 changes: 16 additions & 0 deletions shell/browser/api/electron_api_top_level_window.cc
Expand Up @@ -814,6 +814,16 @@ void TopLevelWindow::SetVibrancy(v8::Isolate* isolate,
window_->SetVibrancy(type);
}

#if defined(OS_MACOSX)
void TopLevelWindow::SetTrafficLightPosition(const gfx::Point& position) {
window_->SetTrafficLightPosition(position);
}

gfx::Point TopLevelWindow::GetTrafficLightPosition() const {
return window_->GetTrafficLightPosition();
}
#endif

void TopLevelWindow::SetTouchBar(
std::vector<gin_helper::PersistentDictionary> items) {
window_->SetTouchBar(std::move(items));
Expand Down Expand Up @@ -1184,6 +1194,12 @@ void TopLevelWindow::BuildPrototype(v8::Isolate* isolate,
.SetMethod("setAutoHideCursor", &TopLevelWindow::SetAutoHideCursor)
#endif
.SetMethod("setVibrancy", &TopLevelWindow::SetVibrancy)
#if defined(OS_MACOSX)
.SetMethod("setTrafficLightPosition",
&TopLevelWindow::SetTrafficLightPosition)
.SetMethod("getTrafficLightPosition",
&TopLevelWindow::GetTrafficLightPosition)
#endif
.SetMethod("_setTouchBarItems", &TopLevelWindow::SetTouchBar)
.SetMethod("_refreshTouchBarItem", &TopLevelWindow::RefreshTouchBarItem)
.SetMethod("_setEscapeTouchBarItem",
Expand Down
6 changes: 6 additions & 0 deletions shell/browser/api/electron_api_top_level_window.h
Expand Up @@ -185,6 +185,12 @@ class TopLevelWindow : public gin_helper::TrackableObject<TopLevelWindow>,
bool IsVisibleOnAllWorkspaces();
void SetAutoHideCursor(bool auto_hide);
virtual void SetVibrancy(v8::Isolate* isolate, v8::Local<v8::Value> value);

#if defined(OS_MACOSX)
void SetTrafficLightPosition(const gfx::Point& position);
gfx::Point GetTrafficLightPosition() const;
#endif

void SetTouchBar(std::vector<gin_helper::PersistentDictionary> items);
void RefreshTouchBarItem(const std::string& item_id);
void SetEscapeTouchBarItem(gin_helper::PersistentDictionary item);
Expand Down
6 changes: 6 additions & 0 deletions shell/browser/native_window.h
Expand Up @@ -194,6 +194,12 @@ class NativeWindow : public base::SupportsUserData,
// Vibrancy API
virtual void SetVibrancy(const std::string& type);

// Traffic Light API
#if defined(OS_MACOSX)
virtual void SetTrafficLightPosition(const gfx::Point& position) = 0;
virtual gfx::Point GetTrafficLightPosition() const = 0;
#endif

// Touchbar API
virtual void SetTouchBar(std::vector<gin_helper::PersistentDictionary> items);
virtual void RefreshTouchBarItem(const std::string& item_id);
Expand Down
2 changes: 2 additions & 0 deletions shell/browser/native_window_mac.h
Expand Up @@ -153,6 +153,8 @@ class NativeWindowMac : public NativeWindow, public ui::NativeThemeObserver {
// Custom traffic light positioning
void RepositionTrafficLights();
void SetExitingFullScreen(bool flag);
void SetTrafficLightPosition(const gfx::Point& position) override;
gfx::Point GetTrafficLightPosition() const override;
void OnNativeThemeUpdated(ui::NativeTheme* observed_theme) override;

enum class TitleBarStyle {
Expand Down
9 changes: 9 additions & 0 deletions shell/browser/native_window_mac.mm
Expand Up @@ -1552,6 +1552,15 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
[effect_view setMaterial:vibrancyType];
}

void NativeWindowMac::SetTrafficLightPosition(const gfx::Point& position) {
traffic_light_position_ = position;
RepositionTrafficLights();
}

gfx::Point NativeWindowMac::GetTrafficLightPosition() const {
return traffic_light_position_;
}

void NativeWindowMac::SetTouchBar(
std::vector<gin_helper::PersistentDictionary> items) {
if (@available(macOS 10.12.2, *)) {
Expand Down
35 changes: 30 additions & 5 deletions spec-main/api-browser-window-spec.ts
Expand Up @@ -210,7 +210,7 @@ describe('BrowserWindow module', () => {
}).to.throw('Object has been destroyed')
})
it('should not crash when destroying windows with pending events', () => {
const focusListener = () => {}
const focusListener = () => { }
app.on('browser-window-focus', focusListener)
const windowCount = 3
const windowOptions = {
Expand Down Expand Up @@ -281,7 +281,7 @@ describe('BrowserWindow module', () => {
fs.readFile(filePath, (err, data) => {
if (err) return
if (parsedData.username === 'test' &&
parsedData.file === data.toString()) {
parsedData.file === data.toString()) {
res.end()
}
})
Expand Down Expand Up @@ -1347,6 +1347,31 @@ describe('BrowserWindow module', () => {
})
})

ifdescribe(process.platform === 'darwin')('BrowserWindow.getTrafficLightPosition(pos)', () => {
afterEach(closeAllWindows)

it('gets the set traffic light position property', () => {
const pos = { x: 10, y: 10 }
const w = new BrowserWindow({ show: false, titleBarStyle: 'hidden', trafficLightPosition: pos })
const currentPosition = w.getTrafficLightPosition()

expect(currentPosition).to.deep.equal(pos)
})
})

ifdescribe(process.platform === 'darwin')('BrowserWindow.setTrafficLightPosition(pos)', () => {
afterEach(closeAllWindows)

it('can set the traffic light position property', () => {
const pos = { x: 10, y: 10 }
const w = new BrowserWindow({ show: false, titleBarStyle: 'hidden', trafficLightPosition: pos })
w.setTrafficLightPosition(pos)
const currentPosition = w.getTrafficLightPosition()

expect(currentPosition).to.deep.equal(pos)
})
})

ifdescribe(process.platform === 'win32')('BrowserWindow.setAppDetails(options)', () => {
afterEach(closeAllWindows)

Expand Down Expand Up @@ -1613,7 +1638,7 @@ describe('BrowserWindow module', () => {
afterEach(closeAllWindows)

describe('"preload" option', () => {
const doesNotLeakSpec = (name: string, webPrefs: {nodeIntegration: boolean, sandbox: boolean, contextIsolation: boolean}) => {
const doesNotLeakSpec = (name: string, webPrefs: { nodeIntegration: boolean, sandbox: boolean, contextIsolation: boolean }) => {
it(name, async () => {
const w = new BrowserWindow({
webPreferences: {
Expand Down Expand Up @@ -1875,7 +1900,7 @@ describe('BrowserWindow module', () => {
})

describe('"sandbox" option', () => {
function waitForEvents<T> (emitter: {once: Function}, events: string[], callback: () => void) {
function waitForEvents<T> (emitter: { once: Function }, events: string[], callback: () => void) {
let count = events.length
for (const event of events) {
emitter.once(event, () => {
Expand Down Expand Up @@ -2863,7 +2888,7 @@ describe('BrowserWindow module', () => {
return
}
if (rect.height === contentHeight && rect.width === contentWidth &&
!gotInitialFullSizeFrame) {
!gotInitialFullSizeFrame) {
// The initial frame is full-size, but we're looking for a call
// with just the dirty-rect. The next frame should be a smaller
// rect.
Expand Down

0 comments on commit 3e2cec8

Please sign in to comment.