feat: programmatically modify traffic light positioning (#22533)
* setter * getter * specs and docs * fixup Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
This commit is contained in:
parent
1811751c6c
commit
3e2cec83d9
7 changed files with 80 additions and 5 deletions
|
@ -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
|
Note that `appearance-based`, `light`, `dark`, `medium-light`, and `ultra-dark` have been
|
||||||
deprecated and will be removed in an upcoming version of macOS.
|
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_
|
#### `win.setTouchBar(touchBar)` _macOS_ _Experimental_
|
||||||
|
|
||||||
* `touchBar` TouchBar | null
|
* `touchBar` TouchBar | null
|
||||||
|
|
|
@ -814,6 +814,16 @@ void TopLevelWindow::SetVibrancy(v8::Isolate* isolate,
|
||||||
window_->SetVibrancy(type);
|
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(
|
void TopLevelWindow::SetTouchBar(
|
||||||
std::vector<gin_helper::PersistentDictionary> items) {
|
std::vector<gin_helper::PersistentDictionary> items) {
|
||||||
window_->SetTouchBar(std::move(items));
|
window_->SetTouchBar(std::move(items));
|
||||||
|
@ -1184,6 +1194,12 @@ void TopLevelWindow::BuildPrototype(v8::Isolate* isolate,
|
||||||
.SetMethod("setAutoHideCursor", &TopLevelWindow::SetAutoHideCursor)
|
.SetMethod("setAutoHideCursor", &TopLevelWindow::SetAutoHideCursor)
|
||||||
#endif
|
#endif
|
||||||
.SetMethod("setVibrancy", &TopLevelWindow::SetVibrancy)
|
.SetMethod("setVibrancy", &TopLevelWindow::SetVibrancy)
|
||||||
|
#if defined(OS_MACOSX)
|
||||||
|
.SetMethod("setTrafficLightPosition",
|
||||||
|
&TopLevelWindow::SetTrafficLightPosition)
|
||||||
|
.SetMethod("getTrafficLightPosition",
|
||||||
|
&TopLevelWindow::GetTrafficLightPosition)
|
||||||
|
#endif
|
||||||
.SetMethod("_setTouchBarItems", &TopLevelWindow::SetTouchBar)
|
.SetMethod("_setTouchBarItems", &TopLevelWindow::SetTouchBar)
|
||||||
.SetMethod("_refreshTouchBarItem", &TopLevelWindow::RefreshTouchBarItem)
|
.SetMethod("_refreshTouchBarItem", &TopLevelWindow::RefreshTouchBarItem)
|
||||||
.SetMethod("_setEscapeTouchBarItem",
|
.SetMethod("_setEscapeTouchBarItem",
|
||||||
|
|
|
@ -185,6 +185,12 @@ class TopLevelWindow : public gin_helper::TrackableObject<TopLevelWindow>,
|
||||||
bool IsVisibleOnAllWorkspaces();
|
bool IsVisibleOnAllWorkspaces();
|
||||||
void SetAutoHideCursor(bool auto_hide);
|
void SetAutoHideCursor(bool auto_hide);
|
||||||
virtual void SetVibrancy(v8::Isolate* isolate, v8::Local<v8::Value> value);
|
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 SetTouchBar(std::vector<gin_helper::PersistentDictionary> items);
|
||||||
void RefreshTouchBarItem(const std::string& item_id);
|
void RefreshTouchBarItem(const std::string& item_id);
|
||||||
void SetEscapeTouchBarItem(gin_helper::PersistentDictionary item);
|
void SetEscapeTouchBarItem(gin_helper::PersistentDictionary item);
|
||||||
|
|
|
@ -194,6 +194,12 @@ class NativeWindow : public base::SupportsUserData,
|
||||||
// Vibrancy API
|
// Vibrancy API
|
||||||
virtual void SetVibrancy(const std::string& type);
|
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
|
// Touchbar API
|
||||||
virtual void SetTouchBar(std::vector<gin_helper::PersistentDictionary> items);
|
virtual void SetTouchBar(std::vector<gin_helper::PersistentDictionary> items);
|
||||||
virtual void RefreshTouchBarItem(const std::string& item_id);
|
virtual void RefreshTouchBarItem(const std::string& item_id);
|
||||||
|
|
|
@ -153,6 +153,8 @@ class NativeWindowMac : public NativeWindow, public ui::NativeThemeObserver {
|
||||||
// Custom traffic light positioning
|
// Custom traffic light positioning
|
||||||
void RepositionTrafficLights();
|
void RepositionTrafficLights();
|
||||||
void SetExitingFullScreen(bool flag);
|
void SetExitingFullScreen(bool flag);
|
||||||
|
void SetTrafficLightPosition(const gfx::Point& position) override;
|
||||||
|
gfx::Point GetTrafficLightPosition() const override;
|
||||||
void OnNativeThemeUpdated(ui::NativeTheme* observed_theme) override;
|
void OnNativeThemeUpdated(ui::NativeTheme* observed_theme) override;
|
||||||
|
|
||||||
enum class TitleBarStyle {
|
enum class TitleBarStyle {
|
||||||
|
|
|
@ -1552,6 +1552,15 @@ void NativeWindowMac::SetVibrancy(const std::string& type) {
|
||||||
[effect_view setMaterial:vibrancyType];
|
[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(
|
void NativeWindowMac::SetTouchBar(
|
||||||
std::vector<gin_helper::PersistentDictionary> items) {
|
std::vector<gin_helper::PersistentDictionary> items) {
|
||||||
if (@available(macOS 10.12.2, *)) {
|
if (@available(macOS 10.12.2, *)) {
|
||||||
|
|
|
@ -210,7 +210,7 @@ describe('BrowserWindow module', () => {
|
||||||
}).to.throw('Object has been destroyed')
|
}).to.throw('Object has been destroyed')
|
||||||
})
|
})
|
||||||
it('should not crash when destroying windows with pending events', () => {
|
it('should not crash when destroying windows with pending events', () => {
|
||||||
const focusListener = () => {}
|
const focusListener = () => { }
|
||||||
app.on('browser-window-focus', focusListener)
|
app.on('browser-window-focus', focusListener)
|
||||||
const windowCount = 3
|
const windowCount = 3
|
||||||
const windowOptions = {
|
const windowOptions = {
|
||||||
|
@ -281,7 +281,7 @@ describe('BrowserWindow module', () => {
|
||||||
fs.readFile(filePath, (err, data) => {
|
fs.readFile(filePath, (err, data) => {
|
||||||
if (err) return
|
if (err) return
|
||||||
if (parsedData.username === 'test' &&
|
if (parsedData.username === 'test' &&
|
||||||
parsedData.file === data.toString()) {
|
parsedData.file === data.toString()) {
|
||||||
res.end()
|
res.end()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -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)', () => {
|
ifdescribe(process.platform === 'win32')('BrowserWindow.setAppDetails(options)', () => {
|
||||||
afterEach(closeAllWindows)
|
afterEach(closeAllWindows)
|
||||||
|
|
||||||
|
@ -1613,7 +1638,7 @@ describe('BrowserWindow module', () => {
|
||||||
afterEach(closeAllWindows)
|
afterEach(closeAllWindows)
|
||||||
|
|
||||||
describe('"preload" option', () => {
|
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 () => {
|
it(name, async () => {
|
||||||
const w = new BrowserWindow({
|
const w = new BrowserWindow({
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
|
@ -1875,7 +1900,7 @@ describe('BrowserWindow module', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('"sandbox" option', () => {
|
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
|
let count = events.length
|
||||||
for (const event of events) {
|
for (const event of events) {
|
||||||
emitter.once(event, () => {
|
emitter.once(event, () => {
|
||||||
|
@ -2863,7 +2888,7 @@ describe('BrowserWindow module', () => {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (rect.height === contentHeight && rect.width === contentWidth &&
|
if (rect.height === contentHeight && rect.width === contentWidth &&
|
||||||
!gotInitialFullSizeFrame) {
|
!gotInitialFullSizeFrame) {
|
||||||
// The initial frame is full-size, but we're looking for a call
|
// 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
|
// with just the dirty-rect. The next frame should be a smaller
|
||||||
// rect.
|
// rect.
|
||||||
|
|
Loading…
Reference in a new issue