mirror of
https://github.com/ElectronNET/Electron.NET.git
synced 2026-09-22 15:04:47 +00:00
remove semaphore in favor of unique events per window /view create request
This commit is contained in:
@@ -40,7 +40,6 @@ namespace ElectronNET.API
|
||||
return _windowManager;
|
||||
}
|
||||
}
|
||||
private readonly SemaphoreSlim _singleCreate = new SemaphoreSlim(1, 1);
|
||||
|
||||
/// <summary>
|
||||
/// Quit when all windows are closed. (Default is true)
|
||||
@@ -96,76 +95,85 @@ namespace ElectronNET.API
|
||||
/// <returns></returns>
|
||||
public async Task<BrowserWindow> CreateWindowAsync(BrowserWindowOptions options, string loadUrl = "http://localhost")
|
||||
{
|
||||
await _singleCreate.WaitAsync();
|
||||
BootstrapUpdateOpenIDsEvent();
|
||||
|
||||
try
|
||||
var taskCompletionSource = new TaskCompletionSource<BrowserWindow>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
var guid = Guid.NewGuid().ToString();
|
||||
|
||||
BridgeConnector.Once<int>("BrowserWindowCreated" + guid, (id) =>
|
||||
{
|
||||
var taskCompletionSource = new TaskCompletionSource<BrowserWindow>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var browserWindow = new BrowserWindow(id);
|
||||
|
||||
BridgeConnector.On<int>("BrowserWindowCreated", (id) =>
|
||||
{
|
||||
BridgeConnector.Off("BrowserWindowCreated");
|
||||
_browserWindows[id] = browserWindow;
|
||||
|
||||
var browserWindow = new BrowserWindow(id);
|
||||
taskCompletionSource.SetResult(browserWindow);
|
||||
});
|
||||
|
||||
_browserWindows[id] = browserWindow;
|
||||
|
||||
taskCompletionSource.SetResult(browserWindow);
|
||||
});
|
||||
if (string.Equals(loadUrl, "HTTP://LOCALHOST", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
loadUrl = $"{loadUrl}:{BridgeSettings.WebPort}";
|
||||
}
|
||||
|
||||
BridgeConnector.Off("BrowserWindowClosed");
|
||||
BridgeConnector.On<int[]>("BrowserWindowClosed", (browserWindowIdsStillOpen) =>
|
||||
{
|
||||
if (browserWindowIdsStillOpen.Any())
|
||||
{
|
||||
foreach (var id in _browserWindows.Keys.ToArray())
|
||||
{
|
||||
if (!browserWindowIdsStillOpen.Contains(id)) _browserWindows.TryRemove(id, out _);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_browserWindows.Clear();
|
||||
}
|
||||
});
|
||||
// Workaround Windows 10 / Electron Bug
|
||||
// https://github.com/electron/electron/issues/4045
|
||||
if (IsWindows10())
|
||||
{
|
||||
options.Width += 14;
|
||||
options.Height += 7;
|
||||
}
|
||||
|
||||
if (string.Equals(loadUrl, "HTTP://LOCALHOST", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
loadUrl = $"{loadUrl}:{BridgeSettings.WebPort}";
|
||||
}
|
||||
if (options.X == -1 && options.Y == -1)
|
||||
{
|
||||
options.X = 0;
|
||||
options.Y = 0;
|
||||
|
||||
BridgeConnector.Emit("createBrowserWindow", guid, JObject.FromObject(options, _jsonSerializer), loadUrl);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Workaround Windows 10 / Electron Bug
|
||||
// https://github.com/electron/electron/issues/4045
|
||||
if (IsWindows10())
|
||||
{
|
||||
options.Width = options.Width + 14;
|
||||
options.Height = options.Height + 7;
|
||||
options.X -= 7;
|
||||
}
|
||||
|
||||
if (options.X == -1 && options.Y == -1)
|
||||
{
|
||||
options.X = 0;
|
||||
options.Y = 0;
|
||||
|
||||
BridgeConnector.Emit("createBrowserWindow", JObject.FromObject(options, _jsonSerializer), loadUrl);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Workaround Windows 10 / Electron Bug
|
||||
// https://github.com/electron/electron/issues/4045
|
||||
if (IsWindows10())
|
||||
{
|
||||
options.X = options.X - 7;
|
||||
}
|
||||
|
||||
BridgeConnector.Emit("createBrowserWindow", JObject.FromObject(options, _keepDefaultValuesSerializer), loadUrl);
|
||||
}
|
||||
|
||||
return await taskCompletionSource.Task;
|
||||
BridgeConnector.Emit("createBrowserWindow", guid, JObject.FromObject(options, _keepDefaultValuesSerializer), loadUrl);
|
||||
}
|
||||
finally
|
||||
|
||||
return await taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
|
||||
private bool _hasClosedEvent = false;
|
||||
private readonly object _hasClosedEventLock = new();
|
||||
private void BootstrapUpdateOpenIDsEvent()
|
||||
{
|
||||
if (!_hasClosedEvent)
|
||||
{
|
||||
_singleCreate.Release();
|
||||
lock(_hasClosedEventLock)
|
||||
{
|
||||
if(!_hasClosedEvent)
|
||||
{
|
||||
BridgeConnector.On<int[]>("BrowserWindowUpdateOpenIDs", (browserWindowIdsStillOpen) =>
|
||||
{
|
||||
if (browserWindowIdsStillOpen.Any())
|
||||
{
|
||||
foreach (var id in _browserWindows.Keys.ToArray())
|
||||
{
|
||||
if (!browserWindowIdsStillOpen.Contains(id)) _browserWindows.TryRemove(id, out _);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_browserWindows.Clear();
|
||||
}
|
||||
});
|
||||
_hasClosedEvent = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,32 +202,20 @@ namespace ElectronNET.API
|
||||
/// <returns></returns>
|
||||
public async Task<BrowserView> CreateBrowserViewAsync(BrowserViewConstructorOptions options)
|
||||
{
|
||||
await _singleCreate.WaitAsync();
|
||||
var guid = Guid.NewGuid().ToString();
|
||||
|
||||
try
|
||||
var taskCompletionSource = new TaskCompletionSource<BrowserView>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
BridgeConnector.Once<int>("BrowserViewCreated" + guid, (id) =>
|
||||
{
|
||||
var browserView = new BrowserView(id);
|
||||
_browserViews[id] = browserView;
|
||||
taskCompletionSource.SetResult(browserView);
|
||||
});
|
||||
|
||||
var taskCompletionSource = new TaskCompletionSource<BrowserView>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
BridgeConnector.Emit("createBrowserView", guid, JObject.FromObject(options, _keepDefaultValuesSerializer));
|
||||
|
||||
BridgeConnector.On<int>("BrowserViewCreated", (id) =>
|
||||
{
|
||||
BridgeConnector.Off("BrowserViewCreated");
|
||||
|
||||
BrowserView browserView = new BrowserView(id);
|
||||
|
||||
_browserViews[id] = browserView;
|
||||
|
||||
taskCompletionSource.SetResult(browserView);
|
||||
});
|
||||
|
||||
BridgeConnector.Emit("createBrowserView", JObject.FromObject(options, _keepDefaultValuesSerializer));
|
||||
|
||||
return await taskCompletionSource.Task;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_singleCreate.Release();
|
||||
}
|
||||
return await taskCompletionSource.Task;
|
||||
}
|
||||
|
||||
private static JsonSerializer _jsonSerializer = new JsonSerializer()
|
||||
|
||||
@@ -7,7 +7,7 @@ let browserView, electronSocket;
|
||||
const proxyToCredentialsMap = (global['proxyToCredentialsMap'] = global['proxyToCredentialsMap'] || []);
|
||||
const browserViewApi = (socket) => {
|
||||
electronSocket = socket;
|
||||
socket.on('createBrowserView', (options) => {
|
||||
socket.on('createBrowserView', (guid, options) => {
|
||||
if (!hasOwnChildreen(options, 'webPreferences', 'nodeIntegration')) {
|
||||
options = { ...options, webPreferences: { nodeIntegration: true, contextIsolation: false } };
|
||||
}
|
||||
@@ -20,7 +20,7 @@ const browserViewApi = (socket) => {
|
||||
proxyToCredentialsMap[options.proxy] = options.proxyCredentials;
|
||||
}
|
||||
browserViews.push(browserView);
|
||||
electronSocket.emit('BrowserViewCreated', browserView['id']);
|
||||
electronSocket.emit('BrowserViewCreated' + guid, browserView['id']);
|
||||
});
|
||||
socket.on('browserView-getBounds', (id) => {
|
||||
const bounds = getBrowserViewById(id).getBounds();
|
||||
|
||||
@@ -7,7 +7,7 @@ const proxyToCredentialsMap: { [proxy: string]: string } = (global['proxyToCrede
|
||||
const browserViewApi = (socket: Socket) => {
|
||||
electronSocket = socket;
|
||||
|
||||
socket.on('createBrowserView', (options) => {
|
||||
socket.on('createBrowserView', (guid, options) => {
|
||||
if (!hasOwnChildreen(options, 'webPreferences', 'nodeIntegration')) {
|
||||
options = { ...options, webPreferences: { nodeIntegration: true, contextIsolation: false } };
|
||||
}
|
||||
@@ -25,7 +25,7 @@ const browserViewApi = (socket: Socket) => {
|
||||
|
||||
browserViews.push(browserView);
|
||||
|
||||
electronSocket.emit('BrowserViewCreated', browserView['id']);
|
||||
electronSocket.emit('BrowserViewCreated' + guid, browserView['id']);
|
||||
});
|
||||
|
||||
socket.on('browserView-getBounds', (id) => {
|
||||
|
||||
@@ -175,7 +175,7 @@ module.exports = (socket, app) => {
|
||||
electronSocket.emit('browserWindow-new-window-for-tab' + id);
|
||||
});
|
||||
});
|
||||
socket.on('createBrowserWindow', (options, loadUrl) => {
|
||||
socket.on('createBrowserWindow', (guid, options, loadUrl) => {
|
||||
if (options.webPreferences && !('nodeIntegration' in options.webPreferences)) {
|
||||
options = { ...options, webPreferences: { ...options.webPreferences, nodeIntegration: true, contextIsolation: false } };
|
||||
}
|
||||
@@ -188,7 +188,7 @@ module.exports = (socket, app) => {
|
||||
if (window) {
|
||||
window.reload();
|
||||
windows.push(window);
|
||||
electronSocket.emit('BrowserWindowCreated', window.id);
|
||||
electronSocket.emit('BrowserWindowCreated' + guid, window.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -218,6 +218,7 @@ module.exports = (socket, app) => {
|
||||
readyToShowWindowsIds.push(window.id);
|
||||
}
|
||||
});
|
||||
|
||||
window.on('closed', (sender) => {
|
||||
again:
|
||||
for (let index = 0; index < windows.length; index++) {
|
||||
@@ -234,7 +235,7 @@ module.exports = (socket, app) => {
|
||||
}
|
||||
const ids = [];
|
||||
windows.forEach(x => ids.push(x.id));
|
||||
electronSocket.emit('BrowserWindowClosed', ids);
|
||||
electronSocket.emit('BrowserWindowUpdateOpenIDs', ids);
|
||||
});
|
||||
if (loadUrl) {
|
||||
window.loadURL(loadUrl);
|
||||
@@ -250,7 +251,7 @@ module.exports = (socket, app) => {
|
||||
app['mainWindow'] = window;
|
||||
}
|
||||
windows.push(window);
|
||||
electronSocket.emit('BrowserWindowCreated', window.id);
|
||||
electronSocket.emit('BrowserWindowCreated' + guid, window.id);
|
||||
});
|
||||
socket.on('browserWindowDestroy', (id) => {
|
||||
getWindowById(id)?.destroy();
|
||||
|
||||
@@ -209,7 +209,7 @@ export = (socket: Socket, app: Electron.App) => {
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('createBrowserWindow', (options, loadUrl) => {
|
||||
socket.on('createBrowserWindow', (guid, options, loadUrl) => {
|
||||
if (options.webPreferences && !('nodeIntegration' in options.webPreferences)) {
|
||||
options = { ...options, webPreferences: { ...options.webPreferences, nodeIntegration: true, contextIsolation: false } };
|
||||
} else if (!options.webPreferences) {
|
||||
@@ -222,7 +222,7 @@ export = (socket: Socket, app: Electron.App) => {
|
||||
if (window) {
|
||||
window.reload();
|
||||
windows.push(window);
|
||||
electronSocket.emit('BrowserWindowCreated', window.id);
|
||||
electronSocket.emit('BrowserWindowCreated' + guid, window.id);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@@ -261,7 +261,7 @@ export = (socket: Socket, app: Electron.App) => {
|
||||
}
|
||||
const ids = [];
|
||||
windows.forEach(x => ids.push(x.id));
|
||||
electronSocket.emit('BrowserWindowClosed', ids);
|
||||
electronSocket.emit('BrowserWindowUpdateOpenIDs', ids);
|
||||
});
|
||||
|
||||
if (loadUrl) {
|
||||
@@ -281,7 +281,7 @@ export = (socket: Socket, app: Electron.App) => {
|
||||
}
|
||||
|
||||
windows.push(window);
|
||||
electronSocket.emit('BrowserWindowCreated', window.id);
|
||||
electronSocket.emit('BrowserWindowCreated' + guid, window.id);
|
||||
});
|
||||
|
||||
socket.on('browserWindowDestroy', (id) => {
|
||||
|
||||
Reference in New Issue
Block a user