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

feat: add BrowserWindow.isFocusable() #28642

Merged
merged 1 commit into from Apr 21, 2021
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: 8 additions & 0 deletions docs/api/browser-window.md
Expand Up @@ -758,6 +758,10 @@ A `Boolean` property that determines whether the window is in simple (pre-Lion)

A `Boolean` property that determines whether the window is in fullscreen mode.

#### `win.focusable` _Windows_ _macOS_

A `Boolean` property that determines whether the window is focusable.

#### `win.visibleOnAllWorkspaces`

A `Boolean` property that determines whether the window is visible on all workspaces.
Expand Down Expand Up @@ -1676,6 +1680,10 @@ Changes whether the window can be focused.

On macOS it does not remove the focus from the window.

#### `win.isFocusable()` _macOS_ _Windows_

Returns whether the window can be focused.

#### `win.setParentWindow(parent)`

* `parent` BrowserWindow | null
Expand Down
5 changes: 5 additions & 0 deletions lib/browser/api/base-window.ts
Expand Up @@ -37,6 +37,11 @@ Object.defineProperty(BaseWindow.prototype, 'simpleFullScreen', {
set: function (simple) { this.setSimpleFullScreen(simple); }
});

Object.defineProperty(BaseWindow.prototype, 'focusable', {
get: function () { return this.isFocusable(); },
set: function (focusable) { this.setFocusable(focusable); }
});

Object.defineProperty(BaseWindow.prototype, 'kiosk', {
get: function () { return this.isKiosk(); },
set: function (kiosk) { this.setKiosk(kiosk); }
Expand Down
5 changes: 5 additions & 0 deletions shell/browser/api/electron_api_base_window.cc
Expand Up @@ -696,6 +696,10 @@ void BaseWindow::SetFocusable(bool focusable) {
return window_->SetFocusable(focusable);
}

bool BaseWindow::IsFocusable() {
return window_->IsFocusable();
}

void BaseWindow::SetMenu(v8::Isolate* isolate, v8::Local<v8::Value> value) {
auto context = isolate->GetCurrentContext();
gin::Handle<Menu> menu;
Expand Down Expand Up @@ -1243,6 +1247,7 @@ void BaseWindow::BuildPrototype(v8::Isolate* isolate,
.SetMethod("setIgnoreMouseEvents", &BaseWindow::SetIgnoreMouseEvents)
.SetMethod("setContentProtection", &BaseWindow::SetContentProtection)
.SetMethod("setFocusable", &BaseWindow::SetFocusable)
.SetMethod("isFocusable", &BaseWindow::IsFocusable)
.SetMethod("setMenu", &BaseWindow::SetMenu)
.SetMethod("removeMenu", &BaseWindow::RemoveMenu)
.SetMethod("setParentWindow", &BaseWindow::SetParentWindow)
Expand Down
1 change: 1 addition & 0 deletions shell/browser/api/electron_api_base_window.h
Expand Up @@ -171,6 +171,7 @@ class BaseWindow : public gin_helper::TrackableObject<BaseWindow>,
void SetIgnoreMouseEvents(bool ignore, gin_helper::Arguments* args);
void SetContentProtection(bool enable);
void SetFocusable(bool focusable);
bool IsFocusable();
void SetMenu(v8::Isolate* isolate, v8::Local<v8::Value> menu);
void RemoveMenu();
void SetParentWindow(v8::Local<v8::Value> value, gin_helper::Arguments* args);
Expand Down
4 changes: 4 additions & 0 deletions shell/browser/native_window.cc
Expand Up @@ -328,6 +328,10 @@ bool NativeWindow::IsDocumentEdited() {

void NativeWindow::SetFocusable(bool focusable) {}

bool NativeWindow::IsFocusable() {
return false;
}

void NativeWindow::SetMenu(ElectronMenuModel* menu) {}

void NativeWindow::SetParentWindow(NativeWindow* parent) {
Expand Down
1 change: 1 addition & 0 deletions shell/browser/native_window.h
Expand Up @@ -162,6 +162,7 @@ class NativeWindow : public base::SupportsUserData,
virtual void SetIgnoreMouseEvents(bool ignore, bool forward) = 0;
virtual void SetContentProtection(bool enable) = 0;
virtual void SetFocusable(bool focusable);
virtual bool IsFocusable();
virtual void SetMenu(ElectronMenuModel* menu);
virtual void SetParentWindow(NativeWindow* parent);
virtual void AddBrowserView(NativeBrowserView* browser_view) = 0;
Expand Down
1 change: 1 addition & 0 deletions shell/browser/native_window_mac.h
Expand Up @@ -104,6 +104,7 @@ class NativeWindowMac : public NativeWindow,
void SetIgnoreMouseEvents(bool ignore, bool forward) override;
void SetContentProtection(bool enable) override;
void SetFocusable(bool focusable) override;
bool IsFocusable() override;
void AddBrowserView(NativeBrowserView* browser_view) override;
void RemoveBrowserView(NativeBrowserView* browser_view) override;
void SetTopBrowserView(NativeBrowserView* browser_view) override;
Expand Down
4 changes: 4 additions & 0 deletions shell/browser/native_window_mac.mm
Expand Up @@ -1072,6 +1072,10 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
[window_ setDisableKeyOrMainWindow:!focusable];
}

bool NativeWindowMac::IsFocusable() {
return ![window_ disableKeyOrMainWindow];
}

void NativeWindowMac::AddBrowserView(NativeBrowserView* view) {
[CATransaction begin];
[CATransaction setDisableActions:YES];
Expand Down
11 changes: 11 additions & 0 deletions shell/browser/native_window_views.cc
Expand Up @@ -1083,6 +1083,17 @@ void NativeWindowViews::SetFocusable(bool focusable) {
#endif
}

bool NativeWindowViews::IsFocusable() {
bool can_activate = widget()->widget_delegate()->CanActivate();
#if defined(OS_WIN)
LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE);
bool no_activate = ex_style & WS_EX_NOACTIVATE;
return !no_activate && can_activate;
#else
return can_activate;
#endif
}

void NativeWindowViews::SetMenu(ElectronMenuModel* menu_model) {
#if defined(USE_X11)
if (!features::IsUsingOzonePlatform()) {
Expand Down
1 change: 1 addition & 0 deletions shell/browser/native_window_views.h
Expand Up @@ -112,6 +112,7 @@ class NativeWindowViews : public NativeWindow,
void SetIgnoreMouseEvents(bool ignore, bool forward) override;
void SetContentProtection(bool enable) override;
void SetFocusable(bool focusable) override;
bool IsFocusable() override;
void SetMenu(ElectronMenuModel* menu_model) override;
void AddBrowserView(NativeBrowserView* browser_view) override;
void RemoveBrowserView(NativeBrowserView* browser_view) override;
Expand Down
11 changes: 11 additions & 0 deletions spec-main/api-browser-window-spec.ts
Expand Up @@ -838,6 +838,17 @@ describe('BrowserWindow module', () => {
await closeWindow(w2, { assertNotWindows: false });
});
});

describe('BrowserWindow.isFocusable()', () => {
it('correctly returns whether a window is focusable', async () => {
const w2 = new BrowserWindow({ focusable: false });
expect(w2.isFocusable()).to.be.false();

w2.setFocusable(true);
expect(w2.isFocusable()).to.be.true();
await closeWindow(w2, { assertNotWindows: false });
});
});
});

describe('sizing', () => {
Expand Down