mirror of
https://github.com/ElectronNET/Electron.NET.git
synced 2026-09-22 15:04:47 +00:00
Merge branch 'master' of https://github.com/theolivenbaum/Electron.NET
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
variables:
|
||||
PackageVersion: 13.5.1.$(Build.BuildId)
|
||||
PackageVersion: 14.0.0.$(Build.BuildId)
|
||||
projectAPI: './ElectronNET.API/ElectronNET.API.csproj'
|
||||
projectCLI: './ElectronNET.CLI/ElectronNET.CLI.csproj'
|
||||
|
||||
|
||||
@@ -90,34 +90,41 @@ namespace ElectronNET.API
|
||||
|
||||
private static SemaphoreSlim _socketSemaphoreEmit = new SemaphoreSlim(1, 1);
|
||||
private static SemaphoreSlim _socketSemaphoreHandlers = new SemaphoreSlim(1, 1);
|
||||
|
||||
private static TaskCompletionSource _waitForBeingConnected = new TaskCompletionSource();
|
||||
|
||||
private static Task _waitForConnection => _waitForBeingConnected.Task;
|
||||
private static TaskCompletionSource<SocketIO> _connectedSocketTask = new TaskCompletionSource<SocketIO>();
|
||||
|
||||
private static Task<SocketIO> _waitForConnection
|
||||
{
|
||||
get
|
||||
{
|
||||
EnsureSocketTaskIsCreated();
|
||||
return _connectedSocketTask.Task;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsConnected => _waitForConnection is Task task && task.IsCompletedSuccessfully;
|
||||
|
||||
public static void Emit(string eventString, params object[] args)
|
||||
{
|
||||
//We don't care about waiting for the event to be emitted, so this doesn't need to be async
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await EmitAsync(eventString, args);
|
||||
});
|
||||
Task.Run(() => EmitAsync(eventString, args));
|
||||
}
|
||||
|
||||
private static async Task EmitAsync(string eventString, object[] args)
|
||||
{
|
||||
await _waitForConnection;
|
||||
|
||||
if (App.SocketDebug)
|
||||
{
|
||||
Log("Sending event {0}", eventString);
|
||||
}
|
||||
|
||||
var socket = await _waitForConnection;
|
||||
|
||||
await _socketSemaphoreEmit.WaitAsync();
|
||||
|
||||
try
|
||||
{
|
||||
await Socket.EmitAsync(eventString, args);
|
||||
await socket.EmitAsync(eventString, args);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -130,30 +137,6 @@ namespace ElectronNET.API
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Log(string formatString, params object[] args)
|
||||
{
|
||||
if (Logger is object)
|
||||
{
|
||||
Logger.LogInformation(formatString, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(formatString, args);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void LogError(Exception E, string formatString, params object[] args)
|
||||
{
|
||||
if (Logger is object)
|
||||
{
|
||||
Logger.LogError(E, formatString, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(formatString, args);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is only used on places where we need to be sure the event was sent on the socket, such as Quit, Exit, Relaunch and QuitAndInstall methods
|
||||
/// </summary>
|
||||
@@ -166,18 +149,19 @@ namespace ElectronNET.API
|
||||
Log("Sending event {0}", eventString);
|
||||
}
|
||||
|
||||
_waitForConnection.Wait();
|
||||
|
||||
_socketSemaphoreEmit.Wait();
|
||||
|
||||
try
|
||||
Task.Run(async () =>
|
||||
{
|
||||
Socket.EmitAsync(eventString, args).Wait();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_socketSemaphoreEmit.Release();
|
||||
}
|
||||
var socket = await _waitForConnection;
|
||||
try
|
||||
{
|
||||
await _socketSemaphoreEmit.WaitAsync();
|
||||
await socket.EmitAsync(eventString, args);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_socketSemaphoreEmit.Release();
|
||||
}
|
||||
}).Wait();
|
||||
|
||||
|
||||
if (App.SocketDebug)
|
||||
@@ -188,10 +172,12 @@ namespace ElectronNET.API
|
||||
|
||||
public static void Off(string eventString)
|
||||
{
|
||||
EnsureSocketTaskIsCreated();
|
||||
|
||||
_socketSemaphoreHandlers.Wait();
|
||||
try
|
||||
{
|
||||
Socket.Off(eventString);
|
||||
_socket.Off(eventString);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -201,10 +187,12 @@ namespace ElectronNET.API
|
||||
|
||||
public static void On(string eventString, Action fn)
|
||||
{
|
||||
EnsureSocketTaskIsCreated();
|
||||
|
||||
_socketSemaphoreHandlers.Wait();
|
||||
try
|
||||
{
|
||||
Socket.On(eventString, _ =>
|
||||
_socket.On(eventString, _ =>
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -224,10 +212,12 @@ namespace ElectronNET.API
|
||||
|
||||
public static void On<T>(string eventString, Action<T> fn)
|
||||
{
|
||||
EnsureSocketTaskIsCreated();
|
||||
|
||||
_socketSemaphoreHandlers.Wait();
|
||||
try
|
||||
{
|
||||
Socket.On(eventString, (o) =>
|
||||
_socket.On(eventString, (o) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -359,101 +349,131 @@ namespace ElectronNET.API
|
||||
|
||||
return await taskCompletionSource.Task;
|
||||
}
|
||||
private static SocketIO Socket
|
||||
|
||||
internal static void Log(string formatString, params object[] args)
|
||||
{
|
||||
get
|
||||
if (Logger is object)
|
||||
{
|
||||
if (_socket is null)
|
||||
Logger.LogInformation(formatString, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(formatString, args);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void LogError(Exception E, string formatString, params object[] args)
|
||||
{
|
||||
if (Logger is object)
|
||||
{
|
||||
Logger.LogError(E, formatString, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(formatString, args);
|
||||
Console.WriteLine(E.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private static void EnsureSocketTaskIsCreated()
|
||||
{
|
||||
if (_socket is null)
|
||||
{
|
||||
if (HybridSupport.IsElectronActive)
|
||||
{
|
||||
if (HybridSupport.IsElectronActive)
|
||||
lock (_syncRoot)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
if (_socket is null && HybridSupport.IsElectronActive)
|
||||
{
|
||||
if (_socket is null && HybridSupport.IsElectronActive)
|
||||
var socket = new SocketIO($"http://localhost:{BridgeSettings.SocketPort}", new SocketIOOptions()
|
||||
{
|
||||
var socket = new SocketIO($"http://localhost:{BridgeSettings.SocketPort}", new SocketIOOptions()
|
||||
{
|
||||
EIO = 3,
|
||||
Reconnection = true,
|
||||
ReconnectionAttempts = int.MaxValue,
|
||||
ReconnectionDelay = 1000,
|
||||
ReconnectionDelayMax = 5000,
|
||||
RandomizationFactor = 0.1,
|
||||
ConnectionTimeout = TimeSpan.FromSeconds(10)
|
||||
});
|
||||
EIO = 3,
|
||||
Reconnection = true,
|
||||
ReconnectionAttempts = int.MaxValue,
|
||||
ReconnectionDelay = 1000,
|
||||
ReconnectionDelayMax = 5000,
|
||||
RandomizationFactor = 0.5,
|
||||
ConnectionTimeout = TimeSpan.FromSeconds(10)
|
||||
});
|
||||
|
||||
socket.JsonSerializer = new CamelCaseNewtonsoftJsonSerializer(socket.Options.EIO);
|
||||
socket.JsonSerializer = new CamelCaseNewtonsoftJsonSerializer(socket.Options.EIO);
|
||||
|
||||
socket.OnConnected += (_, __) =>
|
||||
{
|
||||
Log("ElectronNET socket connected on port {0}!", BridgeSettings.SocketPort);
|
||||
_waitForBeingConnected.TrySetResult();
|
||||
};
|
||||
socket.OnConnected += (_, __) =>
|
||||
{
|
||||
_connectedSocketTask.TrySetResult(socket);
|
||||
Log("ElectronNET socket connected on port {0}!", BridgeSettings.SocketPort);
|
||||
};
|
||||
|
||||
socket.OnReconnectAttempt += (_, __) =>
|
||||
{
|
||||
Log("ElectronNET socket is trying to reconnect on port {0}...", BridgeSettings.SocketPort);
|
||||
_waitForBeingConnected = new();
|
||||
};
|
||||
socket.OnReconnectAttempt += (_, __) =>
|
||||
{
|
||||
_connectedSocketTask = new();
|
||||
Log("ElectronNET socket is trying to reconnect on port {0}...", BridgeSettings.SocketPort);
|
||||
};
|
||||
|
||||
socket.OnReconnectError += (_, ex) =>
|
||||
{
|
||||
Log("ElectronNET socket failed to connect {0}", ex);
|
||||
};
|
||||
socket.OnReconnectError += (_, ex) =>
|
||||
{
|
||||
Log("ElectronNET socket failed to connect {0}", ex);
|
||||
};
|
||||
|
||||
socket.OnReconnected += (_, __) =>
|
||||
{
|
||||
Log("ElectronNET socket reconnected on port {0}...", BridgeSettings.SocketPort);
|
||||
_waitForBeingConnected.TrySetResult();
|
||||
};
|
||||
socket.OnReconnected += (_, __) =>
|
||||
{
|
||||
_connectedSocketTask.TrySetResult(socket);
|
||||
Log("ElectronNET socket reconnected on port {0}...", BridgeSettings.SocketPort);
|
||||
};
|
||||
|
||||
|
||||
socket.OnDisconnected += async (_, reason) =>
|
||||
{
|
||||
Log("ElectronNET socket disconnected with reason {0}, trying to reconnect on port {1}!", reason, BridgeSettings.SocketPort);
|
||||
socket.OnDisconnected += async (_, reason) =>
|
||||
{
|
||||
_connectedSocketTask = new();
|
||||
|
||||
Log("ElectronNET socket disconnected with reason {0}, trying to reconnect on port {1}!", reason, BridgeSettings.SocketPort);
|
||||
|
||||
int i = 0;
|
||||
|
||||
_waitForBeingConnected = new();
|
||||
double miliseconds = 500;
|
||||
|
||||
int i = 0;
|
||||
|
||||
double miliseconds = 500;
|
||||
|
||||
while (true)
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
try
|
||||
if (!socket.Connected)
|
||||
{
|
||||
if (!socket.Connected)
|
||||
{
|
||||
await socket.ConnectAsync();
|
||||
_waitForBeingConnected.TrySetResult(); //Probably was already on the OnConnected call
|
||||
}
|
||||
return;
|
||||
await socket.ConnectAsync();
|
||||
_connectedSocketTask.TrySetResult(socket); //Probably was already on the OnConnected call
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogError(e, "Failed to reconnect, will try again in {0} ms.", miliseconds * 2);
|
||||
}
|
||||
|
||||
await Task.Delay(TimeSpan.FromMilliseconds(miliseconds));
|
||||
|
||||
miliseconds = Math.Min(60_000, Math.Pow(2, i) + 500);
|
||||
i++;
|
||||
return;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogError(e, "Failed to reconnect, will try again in {0} ms.", miliseconds * 2);
|
||||
}
|
||||
};
|
||||
|
||||
socket.ConnectAsync().Wait();
|
||||
await Task.Delay(TimeSpan.FromMilliseconds(miliseconds));
|
||||
|
||||
_socket = socket;
|
||||
}
|
||||
miliseconds = Math.Min(60_000, Math.Pow(2, i) + 500);
|
||||
|
||||
i++;
|
||||
}
|
||||
};
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await socket.ConnectAsync();
|
||||
_connectedSocketTask.TrySetResult(socket); //Probably was already on the OnConnected call
|
||||
});
|
||||
|
||||
_socket = socket;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Missing Socket Port");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Missing Socket Port");
|
||||
}
|
||||
}
|
||||
|
||||
return _socket;
|
||||
else
|
||||
{
|
||||
throw new Exception("Missing Socket Port");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,12 +26,12 @@
|
||||
/// <summary>
|
||||
/// Can be 0, 90, 180, 270, represents screen rotation in clock-wise degrees.
|
||||
/// </summary>
|
||||
public int Rotation { get; set; }
|
||||
public float Rotation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Output device's pixel scale factor.
|
||||
/// </summary>
|
||||
public int ScaleFactor { get; set; }
|
||||
public float ScaleFactor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the size.
|
||||
|
||||
@@ -207,11 +207,5 @@ namespace ElectronNET.API.Entities
|
||||
/// </value>
|
||||
[DefaultValue(false)]
|
||||
public bool WebviewTag { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to enable the remote module. Defaults to false.
|
||||
/// </summary>
|
||||
[DefaultValue(false)]
|
||||
public bool EnableRemoteModule { get; set; } = false;
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,8 @@ namespace ElectronNET.API
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsConnected => BridgeConnector.IsConnected;
|
||||
|
||||
/// <summary>
|
||||
/// Listens to channel, when a new message arrives listener would be called with
|
||||
/// listener(event, args...).
|
||||
@@ -62,7 +64,6 @@ namespace ElectronNET.API
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Listens to channel, when a new message arrives listener would be called with
|
||||
/// listener(event, args...). This listner will keep the window event sender id
|
||||
@@ -173,32 +174,28 @@ namespace ElectronNET.API
|
||||
/// <param name="data">Arguments data.</param>
|
||||
public void Send(BrowserWindow browserWindow, string channel, params object[] data)
|
||||
{
|
||||
List<JObject> jobjects = new List<JObject>();
|
||||
List<JArray> jarrays = new List<JArray>();
|
||||
List<object> objects = new List<object>();
|
||||
var objectsWithCorrectSerialization = new List<object>();
|
||||
|
||||
objectsWithCorrectSerialization.Add(browserWindow.Id);
|
||||
objectsWithCorrectSerialization.Add(channel);
|
||||
|
||||
foreach (var parameterObject in data)
|
||||
{
|
||||
if(parameterObject.GetType().IsArray || parameterObject.GetType().IsGenericType && parameterObject is IEnumerable)
|
||||
{
|
||||
jarrays.Add(JArray.FromObject(parameterObject, _jsonSerializer));
|
||||
} else if(parameterObject.GetType().IsClass && !parameterObject.GetType().IsPrimitive && !(parameterObject is string))
|
||||
objectsWithCorrectSerialization.Add(JArray.FromObject(parameterObject, _jsonSerializer));
|
||||
}
|
||||
else if(parameterObject.GetType().IsClass && !parameterObject.GetType().IsPrimitive && !(parameterObject is string))
|
||||
{
|
||||
jobjects.Add(JObject.FromObject(parameterObject, _jsonSerializer));
|
||||
} else if(parameterObject.GetType().IsPrimitive || (parameterObject is string))
|
||||
objectsWithCorrectSerialization.Add(JObject.FromObject(parameterObject, _jsonSerializer));
|
||||
}
|
||||
else if(parameterObject.GetType().IsPrimitive || (parameterObject is string))
|
||||
{
|
||||
objects.Add(parameterObject);
|
||||
objectsWithCorrectSerialization.Add(parameterObject);
|
||||
}
|
||||
}
|
||||
|
||||
if(jobjects.Count > 0 || jarrays.Count > 0)
|
||||
{
|
||||
BridgeConnector.Emit("sendToIpcRenderer", JObject.FromObject(browserWindow, _jsonSerializer), channel, jarrays.ToArray(), jobjects.ToArray(), objects.ToArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
BridgeConnector.Emit("sendToIpcRenderer", JObject.FromObject(browserWindow, _jsonSerializer), channel, data);
|
||||
}
|
||||
BridgeConnector.Emit("sendToIpcRenderer", objectsWithCorrectSerialization.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -38,8 +38,8 @@ module.exports = (socket) => {
|
||||
socket.on('removeAllListenersIpcMainChannel', (channel) => {
|
||||
electron_1.ipcMain.removeAllListeners(channel);
|
||||
});
|
||||
socket.on('sendToIpcRenderer', (browserWindow, channel, ...data) => {
|
||||
const window = electron_1.BrowserWindow.fromId(browserWindow.id);
|
||||
socket.on('sendToIpcRenderer', (browserWindowId, channel, ...data) => {
|
||||
const window = electron_1.BrowserWindow.fromId(browserWindowId);
|
||||
if (window) {
|
||||
window.webContents.send(channel, ...data);
|
||||
}
|
||||
|
||||
@@ -44,8 +44,8 @@ export = (socket: Socket) => {
|
||||
ipcMain.removeAllListeners(channel);
|
||||
});
|
||||
|
||||
socket.on('sendToIpcRenderer', (browserWindow, channel, ...data) => {
|
||||
const window = BrowserWindow.fromId(browserWindow.id);
|
||||
socket.on('sendToIpcRenderer', (browserWindowId, channel, ...data) => {
|
||||
const window = BrowserWindow.fromId(browserWindowId);
|
||||
|
||||
if (window) {
|
||||
window.webContents.send(channel, ...data);
|
||||
|
||||
60
ElectronNET.Host/package-lock.json
generated
60
ElectronNET.Host/package-lock.json
generated
@@ -31,9 +31,9 @@
|
||||
}
|
||||
},
|
||||
"@electron/get": {
|
||||
"version": "1.12.4",
|
||||
"resolved": "https://registry.npmjs.org/@electron/get/-/get-1.12.4.tgz",
|
||||
"integrity": "sha512-6nr9DbJPUR9Xujw6zD3y+rS95TyItEVM0NVjt1EehY2vUWfIgPiIPVHxCvaTS0xr2B+DRxovYVKbuOWqC35kjg==",
|
||||
"version": "1.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron/get/-/get-1.13.0.tgz",
|
||||
"integrity": "sha512-+SjZhRuRo+STTO1Fdhzqnv9D2ZhjxXP6egsJ9kiO8dtP68cDx7dFCwWi64dlMQV7sWcfW1OYCW4wviEBzmRsfQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "^4.1.1",
|
||||
@@ -71,9 +71,9 @@
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "15.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-15.14.0.tgz",
|
||||
"integrity": "sha512-um/+/ip3QZmwLfIkWZSNtQIJNVAqrJ92OkLMeuZrjZMTAJniI7fh8N8OICyDhAJ2mzgk/fmYFo72jRr5HyZ1EQ==",
|
||||
"version": "15.14.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-15.14.9.tgz",
|
||||
"integrity": "sha512-qjd88DrCxupx/kJD5yQgZdcYKZKSIGBVDIBE1/LTGcNm3d2Np/jxojkdePDdfnBHJc5W7vSMpbJ1aB7p/Py69A==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/semver": {
|
||||
@@ -153,9 +153,9 @@
|
||||
"integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig=="
|
||||
},
|
||||
"boolean": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/boolean/-/boolean-3.1.2.tgz",
|
||||
"integrity": "sha512-YN6UmV0FfLlBVvRvNPx3pz5W/mUoYB24J4WSXOKP/OOJpi+Oq6WYqPaNTHzjI0QzwWtnvEd5CGYyQPgp1jFxnw==",
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/boolean/-/boolean-3.1.4.tgz",
|
||||
"integrity": "sha512-3hx0kwU3uzG6ReQ3pnaFQPSktpBw6RHN3/ivDKEuU8g1XSfafowyvDnadjv1xp8IZqhtSukxlwv9bF6FhX8m0w==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
@@ -176,9 +176,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"buffer-from": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
|
||||
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||
"dev": true
|
||||
},
|
||||
"builder-util-runtime": {
|
||||
@@ -337,16 +337,16 @@
|
||||
"integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA=="
|
||||
},
|
||||
"core-js": {
|
||||
"version": "3.15.2",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.15.2.tgz",
|
||||
"integrity": "sha512-tKs41J7NJVuaya8DxIOCnl8QuPHx5/ZVbFo1oKgVl1qHFBBrDctzQGtuLjPpRdNTWmKPH6oEvgN/MUID+l485Q==",
|
||||
"version": "3.17.1",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.17.1.tgz",
|
||||
"integrity": "sha512-C8i/FNpVN2Ti89QIJcFn9ZQmnM+HaAQr2OpE+ja3TRM9Q34FigsGlAVuwPGkIgydSVClo/1l1D1grP8LVt9IYA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
|
||||
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
|
||||
"dev": true
|
||||
},
|
||||
"dasherize": {
|
||||
@@ -355,9 +355,9 @@
|
||||
"integrity": "sha1-bYCcnNDPe7iVLYD8hPoT1H3bEwg="
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
|
||||
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
@@ -408,9 +408,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"electron": {
|
||||
"version": "13.1.5",
|
||||
"resolved": "https://registry.npmjs.org/electron/-/electron-13.1.5.tgz",
|
||||
"integrity": "sha512-ZoMCcPQNs/zO/Zdb5hq5H+rwRaKrdI3/sfXEwBVMx7f5jwa9jPQB3dZ2+7t59uD9VcFAWsH/pozr8nPPlv0tyw==",
|
||||
"version": "14.0.0",
|
||||
"resolved": "https://registry.npmjs.org/electron/-/electron-14.0.0.tgz",
|
||||
"integrity": "sha512-O6EI7L1BPIrTpEIFefjjmdbmSn9LtE4mmrv4dfpV4Mqaa8uKuNYQogwZPEvSwaBexb69eb1LQ25n+f+kBcjiRQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@electron/get": "^1.0.1",
|
||||
@@ -419,9 +419,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "14.17.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.4.tgz",
|
||||
"integrity": "sha512-8kQ3+wKGRNN0ghtEn7EGps/B8CzuBz1nXZEIGGLP2GnwbqYn4dbTs7k+VKLTq1HvZLRCIDtN3Snx1Ege8B7L5A==",
|
||||
"version": "14.17.14",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.14.tgz",
|
||||
"integrity": "sha512-rsAj2u8Xkqfc332iXV12SqIsjVi07H479bOP4q94NAcjzmAvapumEhuVIt53koEf7JFrpjgNKjBga5Pnn/GL8A==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
@@ -1410,9 +1410,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"typescript": {
|
||||
"version": "4.3.5",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz",
|
||||
"integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==",
|
||||
"version": "4.4.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.2.tgz",
|
||||
"integrity": "sha512-gzP+t5W4hdy4c+68bfcv0t400HVJMMd2+H9B7gae1nQlBzCqvrXX+6GL/b3GAgyTH966pzrZ70/fRjwAtZksSQ==",
|
||||
"dev": true
|
||||
},
|
||||
"universalify": {
|
||||
|
||||
@@ -19,9 +19,9 @@
|
||||
"socket.io": "^2.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^15.14.0",
|
||||
"electron": "^13.1.5",
|
||||
"@types/node": "^15.14.9",
|
||||
"electron": "^14.0.0",
|
||||
"tslint": "^6.1.3",
|
||||
"typescript": "^4.3.5"
|
||||
"typescript": "^4.4.2"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user