Skip to content

Commit

Permalink
fix: child window alwaysOnTop level persistence (#29957)
Browse files Browse the repository at this point in the history
  • Loading branch information
codebytere committed Jul 1, 2021
1 parent bb149b0 commit 574bd21
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 6 deletions.
5 changes: 5 additions & 0 deletions shell/browser/api/electron_api_base_window.cc
Expand Up @@ -864,6 +864,10 @@ void BaseWindow::SetVibrancy(v8::Isolate* isolate, v8::Local<v8::Value> value) {
}

#if defined(OS_MAC)
std::string BaseWindow::GetAlwaysOnTopLevel() {
return window_->GetAlwaysOnTopLevel();
}

void BaseWindow::SetTrafficLightPosition(const gfx::Point& position) {
window_->SetTrafficLightPosition(position);
}
Expand Down Expand Up @@ -1244,6 +1248,7 @@ void BaseWindow::BuildPrototype(v8::Isolate* isolate,
.SetMethod("isVisibleOnAllWorkspaces",
&BaseWindow::IsVisibleOnAllWorkspaces)
#if defined(OS_MAC)
.SetMethod("_getAlwaysOnTopLevel", &BaseWindow::GetAlwaysOnTopLevel)
.SetMethod("setAutoHideCursor", &BaseWindow::SetAutoHideCursor)
#endif
.SetMethod("setVibrancy", &BaseWindow::SetVibrancy)
Expand Down
1 change: 1 addition & 0 deletions shell/browser/api/electron_api_base_window.h
Expand Up @@ -191,6 +191,7 @@ class BaseWindow : public gin_helper::TrackableObject<BaseWindow>,
virtual void SetVibrancy(v8::Isolate* isolate, v8::Local<v8::Value> value);

#if defined(OS_MAC)
std::string GetAlwaysOnTopLevel();
void SetTrafficLightPosition(const gfx::Point& position);
gfx::Point GetTrafficLightPosition() const;
#endif
Expand Down
1 change: 1 addition & 0 deletions shell/browser/native_window.h
Expand Up @@ -203,6 +203,7 @@ class NativeWindow : public base::SupportsUserData,

// Traffic Light API
#if defined(OS_MAC)
virtual std::string GetAlwaysOnTopLevel() = 0;
virtual void SetTrafficLightPosition(const gfx::Point& position) = 0;
virtual gfx::Point GetTrafficLightPosition() const = 0;
virtual void RedrawTrafficLights() = 0;
Expand Down
1 change: 1 addition & 0 deletions shell/browser/native_window_mac.h
Expand Up @@ -89,6 +89,7 @@ class NativeWindowMac : public NativeWindow,
void SetAlwaysOnTop(ui::ZOrderLevel z_order,
const std::string& level,
int relativeLevel) override;
std::string GetAlwaysOnTopLevel() override;
ui::ZOrderLevel GetZOrderLevel() override;
void Center() override;
void Invalidate() override;
Expand Down
32 changes: 31 additions & 1 deletion shell/browser/native_window_mac.mm
Expand Up @@ -1055,6 +1055,31 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
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) {
int level = std::min(
std::max(unbounded_level, CGWindowLevelForKey(kCGMinimumWindowLevelKey)),
Expand Down Expand Up @@ -1854,10 +1879,15 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {

// Set new parent window.
// 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()
addChildWindow:window_
ordered:NSWindowAbove];
[window_ setLevel:level];
}
}

void NativeWindowMac::SetForwardMouseMessages(bool forward) {
Expand Down
17 changes: 12 additions & 5 deletions spec-main/api-browser-window-spec.ts
Expand Up @@ -1418,15 +1418,12 @@ describe('BrowserWindow module', () => {
describe('BrowserWindow.setAlwaysOnTop(flag, level)', () => {
let w = null as unknown as BrowserWindow;

afterEach(closeAllWindows);

beforeEach(() => {
w = new BrowserWindow({ show: true });
});

afterEach(async () => {
await closeWindow(w);
w = null as unknown as BrowserWindow;
});

it('sets the window as always on top', () => {
expect(w.isAlwaysOnTop()).to.be.false('is alwaysOnTop');
w.setAlwaysOnTop(true, 'screen-saver');
Expand Down Expand Up @@ -1454,6 +1451,16 @@ describe('BrowserWindow module', () => {
const [, alwaysOnTop] = await alwaysOnTopChanged;
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', () => {
Expand Down

0 comments on commit 574bd21

Please sign in to comment.