Skip to content

Commit

Permalink
chore: tsify browser-window (#24326)
Browse files Browse the repository at this point in the history
* chore: tsify browser-window

* fix focus

* also tsify top-level-window
  • Loading branch information
nornagon committed Jun 29, 2020
1 parent 1c49e4e commit 80e5007
Show file tree
Hide file tree
Showing 8 changed files with 227 additions and 194 deletions.
2 changes: 1 addition & 1 deletion docs/api/browser-window.md
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,7 @@ Returns `BrowserWindow | null` - The window that owns the given `browserView`. I

* `id` Integer

Returns `BrowserWindow` - The window with the given `id`.
Returns `BrowserWindow | null` - The window with the given `id`.

#### `BrowserWindow.addExtension(path)` _Deprecated_

Expand Down
4 changes: 2 additions & 2 deletions filenames.auto.gni
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ auto_filenames = {
"lib/browser/api/auto-updater/auto-updater-win.js",
"lib/browser/api/auto-updater/squirrel-update-win.js",
"lib/browser/api/browser-view.ts",
"lib/browser/api/browser-window.js",
"lib/browser/api/browser-window.ts",
"lib/browser/api/content-tracing.ts",
"lib/browser/api/crash-reporter.ts",
"lib/browser/api/desktop-capturer.ts",
Expand All @@ -216,7 +216,7 @@ auto_filenames = {
"lib/browser/api/screen.ts",
"lib/browser/api/session.ts",
"lib/browser/api/system-preferences.ts",
"lib/browser/api/top-level-window.js",
"lib/browser/api/top-level-window.ts",
"lib/browser/api/touch-bar.js",
"lib/browser/api/tray.ts",
"lib/browser/api/view.ts",
Expand Down
168 changes: 0 additions & 168 deletions lib/browser/api/browser-window.js

This file was deleted.

182 changes: 182 additions & 0 deletions lib/browser/api/browser-window.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import { TopLevelWindow, WebContents, Event, BrowserView, TouchBar } from 'electron';
import type { BrowserWindow as BWT } from 'electron';
const { BrowserWindow } = process._linkedBinding('electron_browser_window') as { BrowserWindow: typeof BWT };

Object.setPrototypeOf(BrowserWindow.prototype, TopLevelWindow.prototype);

(BrowserWindow.prototype as any)._init = function (this: BWT) {
// Call parent class's _init.
(TopLevelWindow.prototype as any)._init.call(this);

// Avoid recursive require.
const { app } = require('electron');

const nativeSetBounds = this.setBounds;
this.setBounds = (bounds, ...opts) => {
bounds = {
...this.getBounds(),
...bounds
};
nativeSetBounds.call(this, bounds, ...opts);
};

// Sometimes the webContents doesn't get focus when window is shown, so we
// have to force focusing on webContents in this case. The safest way is to
// focus it when we first start to load URL, if we do it earlier it won't
// have effect, if we do it later we might move focus in the page.
//
// Though this hack is only needed on macOS when the app is launched from
// Finder, we still do it on all platforms in case of other bugs we don't
// know.
this.webContents.once('load-url' as any, function (this: WebContents) {
this.focus();
});

// Redirect focus/blur event to app instance too.
this.on('blur', (event: Event) => {
app.emit('browser-window-blur', event, this);
});
this.on('focus', (event: Event) => {
app.emit('browser-window-focus', event, this);
});

// Subscribe to visibilityState changes and pass to renderer process.
let isVisible = this.isVisible() && !this.isMinimized();
const visibilityChanged = () => {
const newState = this.isVisible() && !this.isMinimized();
if (isVisible !== newState) {
isVisible = newState;
const visibilityState = isVisible ? 'visible' : 'hidden';
this.webContents.emit('-window-visibility-change', visibilityState);
}
};

const visibilityEvents = ['show', 'hide', 'minimize', 'maximize', 'restore'];
for (const event of visibilityEvents) {
this.on(event as any, visibilityChanged);
}

// Notify the creation of the window.
const event = process._linkedBinding('electron_browser_event').createEmpty();
app.emit('browser-window-created', event, this);

Object.defineProperty(this, 'devToolsWebContents', {
enumerable: true,
configurable: false,
get () {
return this.webContents.devToolsWebContents;
}
});
};

const isBrowserWindow = (win: any) => {
return win && win.constructor.name === 'BrowserWindow';
};

BrowserWindow.fromId = (id: number) => {
const win = TopLevelWindow.fromId(id);
return isBrowserWindow(win) ? win as any as BWT : null;
};

BrowserWindow.getAllWindows = () => {
return TopLevelWindow.getAllWindows().filter(isBrowserWindow) as any[] as BWT[];
};

BrowserWindow.getFocusedWindow = () => {
for (const window of BrowserWindow.getAllWindows()) {
if (window.isFocused() || window.isDevToolsFocused()) return window;
}
return null;
};

BrowserWindow.fromWebContents = (webContents: WebContents) => {
for (const window of BrowserWindow.getAllWindows()) {
if (window.webContents && window.webContents.equal(webContents)) return window;
}

return null;
};

BrowserWindow.fromBrowserView = (browserView: BrowserView) => {
for (const window of BrowserWindow.getAllWindows()) {
if (window.getBrowserView() === browserView) return window;
}

return null;
};

BrowserWindow.prototype.setTouchBar = function (touchBar) {
(TouchBar as any)._setOnWindow(touchBar, this);
};

// Forwarded to webContents:

BrowserWindow.prototype.loadURL = function (...args) {
return this.webContents.loadURL(...args);
};

BrowserWindow.prototype.getURL = function () {
return this.webContents.getURL();
};

BrowserWindow.prototype.loadFile = function (...args) {
return this.webContents.loadFile(...args);
};

BrowserWindow.prototype.reload = function (...args) {
return this.webContents.reload(...args);
};

BrowserWindow.prototype.send = function (...args) {
return this.webContents.send(...args);
};

BrowserWindow.prototype.openDevTools = function (...args) {
return this.webContents.openDevTools(...args);
};

BrowserWindow.prototype.closeDevTools = function () {
return this.webContents.closeDevTools();
};

BrowserWindow.prototype.isDevToolsOpened = function () {
return this.webContents.isDevToolsOpened();
};

BrowserWindow.prototype.isDevToolsFocused = function () {
return this.webContents.isDevToolsFocused();
};

BrowserWindow.prototype.toggleDevTools = function () {
return this.webContents.toggleDevTools();
};

BrowserWindow.prototype.inspectElement = function (...args) {
return this.webContents.inspectElement(...args);
};

BrowserWindow.prototype.inspectSharedWorker = function () {
return this.webContents.inspectSharedWorker();
};

BrowserWindow.prototype.inspectServiceWorker = function () {
return this.webContents.inspectServiceWorker();
};

BrowserWindow.prototype.showDefinitionForSelection = function () {
return this.webContents.showDefinitionForSelection();
};

BrowserWindow.prototype.capturePage = function (...args) {
return this.webContents.capturePage(...args);
};

BrowserWindow.prototype.getBackgroundThrottling = function () {
return this.webContents.getBackgroundThrottling();
};

BrowserWindow.prototype.setBackgroundThrottling = function (allowed: boolean) {
return this.webContents.setBackgroundThrottling(allowed);
};

module.exports = BrowserWindow;
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
'use strict';

const electron = require('electron');
const { EventEmitter } = require('events');
const { TopLevelWindow } = process._linkedBinding('electron_browser_top_level_window');
import { EventEmitter } from 'events';
import type { TopLevelWindow as TLWT } from 'electron';
const { TopLevelWindow } = process._linkedBinding('electron_browser_top_level_window') as { TopLevelWindow: typeof TLWT };

Object.setPrototypeOf(TopLevelWindow.prototype, EventEmitter.prototype);

TopLevelWindow.prototype._init = function () {
(TopLevelWindow.prototype as any)._init = function () {
// Avoid recursive require.
const { app } = electron;
const { app } = require('electron');

// Simulate the application menu on platforms other than macOS.
if (process.platform !== 'darwin') {
Expand Down

0 comments on commit 80e5007

Please sign in to comment.