fix: child window alwaysOnTop level persistence (#29813)
* fix: child window alwaysOnTop level * chore: add undocumented getAlwaysOnTopLevel * test: add test for level persistence * Address feedback from review
This commit is contained in:
parent
6e310b7424
commit
129f92e1fa
6 changed files with 51 additions and 6 deletions
|
@ -882,6 +882,10 @@ void BaseWindow::SetVibrancy(v8::Isolate* isolate, v8::Local<v8::Value> value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(OS_MAC)
|
#if defined(OS_MAC)
|
||||||
|
std::string BaseWindow::GetAlwaysOnTopLevel() {
|
||||||
|
return window_->GetAlwaysOnTopLevel();
|
||||||
|
}
|
||||||
|
|
||||||
void BaseWindow::SetWindowButtonVisibility(bool visible) {
|
void BaseWindow::SetWindowButtonVisibility(bool visible) {
|
||||||
window_->SetWindowButtonVisibility(visible);
|
window_->SetWindowButtonVisibility(visible);
|
||||||
}
|
}
|
||||||
|
@ -1271,6 +1275,7 @@ void BaseWindow::BuildPrototype(v8::Isolate* isolate,
|
||||||
.SetMethod("isVisibleOnAllWorkspaces",
|
.SetMethod("isVisibleOnAllWorkspaces",
|
||||||
&BaseWindow::IsVisibleOnAllWorkspaces)
|
&BaseWindow::IsVisibleOnAllWorkspaces)
|
||||||
#if defined(OS_MAC)
|
#if defined(OS_MAC)
|
||||||
|
.SetMethod("_getAlwaysOnTopLevel", &BaseWindow::GetAlwaysOnTopLevel)
|
||||||
.SetMethod("setAutoHideCursor", &BaseWindow::SetAutoHideCursor)
|
.SetMethod("setAutoHideCursor", &BaseWindow::SetAutoHideCursor)
|
||||||
#endif
|
#endif
|
||||||
.SetMethod("setVibrancy", &BaseWindow::SetVibrancy)
|
.SetMethod("setVibrancy", &BaseWindow::SetVibrancy)
|
||||||
|
|
|
@ -194,6 +194,7 @@ class BaseWindow : public gin_helper::TrackableObject<BaseWindow>,
|
||||||
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_MAC)
|
#if defined(OS_MAC)
|
||||||
|
std::string GetAlwaysOnTopLevel();
|
||||||
void SetWindowButtonVisibility(bool visible);
|
void SetWindowButtonVisibility(bool visible);
|
||||||
bool GetWindowButtonVisibility() const;
|
bool GetWindowButtonVisibility() const;
|
||||||
void SetTrafficLightPosition(const gfx::Point& position);
|
void SetTrafficLightPosition(const gfx::Point& position);
|
||||||
|
|
|
@ -135,6 +135,7 @@ class NativeWindow : public base::SupportsUserData,
|
||||||
virtual void SetTitle(const std::string& title) = 0;
|
virtual void SetTitle(const std::string& title) = 0;
|
||||||
virtual std::string GetTitle() = 0;
|
virtual std::string GetTitle() = 0;
|
||||||
#if defined(OS_MAC)
|
#if defined(OS_MAC)
|
||||||
|
virtual std::string GetAlwaysOnTopLevel() = 0;
|
||||||
virtual void SetActive(bool is_key) = 0;
|
virtual void SetActive(bool is_key) = 0;
|
||||||
virtual bool IsActive() const = 0;
|
virtual bool IsActive() const = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -78,6 +78,7 @@ class NativeWindowMac : public NativeWindow,
|
||||||
void SetAlwaysOnTop(ui::ZOrderLevel z_order,
|
void SetAlwaysOnTop(ui::ZOrderLevel z_order,
|
||||||
const std::string& level,
|
const std::string& level,
|
||||||
int relative_level) override;
|
int relative_level) override;
|
||||||
|
std::string GetAlwaysOnTopLevel() override;
|
||||||
ui::ZOrderLevel GetZOrderLevel() override;
|
ui::ZOrderLevel GetZOrderLevel() override;
|
||||||
void Center() override;
|
void Center() override;
|
||||||
void Invalidate() override;
|
void Invalidate() override;
|
||||||
|
|
|
@ -869,6 +869,31 @@ void NativeWindowMac::SetAlwaysOnTop(ui::ZOrderLevel z_order,
|
||||||
SetWindowLevel(level + relative_level);
|
SetWindowLevel(level + relative_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string NativeWindowMac::GetAlwaysOnTopLevel() {
|
||||||
|
std::string level_name = "normal";
|
||||||
|
|
||||||
|
int level = [window_ level];
|
||||||
|
if (level == NSFloatingWindowLevel) {
|
||||||
|
level_name = "floating";
|
||||||
|
} else if (level == NSTornOffMenuWindowLevel) {
|
||||||
|
level_name = "torn-off-menu";
|
||||||
|
} else if (level == NSModalPanelWindowLevel) {
|
||||||
|
level_name = "modal-panel";
|
||||||
|
} else if (level == NSMainMenuWindowLevel) {
|
||||||
|
level_name = "main-menu";
|
||||||
|
} else if (level == NSStatusWindowLevel) {
|
||||||
|
level_name = "status";
|
||||||
|
} else if (level == NSPopUpMenuWindowLevel) {
|
||||||
|
level_name = "pop-up-menu";
|
||||||
|
} else if (level == NSScreenSaverWindowLevel) {
|
||||||
|
level_name = "screen-saver";
|
||||||
|
} else if (level == NSDockWindowLevel) {
|
||||||
|
level_name = "dock";
|
||||||
|
}
|
||||||
|
|
||||||
|
return level_name;
|
||||||
|
}
|
||||||
|
|
||||||
void NativeWindowMac::SetWindowLevel(int unbounded_level) {
|
void NativeWindowMac::SetWindowLevel(int unbounded_level) {
|
||||||
int level = std::min(
|
int level = std::min(
|
||||||
std::max(unbounded_level, CGWindowLevelForKey(kCGMinimumWindowLevelKey)),
|
std::max(unbounded_level, CGWindowLevelForKey(kCGMinimumWindowLevelKey)),
|
||||||
|
@ -1805,10 +1830,15 @@ void NativeWindowMac::InternalSetParentWindow(NativeWindow* parent,
|
||||||
|
|
||||||
// Set new parent window.
|
// Set new parent window.
|
||||||
// Note that this method will force the window to become visible.
|
// Note that this method will force the window to become visible.
|
||||||
if (parent && attach)
|
if (parent && attach) {
|
||||||
|
// Attaching a window as a child window resets its window level, so
|
||||||
|
// save and restore it afterwards.
|
||||||
|
NSInteger level = window_.level;
|
||||||
[parent->GetNativeWindow().GetNativeNSWindow()
|
[parent->GetNativeWindow().GetNativeNSWindow()
|
||||||
addChildWindow:window_
|
addChildWindow:window_
|
||||||
ordered:NSWindowAbove];
|
ordered:NSWindowAbove];
|
||||||
|
[window_ setLevel:level];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindowMac::SetForwardMouseMessages(bool forward) {
|
void NativeWindowMac::SetForwardMouseMessages(bool forward) {
|
||||||
|
|
|
@ -1430,15 +1430,12 @@ describe('BrowserWindow module', () => {
|
||||||
describe('BrowserWindow.setAlwaysOnTop(flag, level)', () => {
|
describe('BrowserWindow.setAlwaysOnTop(flag, level)', () => {
|
||||||
let w = null as unknown as BrowserWindow;
|
let w = null as unknown as BrowserWindow;
|
||||||
|
|
||||||
|
afterEach(closeAllWindows);
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
w = new BrowserWindow({ show: true });
|
w = new BrowserWindow({ show: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(async () => {
|
|
||||||
await closeWindow(w);
|
|
||||||
w = null as unknown as BrowserWindow;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('sets the window as always on top', () => {
|
it('sets the window as always on top', () => {
|
||||||
expect(w.isAlwaysOnTop()).to.be.false('is alwaysOnTop');
|
expect(w.isAlwaysOnTop()).to.be.false('is alwaysOnTop');
|
||||||
w.setAlwaysOnTop(true, 'screen-saver');
|
w.setAlwaysOnTop(true, 'screen-saver');
|
||||||
|
@ -1466,6 +1463,16 @@ describe('BrowserWindow module', () => {
|
||||||
const [, alwaysOnTop] = await alwaysOnTopChanged;
|
const [, alwaysOnTop] = await alwaysOnTopChanged;
|
||||||
expect(alwaysOnTop).to.be.true('is not alwaysOnTop');
|
expect(alwaysOnTop).to.be.true('is not alwaysOnTop');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ifit(process.platform === 'darwin')('honors the alwaysOnTop level of a child window', () => {
|
||||||
|
w = new BrowserWindow({ show: false });
|
||||||
|
const c = new BrowserWindow({ parent: w });
|
||||||
|
c.setAlwaysOnTop(true, 'screen-saver');
|
||||||
|
|
||||||
|
expect(w.isAlwaysOnTop()).to.be.false();
|
||||||
|
expect(c.isAlwaysOnTop()).to.be.true('child is not always on top');
|
||||||
|
expect((c as any)._getAlwaysOnTopLevel()).to.equal('screen-saver');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('preconnect feature', () => {
|
describe('preconnect feature', () => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue