Fixed 1040

This commit is contained in:
Florian Rappl
2026-09-04 11:37:42 +02:00
parent da0e1f17db
commit 7af2e954c7
6 changed files with 121 additions and 61 deletions

View File

@@ -3,6 +3,7 @@
## ElectronNET.Core
- Updated dependencies
- Fixed single instance handling on macOS (#1040)
- Fixed socket bridge connection when a system proxy is configured (#1105)
- Fixed electron-builder using the host RID instead of the target RID (#1097)
- Fixed cross-compilation behavior on same platform (#1098) @epsnm

View File

@@ -157,10 +157,19 @@ namespace ElectronNET.API
}
BridgeConnector.Socket.On<int[]>("BrowserWindowClosed", HandleBrowserWindowClosed);
BridgeConnector.Socket.On<int>("BrowserWindowRecreated", HandleBrowserWindowRecreated);
_browserWindowClosedSubscribed = true;
}
}
private void HandleBrowserWindowRecreated(int id)
{
if (_browserWindows.All(window => window.Id != id))
{
_browserWindows.Add(new BrowserWindow(id));
}
}
private void HandleBrowserWindowClosed(int[] ids)
{
if (ids == null || ids.Length == 0)

View File

@@ -39,7 +39,6 @@ const windows = (global["browserWindows"] =
global["browserWindows"] || []);
let readyToShowWindowsIds = [];
let window;
let lastOptions;
let electronSocket;
const proxyToCredentialsMap = (global["proxyToCredentialsMap"] = global["proxyToCredentialsMap"] || []);
module.exports = (socket, app) => {
@@ -203,6 +202,18 @@ module.exports = (socket, app) => {
});
});
socket.on("createBrowserWindow", (options, loadUrl) => {
createWindow(options, loadUrl, "BrowserWindowCreated");
});
// Allows the host (main.js) to bring the main window back when the app is activated
// again on macOS after all windows have been closed.
global["recreateMainWindow"] = () => {
if (electron_1.BrowserWindow.getAllWindows().length > 0 || !app["mainWindowOptions"]) {
return false;
}
createWindow(app["mainWindowOptions"], app["mainWindowURL"], "BrowserWindowRecreated");
return true;
};
function createWindow(options, loadUrl, createdEventName) {
if (options.webPreferences &&
!("nodeIntegration" in options.webPreferences)) {
options = {
@@ -226,21 +237,19 @@ module.exports = (socket, app) => {
delete options.isRunningBlazor;
// we dont want to recreate the window when watch is ready.
if (app.commandLine.hasSwitch("watch") &&
app["mainWindowURL"] === loadUrl) {
app["mainWindowURL"] === loadUrl &&
app["mainWindow"] &&
!app["mainWindow"].isDestroyed()) {
window = app["mainWindow"];
if (window) {
window.reload();
synchronizeWindowRegistry();
if (!windows.some((entry) => tryGetWindowId(entry) === window.id)) {
windows.push(window);
}
electronSocket.emit("BrowserWindowCreated", window.id);
return;
window.reload();
synchronizeWindowRegistry();
if (!windows.some((entry) => tryGetWindowId(entry) === window.id)) {
windows.push(window);
}
electronSocket.emit(createdEventName, window.id);
return;
}
else {
window = new electron_1.BrowserWindow(options);
}
window = new electron_1.BrowserWindow(options);
if (options.proxy) {
window.webContents.session.setProxy({ proxyRules: options.proxy });
}
@@ -255,18 +264,10 @@ module.exports = (socket, app) => {
readyToShowWindowsIds.push(window.id);
}
});
lastOptions = options;
window.on("closed", () => {
synchronizeWindowRegistry();
emitBrowserWindowClosed();
});
app.on("activate", () => {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (window === null && lastOptions) {
window = new electron_1.BrowserWindow(lastOptions);
}
});
if (loadUrl) {
// Append authentication token to initial URL if available
const token = global["authToken"];
@@ -299,10 +300,14 @@ module.exports = (socket, app) => {
if (app["mainWindowURL"] == undefined || app["mainWindowURL"] == "") {
app["mainWindowURL"] = loadUrl;
app["mainWindow"] = window;
app["mainWindowOptions"] = options;
}
else if (app["mainWindowURL"] === loadUrl) {
app["mainWindow"] = window;
}
windows.push(window);
electronSocket.emit("BrowserWindowCreated", window.id);
});
electronSocket.emit(createdEventName, window.id);
}
socket.on("browserWindowDestroy", (id) => {
getWindowById(id).destroy();
});

File diff suppressed because one or more lines are too long

View File

@@ -10,7 +10,6 @@ const windows: Electron.BrowserWindow[] = (global["browserWindows"] =
let readyToShowWindowsIds: number[] = [];
let window;
let lastOptions;
let electronSocket;
const proxyToCredentialsMap: { [proxy: string]: string } = (global[
@@ -217,6 +216,26 @@ export = (socket: Socket, app: Electron.App) => {
});
socket.on("createBrowserWindow", (options, loadUrl) => {
createWindow(options, loadUrl, "BrowserWindowCreated");
});
// Allows the host (main.js) to bring the main window back when the app is activated
// again on macOS after all windows have been closed.
global["recreateMainWindow"] = () => {
if (BrowserWindow.getAllWindows().length > 0 || !app["mainWindowOptions"]) {
return false;
}
createWindow(
app["mainWindowOptions"],
app["mainWindowURL"],
"BrowserWindowRecreated",
);
return true;
};
function createWindow(options, loadUrl, createdEventName: string) {
if (
options.webPreferences &&
!("nodeIntegration" in options.webPreferences)
@@ -250,22 +269,24 @@ export = (socket: Socket, app: Electron.App) => {
// we dont want to recreate the window when watch is ready.
if (
app.commandLine.hasSwitch("watch") &&
app["mainWindowURL"] === loadUrl
app["mainWindowURL"] === loadUrl &&
app["mainWindow"] &&
!app["mainWindow"].isDestroyed()
) {
window = app["mainWindow"];
if (window) {
window.reload();
synchronizeWindowRegistry();
if (!windows.some((entry) => tryGetWindowId(entry) === window.id)) {
windows.push(window);
}
electronSocket.emit("BrowserWindowCreated", window.id);
return;
window.reload();
synchronizeWindowRegistry();
if (!windows.some((entry) => tryGetWindowId(entry) === window.id)) {
windows.push(window);
}
} else {
window = new BrowserWindow(options);
electronSocket.emit(createdEventName, window.id);
return;
}
window = new BrowserWindow(options);
if (options.proxy) {
window.webContents.session.setProxy({ proxyRules: options.proxy });
}
@@ -284,21 +305,11 @@ export = (socket: Socket, app: Electron.App) => {
}
});
lastOptions = options;
window.on("closed", () => {
synchronizeWindowRegistry();
emitBrowserWindowClosed();
});
app.on("activate", () => {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (window === null && lastOptions) {
window = new BrowserWindow(lastOptions);
}
});
if (loadUrl) {
// Append authentication token to initial URL if available
const token = global["authToken"];
@@ -338,11 +349,14 @@ export = (socket: Socket, app: Electron.App) => {
if (app["mainWindowURL"] == undefined || app["mainWindowURL"] == "") {
app["mainWindowURL"] = loadUrl;
app["mainWindow"] = window;
app["mainWindowOptions"] = options;
} else if (app["mainWindowURL"] === loadUrl) {
app["mainWindow"] = window;
}
windows.push(window);
electronSocket.emit("BrowserWindowCreated", window.id);
});
electronSocket.emit(createdEventName, window.id);
}
socket.on("browserWindowDestroy", (id) => {
getWindowById(id).destroy();

View File

@@ -103,9 +103,44 @@ app.on('will-finish-launching', () => {
const manifestJsonFile = require(manifestJsonFilePath);
// Brings the app back to the foreground: focuses an already existing window or - if
// all windows have been closed (which keeps the app alive on macOS) - recreates the
// main window.
function activateApp() {
const windows = BrowserWindow.getAllWindows().filter((window) => !window.isDestroyed());
if (!windows.length) {
return typeof global.recreateMainWindow === 'function' && global.recreateMainWindow();
}
const target = windows.find((window) => window.isVisible()) || windows[0];
if (target.isMinimized()) {
target.restore();
}
if (!target.isVisible()) {
target.show();
}
target.focus();
if (platform() === 'darwin') {
// On macOS focusing a window does not necessarily bring the app itself to the front
app.focus({ steal: true });
}
return true;
}
if (manifestJsonFile.singleInstance) {
const mainInstance = app.requestSingleInstanceLock();
app.on('second-instance', (events, args = []) => {
if (!app.requestSingleInstanceLock()) {
// Another instance already owns the lock. Exit right away so that neither the
// socket bridge nor the .NET backend process of this instance is started.
app.exit(0);
}
app.on('second-instance', (event, args = []) => {
args.forEach((parameter) => {
const words = parameter.split('=');
@@ -116,20 +151,16 @@ if (manifestJsonFile.singleInstance) {
}
});
const windows = BrowserWindow.getAllWindows();
if (windows.length) {
if (windows[0].isMinimized()) {
windows[0].restore();
}
windows[0].focus();
}
activateApp();
});
if (!mainInstance) {
app.quit();
}
}
// On macOS launching an already running app (or clicking its dock icon) does not
// start a second instance - the 'activate' event is raised instead.
app.on('activate', () => {
activateApp();
});
// Collect user supplied command line args (excluding those handled by Electron host itself)
function getForwardedArgs() {
const skipSwitches = new Set(['unpackedelectron', 'unpackeddotnet', 'dotnetpacked']);