2025-11-09 12:05:07 +01:00
|
|
|
using ElectronNET.API.Entities;
|
|
|
|
|
using ElectronNET.API.Serialization;
|
|
|
|
|
using ElectronNET.Common;
|
2017-10-23 19:08:10 +02:00
|
|
|
using System;
|
2025-11-09 12:05:07 +01:00
|
|
|
using System.Text.Json;
|
2017-10-23 19:08:10 +02:00
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace ElectronNET.API
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Retrieve information about screen size, displays, cursor position, etc.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public sealed class Screen
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Emitted when an new Display has been added.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event Action<Display> OnDisplayAdded
|
|
|
|
|
{
|
2025-11-09 15:15:52 +01:00
|
|
|
add => ApiEventManager.AddEvent("screen-display-added", GetHashCode(), _onDisplayAdded, value, (args) => args.Deserialize(ElectronJsonContext.Default.Display));
|
2025-11-05 15:06:41 +00:00
|
|
|
remove => ApiEventManager.RemoveEvent("screen-display-added", GetHashCode(), _onDisplayAdded, value);
|
2017-10-23 19:08:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private event Action<Display> _onDisplayAdded;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Emitted when oldDisplay has been removed.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event Action<Display> OnDisplayRemoved
|
|
|
|
|
{
|
2025-11-09 15:15:52 +01:00
|
|
|
add => ApiEventManager.AddEvent("screen-display-removed", GetHashCode(), _onDisplayRemoved, value, (args) => args.Deserialize(ElectronJsonContext.Default.Display));
|
2025-11-05 15:06:41 +00:00
|
|
|
remove => ApiEventManager.RemoveEvent("screen-display-removed", GetHashCode(), _onDisplayRemoved, value);
|
2017-10-23 19:08:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private event Action<Display> _onDisplayRemoved;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Emitted when one or more metrics change in a display.
|
|
|
|
|
/// The changedMetrics is an array of strings that describe the changes.
|
|
|
|
|
/// Possible changes are bounds, workArea, scaleFactor and rotation.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event Action<Display, string[]> OnDisplayMetricsChanged
|
|
|
|
|
{
|
2025-11-05 15:06:41 +00:00
|
|
|
add => ApiEventManager.AddScreenEvent("screen-display-metrics-changed", GetHashCode(), _onDisplayMetricsChanged, value);
|
|
|
|
|
remove => ApiEventManager.RemoveScreenEvent("screen-display-metrics-changed", GetHashCode(), _onDisplayMetricsChanged, value);
|
2017-10-23 19:08:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private event Action<Display, string[]> _onDisplayMetricsChanged;
|
|
|
|
|
|
|
|
|
|
private static Screen _screen;
|
2019-05-18 02:00:56 +02:00
|
|
|
private static object _syncRoot = new object();
|
2017-10-23 19:08:10 +02:00
|
|
|
|
2025-11-09 03:50:24 +01:00
|
|
|
internal Screen()
|
|
|
|
|
{
|
|
|
|
|
}
|
2017-10-23 19:08:10 +02:00
|
|
|
|
|
|
|
|
internal static Screen Instance
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
if (_screen == null)
|
|
|
|
|
{
|
2017-11-04 00:16:14 +01:00
|
|
|
lock (_syncRoot)
|
|
|
|
|
{
|
|
|
|
|
if (_screen == null)
|
|
|
|
|
{
|
|
|
|
|
_screen = new Screen();
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-10-23 19:08:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return _screen;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The current absolute position of the mouse pointer.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
2025-11-09 03:50:24 +01:00
|
|
|
public Task<Point> GetCursorScreenPointAsync()
|
2017-10-23 19:08:10 +02:00
|
|
|
{
|
|
|
|
|
var taskCompletionSource = new TaskCompletionSource<Point>();
|
|
|
|
|
|
2025-11-09 12:05:07 +01:00
|
|
|
BridgeConnector.Socket.On<JsonElement>("screen-getCursorScreenPointCompleted", (point) =>
|
2017-10-23 19:08:10 +02:00
|
|
|
{
|
|
|
|
|
BridgeConnector.Socket.Off("screen-getCursorScreenPointCompleted");
|
|
|
|
|
|
2025-11-09 15:15:52 +01:00
|
|
|
taskCompletionSource.SetResult(point.Deserialize<Point>(ElectronJson.Options));
|
2017-10-23 19:08:10 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
BridgeConnector.Socket.Emit("screen-getCursorScreenPoint");
|
|
|
|
|
|
|
|
|
|
return taskCompletionSource.Task;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// macOS: The height of the menu bar in pixels.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>The height of the menu bar in pixels.</returns>
|
|
|
|
|
public Task<int> GetMenuBarHeightAsync()
|
|
|
|
|
{
|
|
|
|
|
var taskCompletionSource = new TaskCompletionSource<int>();
|
|
|
|
|
|
2025-11-09 12:05:07 +01:00
|
|
|
BridgeConnector.Socket.On<JsonElement>("screen-getMenuBarHeightCompleted", (height) =>
|
2017-10-23 19:08:10 +02:00
|
|
|
{
|
|
|
|
|
BridgeConnector.Socket.Off("screen-getMenuBarHeightCompleted");
|
|
|
|
|
|
2025-11-09 12:05:07 +01:00
|
|
|
taskCompletionSource.SetResult(height.GetInt32());
|
2017-10-23 19:08:10 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
BridgeConnector.Socket.Emit("screen-getMenuBarHeight");
|
|
|
|
|
|
|
|
|
|
return taskCompletionSource.Task;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The primary display.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public Task<Display> GetPrimaryDisplayAsync()
|
|
|
|
|
{
|
|
|
|
|
var taskCompletionSource = new TaskCompletionSource<Display>();
|
|
|
|
|
|
2025-11-09 12:05:07 +01:00
|
|
|
BridgeConnector.Socket.On<JsonElement>("screen-getPrimaryDisplayCompleted", (display) =>
|
2017-10-23 19:08:10 +02:00
|
|
|
{
|
|
|
|
|
BridgeConnector.Socket.Off("screen-getPrimaryDisplayCompleted");
|
|
|
|
|
|
2025-11-09 12:05:07 +01:00
|
|
|
taskCompletionSource.SetResult(display.Deserialize(ElectronJsonContext.Default.Display));
|
2017-10-23 19:08:10 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
BridgeConnector.Socket.Emit("screen-getPrimaryDisplay");
|
|
|
|
|
|
|
|
|
|
return taskCompletionSource.Task;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// An array of displays that are currently available.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>An array of displays that are currently available.</returns>
|
|
|
|
|
public Task<Display[]> GetAllDisplaysAsync()
|
|
|
|
|
{
|
|
|
|
|
var taskCompletionSource = new TaskCompletionSource<Display[]>();
|
|
|
|
|
|
2025-11-09 12:05:07 +01:00
|
|
|
BridgeConnector.Socket.On<JsonElement>("screen-getAllDisplaysCompleted", (displays) =>
|
2017-10-23 19:08:10 +02:00
|
|
|
{
|
|
|
|
|
BridgeConnector.Socket.Off("screen-getAllDisplaysCompleted");
|
|
|
|
|
|
2025-11-09 12:05:07 +01:00
|
|
|
taskCompletionSource.SetResult(displays.Deserialize<Display[]>(ElectronJson.Options));
|
2017-10-23 19:08:10 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
BridgeConnector.Socket.Emit("screen-getAllDisplays");
|
|
|
|
|
|
|
|
|
|
return taskCompletionSource.Task;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The display nearest the specified point.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>The display nearest the specified point.</returns>
|
|
|
|
|
public Task<Display> GetDisplayNearestPointAsync(Point point)
|
|
|
|
|
{
|
|
|
|
|
var taskCompletionSource = new TaskCompletionSource<Display>();
|
|
|
|
|
|
2025-11-09 12:05:07 +01:00
|
|
|
BridgeConnector.Socket.On<JsonElement>("screen-getDisplayNearestPointCompleted", (display) =>
|
2017-10-23 19:08:10 +02:00
|
|
|
{
|
|
|
|
|
BridgeConnector.Socket.Off("screen-getDisplayNearestPointCompleted");
|
|
|
|
|
|
2025-11-09 15:15:52 +01:00
|
|
|
taskCompletionSource.SetResult(display.Deserialize(ElectronJsonContext.Default.Display));
|
2017-10-23 19:08:10 +02:00
|
|
|
});
|
|
|
|
|
|
2025-11-09 12:05:07 +01:00
|
|
|
BridgeConnector.Socket.Emit("screen-getDisplayNearestPoint", point);
|
2017-10-23 19:08:10 +02:00
|
|
|
|
|
|
|
|
return taskCompletionSource.Task;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The display that most closely intersects the provided bounds.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="rectangle"></param>
|
|
|
|
|
/// <returns>The display that most closely intersects the provided bounds.</returns>
|
|
|
|
|
public Task<Display> GetDisplayMatchingAsync(Rectangle rectangle)
|
|
|
|
|
{
|
|
|
|
|
var taskCompletionSource = new TaskCompletionSource<Display>();
|
|
|
|
|
|
2025-11-09 12:05:07 +01:00
|
|
|
BridgeConnector.Socket.On<JsonElement>("screen-getDisplayMatching", (display) =>
|
2017-10-23 19:08:10 +02:00
|
|
|
{
|
|
|
|
|
BridgeConnector.Socket.Off("screen-getDisplayMatching");
|
|
|
|
|
|
2025-11-09 15:15:52 +01:00
|
|
|
taskCompletionSource.SetResult(display.Deserialize(ElectronJsonContext.Default.Display));
|
2017-10-23 19:08:10 +02:00
|
|
|
});
|
|
|
|
|
|
2025-11-09 12:05:07 +01:00
|
|
|
BridgeConnector.Socket.Emit("screen-getDisplayMatching", rectangle);
|
2017-10-23 19:08:10 +02:00
|
|
|
|
|
|
|
|
return taskCompletionSource.Task;
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-09 12:05:07 +01:00
|
|
|
|
2017-10-23 19:08:10 +02:00
|
|
|
}
|
2025-11-09 12:05:07 +01:00
|
|
|
}
|