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

Migrate from BrowserView to WebContentsView #2542

Merged
merged 5 commits into from
Jan 4, 2025
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions js/tabState/tab.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class TabList {

//tab properties that shouldn't be saved to disk

static temporaryProperties = ['hasAudio', 'previewImage', 'loaded', 'hasBrowserView']
static temporaryProperties = ['hasAudio', 'previewImage', 'loaded', 'hasWebContents']

add (tab = {}, options = {}, emit=true) {
var tabId = String(tab.id || Math.round(Math.random() * 100000000000000000)) // you can pass an id that will be used, or a random one will be generated.
Expand All @@ -28,7 +28,7 @@ class TabList {
hasAudio: false,
previewImage: '',
isFileView: false,
hasBrowserView: false,
hasWebContents: false,
}

if (options.atEnd) {
Expand Down
6 changes: 3 additions & 3 deletions js/util/settings/settingsMain.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ var settings = {
settings.runChangeCallbacks(key)

windows.getAll().forEach(function (win) {
win.webContents.send('settingChanged', key, value)
getWindowWebContents(win).send('settingChanged', key, value)
})
},
initialize: function (userDataPath) {
Expand All @@ -86,8 +86,8 @@ var settings = {
settings.runChangeCallbacks(key)

windows.getAll().forEach(function (win) {
if (win.webContents.id !== e.sender.id) {
win.webContents.send('settingChanged', key, value)
if (getWindowWebContents(win).id !== e.sender.id) {
getWindowWebContents(win).send('settingChanged', key, value)
}
})
})
Expand Down
6 changes: 3 additions & 3 deletions js/webviews.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ const webviews = {
events: [],
IPCEvents: [],
hasViewForTab: function(tabId) {
return tabId && tasks.getTaskContainingTab(tabId) && tasks.getTaskContainingTab(tabId).tabs.get(tabId).hasBrowserView
return tabId && tasks.getTaskContainingTab(tabId) && tasks.getTaskContainingTab(tabId).tabs.get(tabId).hasWebContents
},
bindEvent: function (event, fn) {
webviews.events.push({
Expand Down Expand Up @@ -214,7 +214,7 @@ const webviews = {
}

tasks.getTaskContainingTab(tabId).tabs.update(tabId, {
hasBrowserView: true
hasWebContents: true
})
},
setSelected: function (id, options) { // options.focus - whether to focus the view. Defaults to true.
Expand Down Expand Up @@ -248,7 +248,7 @@ const webviews = {

if (webviews.hasViewForTab(id)) {
tasks.getTaskContainingTab(id).tabs.update(id, {
hasBrowserView: false
hasWebContents: false
})
}
//we may be destroying a view for which the tab object no longer exists, so this message should be sent unconditionally
Expand Down
11 changes: 2 additions & 9 deletions main/download.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@ function isAttachment (header) {
}

function downloadHandler (event, item, webContents) {
const sourceView = Object.values(viewMap).find(view => view.webContents.id === webContents.id)
let sourceWindow
if (sourceView) {
sourceWindow = BrowserWindow.fromBrowserView(sourceView)
}
let sourceWindow = windows.windowFromContents(webContents)?.win
if (!sourceWindow) {
sourceWindow = windows.getCurrent()
}
Expand Down Expand Up @@ -64,10 +60,7 @@ function listenForDownloadHeaders (ses) {
if (details.resourceType === 'mainFrame' && details.responseHeaders) {
let sourceWindow
if (details.webContents) {
const sourceView = Object.values(viewMap).find(view => view.webContents.id === details.webContents.id)
if (sourceView) {
sourceWindow = BrowserWindow.fromBrowserView(sourceView)
}
sourceWindow = windows.windowFromContents(details.webContents)?.win
}
if (!sourceWindow) {
sourceWindow = windows.getCurrent()
Expand Down
80 changes: 49 additions & 31 deletions main/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ const path = require('path')
const {
app, // Module to control application life.
protocol, // Module to control protocol handling
BrowserWindow, // Module to create native browser window.
BaseWindow, // Module to create native browser window.
BrowserWindow,
webContents,
session,
ipcMain: ipc,
Expand All @@ -14,7 +15,8 @@ const {
dialog,
nativeTheme,
shell,
net
net,
WebContentsView
} = electron

crashReporter.start({
Expand Down Expand Up @@ -98,24 +100,24 @@ function sendIPCToWindow (window, action, data) {
return
}

if (window && window.webContents && window.webContents.isLoadingMainFrame()) {
if (window && getWindowWebContents(window).isLoadingMainFrame()) {
// immediately after a did-finish-load event, isLoading can still be true,
// so wait a bit to confirm that the page is really loading
setTimeout(function() {
if (window.webContents.isLoadingMainFrame()) {
window.webContents.once('did-finish-load', function () {
window.webContents.send(action, data || {})
if (getWindowWebContents(window).isLoadingMainFrame()) {
getWindowWebContents(window).once('did-finish-load', function () {
getWindowWebContents(window).send(action, data || {})
})
} else {
window.webContents.send(action, data || {})
getWindowWebContents(window).send(action, data || {})
}
}, 0)
} else if (window) {
window.webContents.send(action, data || {})
getWindowWebContents(window).send(action, data || {})
} else {
var window = createWindow()
window.webContents.once('did-finish-load', function () {
window.webContents.send(action, data || {})
getWindowWebContents(window).once('did-finish-load', function () {
getWindowWebContents(window).send(action, data || {})
})
}
}
Expand Down Expand Up @@ -188,7 +190,7 @@ function createWindow (customArgs = {}) {
}

function createWindowWithBounds (bounds, customArgs) {
const newWin = new BrowserWindow({
const newWin = new BaseWindow({
width: bounds.width,
height: bounds.height,
x: bounds.x,
Expand All @@ -201,6 +203,15 @@ function createWindowWithBounds (bounds, customArgs) {
frame: settings.get('useSeparateTitlebar'),
alwaysOnTop: settings.get('windowAlwaysOnTop'),
backgroundColor: '#fff', // the value of this is ignored, but setting it seems to work around https://github.com/electron/electron/issues/10559
})

// windows and linux always use a menu button in the upper-left corner instead
// if frame: false is set, this won't have any effect, but it does apply on Linux if "use separate titlebar" is enabled
if (process.platform !== 'darwin') {
newWin.setMenuBarVisibility(false)
}

const mainView = new WebContentsView({
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
Expand All @@ -217,20 +228,19 @@ function createWindowWithBounds (bounds, customArgs) {
]
}
})
mainView.webContents.loadURL(browserPage)
mainView.setBounds({x: 0, y: 0, width: bounds.width, height: bounds.height})
newWin.contentView.addChildView(mainView)

// windows and linux always use a menu button in the upper-left corner instead
// if frame: false is set, this won't have any effect, but it does apply on Linux if "use separate titlebar" is enabled
if (process.platform !== 'darwin') {
newWin.setMenuBarVisibility(false)
}

// and load the index.html of the app.
newWin.loadURL(browserPage)
newWin.on('resize', function() {
const winBounds = newWin.getBounds()
mainView.setBounds({x: 0, y: 0, width: winBounds.width, height: winBounds.height})
})

if (bounds.maximized) {
newWin.maximize()

newWin.webContents.once('did-finish-load', function () {
mainView.webContents.once('did-finish-load', function () {
sendIPCToWindow(newWin, 'maximize')
})
}
Expand Down Expand Up @@ -269,7 +279,7 @@ function createWindowWithBounds (bounds, customArgs) {

newWin.on('blur', function () {
// if the devtools for this window are focused, this check will be false, and we keep the focused class on the window
if (BrowserWindow.getFocusedWindow() !== newWin) {
if (BaseWindow.getFocusedWindow() !== newWin) {
sendIPCToWindow(newWin, 'blur')
}
})
Expand Down Expand Up @@ -311,7 +321,7 @@ function createWindowWithBounds (bounds, customArgs) {
}

// prevent remote pages from being loaded using drag-and-drop, since they would have node access
newWin.webContents.on('will-navigate', function (e, url) {
mainView.webContents.on('will-navigate', function (e, url) {
if (url !== browserPage) {
e.preventDefault()
}
Expand Down Expand Up @@ -340,7 +350,7 @@ app.on('ready', function () {

const newWin = createWindow()

newWin.webContents.on('did-finish-load', function () {
getWindowWebContents(newWin).on('did-finish-load', function () {
// if a URL was passed as a command line argument (probably because Min is set as the default browser on Linux), open it.
handleCommandLineArguments(process.argv)

Expand Down Expand Up @@ -403,8 +413,7 @@ app.on('activate', function (/* e, hasVisibleWindows */) {
})

ipc.on('focusMainWebContents', function () {
//TODO fix
windows.getCurrent().webContents.focus()
getWindowWebContents(windows.getCurrent()).focus()
})

ipc.on('showSecondaryMenu', function (event, data) {
Expand All @@ -430,25 +439,30 @@ ipc.on('quit', function () {
})

ipc.on('tab-state-change', function(e, events) {
const sourceWindowId = windows.windowFromContents(e.sender)?.id
if (!sourceWindowId) {
console.warn('warning: received tab state update from window after destruction, ignoring')
return
}
windows.getAll().forEach(function(window) {
if (window.webContents.id !== e.sender.id) {
window.webContents.send('tab-state-change-receive', {
sourceWindowId: windows.windowFromContents(e.sender).id,
if (getWindowWebContents(window).id !== e.sender.id) {
getWindowWebContents(window).send('tab-state-change-receive', {
sourceWindowId,
events
})
}
})
})

ipc.on('request-tab-state', function(e) {
const otherWindow = windows.getAll().find(w => w.webContents.id !== e.sender.id)
const otherWindow = windows.getAll().find(w => getWindowWebContents(w).id !== e.sender.id)
if (!otherWindow) {
throw new Error('secondary window doesn\'t exist as source for tab state')
}
ipc.once('return-tab-state', function(e2, data) {
e.returnValue = data
})
otherWindow.webContents.send('read-tab-state')
getWindowWebContents(otherWindow).send('read-tab-state')
})

/* places service */
Expand All @@ -472,4 +486,8 @@ app.once('ready', function() {

ipc.on('places-connect', function (e) {
placesWindow.webContents.postMessage('places-connect', null, e.ports)
})
})

function getWindowWebContents (win) {
return win.getContentView().children[0].webContents
}
2 changes: 1 addition & 1 deletion main/menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ function buildAppMenu (options = {}) {
if (process.platform === 'darwin') { return 'Shift+Cmd+Alt+I' } else { return 'Ctrl+Shift+Alt+I' }
})(),
click: function (item, focusedWindow) {
if (focusedWindow) focusedWindow.toggleDevTools()
if (focusedWindow) getWindowWebContents(focusedWindow).toggleDevTools()
}
},
{
Expand Down
Loading