From a7f2ccf433519ab7f7d8d14cbcc37487aee3e8e6 Mon Sep 17 00:00:00 2001 From: galister <22305755+galister@users.noreply.github.com> Date: Thu, 9 Nov 2023 10:36:36 +0900 Subject: [PATCH] dotnet format --- Core/Subsystem/WaylandSubsystem.cs | 426 +++++++++---------- Desktop/Wayland/XdgScreenCastHandler.cs | 538 ++++++++++++------------ Input/KeyboardLayout.cs | 3 +- Overlays/Watch.cs | 4 +- Program.cs | 40 +- 5 files changed, 506 insertions(+), 505 deletions(-) diff --git a/Core/Subsystem/WaylandSubsystem.cs b/Core/Subsystem/WaylandSubsystem.cs index 66a6fac..ab70121 100644 --- a/Core/Subsystem/WaylandSubsystem.cs +++ b/Core/Subsystem/WaylandSubsystem.cs @@ -10,255 +10,255 @@ namespace WlxOverlay.Core.Subsystem; public class WaylandSubsystem : ISubsystem { - public static string? DisplayName; + public static string? DisplayName; - private DateTime _nextRoundTrip = DateTime.UtcNow; + private DateTime _nextRoundTrip = DateTime.UtcNow; - private readonly Dictionary _outputs = new(); + private readonly Dictionary _outputs = new(); - private readonly List _supportedCaptureMethods = new(); + private readonly List _supportedCaptureMethods = new(); - private readonly WlDisplay _display; - private ZxdgOutputManagerV1? _outputManager; - private WlSeat? _seat; - private CaptureMethod _captureMethod; + private readonly WlDisplay _display; + private ZxdgOutputManagerV1? _outputManager; + private WlSeat? _seat; + private CaptureMethod _captureMethod; - public static bool TryInitialize(out WaylandSubsystem instance) - { - var env = Environment.GetEnvironmentVariable("WAYLAND_DISPLAY"); - if (env != null) - DisplayName = env; - else + public static bool TryInitialize(out WaylandSubsystem instance) { - env = Environment.GetEnvironmentVariable("XDG_RUNTIME_DIR"); - if (env != null) - foreach (var fPath in Directory.GetFiles(env)) + var env = Environment.GetEnvironmentVariable("WAYLAND_DISPLAY"); + if (env != null) + DisplayName = env; + else { - var fName = Path.GetFileName(fPath); - if (fName.StartsWith("wayland-")) - { - DisplayName = fName; - Environment.SetEnvironmentVariable("WAYLAND_DISPLAY", DisplayName); - break; - } + env = Environment.GetEnvironmentVariable("XDG_RUNTIME_DIR"); + if (env != null) + foreach (var fPath in Directory.GetFiles(env)) + { + var fName = Path.GetFileName(fPath); + if (fName.StartsWith("wayland-")) + { + DisplayName = fName; + Environment.SetEnvironmentVariable("WAYLAND_DISPLAY", DisplayName); + break; + } + } } - } - - if (DisplayName == null) - { - instance = null!; - return false; - } - Console.WriteLine("Wayland detected."); + if (DisplayName == null) + { + instance = null!; + return false; + } - switch (Config.Instance.WaylandCapture) - { - case "screencopy": - Console.WriteLine("Not loading EGL due to screencopy."); - break; - case "pw-fallback": - Console.WriteLine("Not loading EGL due to pw-fallback."); - break; - default: - EGL.Initialize(); - break; - } + Console.WriteLine("Wayland detected."); - instance = new WaylandSubsystem(); + switch (Config.Instance.WaylandCapture) + { + case "screencopy": + Console.WriteLine("Not loading EGL due to screencopy."); + break; + case "pw-fallback": + Console.WriteLine("Not loading EGL due to pw-fallback."); + break; + default: + EGL.Initialize(); + break; + } - var maxTries = 100; - while (instance._outputs.Count == 0 && maxTries-- > 0) - { - instance._display.Roundtrip(); - Thread.Sleep(50); - } - Thread.Sleep(100); + instance = new WaylandSubsystem(); - switch (Config.Instance.WaylandCapture) - { - case "dmabuf": - instance._captureMethod = CaptureMethod.WlrDmaBuf; - break; - case "screencopy": - instance._captureMethod = CaptureMethod.WlrScreenCopy; - break; - case "pipewire": - case "pw-fallback": - instance._captureMethod = CaptureMethod.PipeWire; - break; - default: - if (instance._supportedCaptureMethods.Contains(CaptureMethod.WlrDmaBuf)) - instance._captureMethod = CaptureMethod.WlrDmaBuf; - else if (instance._supportedCaptureMethods.Contains(CaptureMethod.WlrScreenCopy)) - instance._captureMethod = CaptureMethod.WlrScreenCopy; - else - instance._captureMethod = CaptureMethod.PipeWire; - break; - } + var maxTries = 100; + while (instance._outputs.Count == 0 && maxTries-- > 0) + { + instance._display.Roundtrip(); + Thread.Sleep(50); + } + Thread.Sleep(100); - return true; - } + switch (Config.Instance.WaylandCapture) + { + case "dmabuf": + instance._captureMethod = CaptureMethod.WlrDmaBuf; + break; + case "screencopy": + instance._captureMethod = CaptureMethod.WlrScreenCopy; + break; + case "pipewire": + case "pw-fallback": + instance._captureMethod = CaptureMethod.PipeWire; + break; + default: + if (instance._supportedCaptureMethods.Contains(CaptureMethod.WlrDmaBuf)) + instance._captureMethod = CaptureMethod.WlrDmaBuf; + else if (instance._supportedCaptureMethods.Contains(CaptureMethod.WlrScreenCopy)) + instance._captureMethod = CaptureMethod.WlrScreenCopy; + else + instance._captureMethod = CaptureMethod.PipeWire; + break; + } - public void Initialize() - { - // No Subsystem Initialization - } + return true; + } - public void Update() - { - if (_nextRoundTrip < DateTime.UtcNow) + public void Initialize() { - _display.Roundtrip(); - _nextRoundTrip = DateTime.UtcNow.AddSeconds(1); + // No Subsystem Initialization } - } - public async Task CreateScreensAsync() - { - switch (_captureMethod) + public void Update() { - case CaptureMethod.WlrDmaBuf: - Console.WriteLine($"Using desktop capture protocol: {WlInterface.ZwlrExportDmabufManagerV1.Name}"); - foreach (var output in _outputs.Values) + if (_nextRoundTrip < DateTime.UtcNow) { - var screen = new DesktopOverlay(output, - new WlrCapture(output)); - OverlayRegistry.Register(screen); + _display.Roundtrip(); + _nextRoundTrip = DateTime.UtcNow.AddSeconds(1); } - break; - case CaptureMethod.WlrScreenCopy: - Console.WriteLine($"Using desktop capture protocol: {WlInterface.ZwlrScreencopyManagerV1.Name}"); - foreach (var output in _outputs.Values) + } + + public async Task CreateScreensAsync() + { + switch (_captureMethod) { - var screen = new DesktopOverlay(output, - new WlrCapture(output)); - OverlayRegistry.Register(screen); + case CaptureMethod.WlrDmaBuf: + Console.WriteLine($"Using desktop capture protocol: {WlInterface.ZwlrExportDmabufManagerV1.Name}"); + foreach (var output in _outputs.Values) + { + var screen = new DesktopOverlay(output, + new WlrCapture(output)); + OverlayRegistry.Register(screen); + } + break; + case CaptureMethod.WlrScreenCopy: + Console.WriteLine($"Using desktop capture protocol: {WlInterface.ZwlrScreencopyManagerV1.Name}"); + foreach (var output in _outputs.Values) + { + var screen = new DesktopOverlay(output, + new WlrCapture(output)); + OverlayRegistry.Register(screen); + } + break; + case CaptureMethod.PipeWire: + Console.WriteLine("Using PipeWire capture."); + await CreatePipeWireScreensAsync(); + break; } - break; - case CaptureMethod.PipeWire: - Console.WriteLine("Using PipeWire capture."); - await CreatePipeWireScreensAsync(); - break; } - } - - private async Task CreatePipeWireScreensAsync() - { - PipeWireCapture.Load(); - if (_outputs.Values.Count > 0) + private async Task CreatePipeWireScreensAsync() { - Console.WriteLine(" You will be prompted one screen at a time.\n" + - " Please select the corresponding screen on the prompt.\n" + - " Cancel the prompt if you do not wish to capture the given screen. \n" + - " If your compositor supports org.freedesktop.portal.ScreenCast v4, you will only be prompted once."); - - foreach (var output in _outputs.Values) - { - if (output == null!) // idk why, but it happens - continue; - - var data = await XdgScreenCastHandler.PromptUserAsync(output); - if (data != null) + PipeWireCapture.Load(); + + if (_outputs.Values.Count > 0) { - var screen = new DesktopOverlay(output, new PipeWireCapture(output, data.Value)); - OverlayRegistry.Register(screen); - Console.WriteLine($"{output.Name} -> {data.Value}"); + Console.WriteLine(" You will be prompted one screen at a time.\n" + + " Please select the corresponding screen on the prompt.\n" + + " Cancel the prompt if you do not wish to capture the given screen. \n" + + " If your compositor supports org.freedesktop.portal.ScreenCast v4, you will only be prompted once."); + + foreach (var output in _outputs.Values) + { + if (output == null!) // idk why, but it happens + continue; + + var data = await XdgScreenCastHandler.PromptUserAsync(output); + if (data != null) + { + var screen = new DesktopOverlay(output, new PipeWireCapture(output, data.Value)); + OverlayRegistry.Register(screen); + Console.WriteLine($"{output.Name} -> {data.Value}"); + } + else + Console.WriteLine($"{output.Name} will not be used."); + } } else - Console.WriteLine($"{output.Name} will not be used."); - } + { + Console.WriteLine(" ERROR Could not poll Wayland outputs.\n" + + " You may still use WlxOverlay in single-screen mode.\n" + + " Select your screen which is positioned at 0,0."); + + var output = new WaylandOutput(0, null) { Name = "Default" }; + var data = await XdgScreenCastHandler.PromptUserAsync(output); + if (data != null) + { + output.RecalculateTransform(); + var screen = new DesktopOverlay(output, new PipeWireCapture(output, data.Value)); + OverlayRegistry.Register(screen); + Console.WriteLine($"{output.Name} -> {data.Value}"); + + } + else + Console.WriteLine($"{output.Name} will not be used."); + } } - else + + private WaylandSubsystem() { - Console.WriteLine(" ERROR Could not poll Wayland outputs.\n" + - " You may still use WlxOverlay in single-screen mode.\n" + - " Select your screen which is positioned at 0,0."); - - var output = new WaylandOutput(0, null) { Name = "Default" }; - var data = await XdgScreenCastHandler.PromptUserAsync(output); - if (data != null) - { - output.RecalculateTransform(); - var screen = new DesktopOverlay(output, new PipeWireCapture(output, data.Value)); - OverlayRegistry.Register(screen); - Console.WriteLine($"{output.Name} -> {data.Value}"); - - } - else - Console.WriteLine($"{output.Name} will not be used."); + _display = WlDisplay.Connect(DisplayName!); + + var reg = _display.GetRegistry(); + + reg.Global += (__, e) => + { + if (e.Interface == WlInterface.WlOutput.Name) + _ = CreateOutputAsync(reg, e); + else if (e.Interface == WlInterface.WlSeat.Name) + _seat = reg.Bind(e.Name, e.Interface, e.Version); + else if (e.Interface == WlInterface.ZxdgOutputManagerV1.Name) + _outputManager = reg.Bind(e.Name, e.Interface, e.Version); + else if (e.Interface == WlInterface.ZwlrExportDmabufManagerV1.Name) + _supportedCaptureMethods.Add(CaptureMethod.WlrDmaBuf); + else if (e.Interface == WlInterface.ZwlrScreencopyManagerV1.Name) + _supportedCaptureMethods.Add(CaptureMethod.WlrScreenCopy); + }; + + reg.GlobalRemove += (_, e) => + { + if (!_outputs.TryGetValue(e.Name, out var output)) + return; + + _outputs.Remove(e.Name); + output.Dispose(); + }; } - } - private WaylandSubsystem() - { - _display = WlDisplay.Connect(DisplayName!); + private async Task CreateOutputAsync(WlRegistry reg, WlRegistry.GlobalEventArgs e) + { + var wlOutput = reg.Bind(e.Name, e.Interface, e.Version); + + while (_outputManager == null) + await Task.Delay(10); + + var obj = new WaylandOutput(e.Name, wlOutput); - var reg = _display.GetRegistry(); + wlOutput.Geometry += obj.SetGeometry; + wlOutput.Mode += obj.SetMode; + + using var xdgOutput = _outputManager.GetXdgOutput(wlOutput); + xdgOutput.Name += obj.SetName; + xdgOutput.LogicalSize += obj.SetSize; + xdgOutput.LogicalPosition += obj.SetPosition; + _display.Roundtrip(); + + _outputs.Add(e.Name, obj); + obj.RecalculateTransform(); + } - reg.Global += (__, e) => + public void Dispose() { - if (e.Interface == WlInterface.WlOutput.Name) - _ = CreateOutputAsync(reg, e); - else if (e.Interface == WlInterface.WlSeat.Name) - _seat = reg.Bind(e.Name, e.Interface, e.Version); - else if (e.Interface == WlInterface.ZxdgOutputManagerV1.Name) - _outputManager = reg.Bind(e.Name, e.Interface, e.Version); - else if (e.Interface == WlInterface.ZwlrExportDmabufManagerV1.Name) - _supportedCaptureMethods.Add(CaptureMethod.WlrDmaBuf); - else if (e.Interface == WlInterface.ZwlrScreencopyManagerV1.Name) - _supportedCaptureMethods.Add(CaptureMethod.WlrScreenCopy); - }; - - reg.GlobalRemove += (_, e) => + Thread.Sleep(5); + + foreach (var output in _outputs.Values) + output.Dispose(); + + _seat?.Dispose(); + _outputManager?.Dispose(); + _display.Dispose(); + } + + private enum CaptureMethod { - if (!_outputs.TryGetValue(e.Name, out var output)) - return; - - _outputs.Remove(e.Name); - output.Dispose(); - }; - } - - private async Task CreateOutputAsync(WlRegistry reg, WlRegistry.GlobalEventArgs e) - { - var wlOutput = reg.Bind(e.Name, e.Interface, e.Version); - - while (_outputManager == null) - await Task.Delay(10); - - var obj = new WaylandOutput(e.Name, wlOutput); - - wlOutput.Geometry += obj.SetGeometry; - wlOutput.Mode += obj.SetMode; - - using var xdgOutput = _outputManager.GetXdgOutput(wlOutput); - xdgOutput.Name += obj.SetName; - xdgOutput.LogicalSize += obj.SetSize; - xdgOutput.LogicalPosition += obj.SetPosition; - _display.Roundtrip(); - - _outputs.Add(e.Name, obj); - obj.RecalculateTransform(); - } - - public void Dispose() - { - Thread.Sleep(5); - - foreach (var output in _outputs.Values) - output.Dispose(); - - _seat?.Dispose(); - _outputManager?.Dispose(); - _display.Dispose(); - } - - private enum CaptureMethod - { - PipeWire, - WlrDmaBuf, - WlrScreenCopy - } + PipeWire, + WlrDmaBuf, + WlrScreenCopy + } } diff --git a/Desktop/Wayland/XdgScreenCastHandler.cs b/Desktop/Wayland/XdgScreenCastHandler.cs index f7971cc..e994dfd 100644 --- a/Desktop/Wayland/XdgScreenCastHandler.cs +++ b/Desktop/Wayland/XdgScreenCastHandler.cs @@ -8,298 +8,298 @@ namespace WlxOverlay.Desktop.Wayland; internal static class XdgScreenCastHandler { - public static async Task PromptUserAsync(WaylandOutput output) - { - var data = new XdgScreenData(output); - if (await data.InitDbusAsync()) - return data.NodeId; - return null; - } + public static async Task PromptUserAsync(WaylandOutput output) + { + var data = new XdgScreenData(output); + if (await data.InitDbusAsync()) + return data.NodeId; + return null; + } } internal class XdgScreenData : IDisposable { - internal uint NodeId; - private WaylandOutput _output; - - private Connection _dbus = null!; - private DesktopService _service = null!; - private ScreenCast _screenCast = null!; - - private readonly string _token; - private string? _requestPath; - private string? _sessionPath; - - public XdgScreenData(WaylandOutput output) - { - _output = output; - _token = $"xdg_screen_{output.IdName}"; - } - - private Process? ShowNotification() - { - Console.WriteLine($"Select the following screen: {_output.Model} @ {_output.Name}"); - try + internal uint NodeId; + private WaylandOutput _output; + + private Connection _dbus = null!; + private DesktopService _service = null!; + private ScreenCast _screenCast = null!; + + private readonly string _token; + private string? _requestPath; + private string? _sessionPath; + + public XdgScreenData(WaylandOutput output) { - var psi = new ProcessStartInfo("notify-send") - { - ArgumentList = { "-u", "critical", "-t", "120000", "-w", "WlxOverlay", $"Now select: {_output.Model} @ {_output.Name}" } - }; - return Process.Start(psi); + _output = output; + _token = $"xdg_screen_{output.IdName}"; + } + private Process? ShowNotification() + { + Console.WriteLine($"Select the following screen: {_output.Model} @ {_output.Name}"); + try + { + var psi = new ProcessStartInfo("notify-send") + { + ArgumentList = { "-u", "critical", "-t", "120000", "-w", "WlxOverlay", $"Now select: {_output.Model} @ {_output.Name}" } + }; + return Process.Start(psi); + + } + catch (Exception e) + { + Console.WriteLine($"ERR Could not notify user: {e.Message}"); + return null; + } } - catch (Exception e) + + private void HideNotification(Process? p) { - Console.WriteLine($"ERR Could not notify user: {e.Message}"); - return null; + if (p == null) return; + LibC.kill(p.Id, 2); + p.Close(); + p.Dispose(); } - } - private void HideNotification(Process? p) - { - if (p == null) return; - LibC.kill(p.Id, 2); - p.Close(); - p.Dispose(); - } + public async Task InitDbusAsync() + { + _dbus = new Connection(Address.Session!); + await _dbus.ConnectAsync(); - public async Task InitDbusAsync() - { - _dbus = new Connection(Address.Session!); - await _dbus.ConnectAsync(); + var myName = _dbus.UniqueName![1..].Replace(".", "_"); + _requestPath = $"/org/freedesktop/portal/desktop/request/{myName}/{_token}"; - var myName = _dbus.UniqueName![1..].Replace(".", "_"); - _requestPath = $"/org/freedesktop/portal/desktop/request/{myName}/{_token}"; + _service = new DesktopService(_dbus, "org.freedesktop.portal.Desktop"); + _screenCast = _service.CreateScreenCast("/org/freedesktop/portal/desktop"); - _service = new DesktopService(_dbus, "org.freedesktop.portal.Desktop"); - _screenCast = _service.CreateScreenCast("/org/freedesktop/portal/desktop"); + if (await CreateSessionAsync() && await SelectSourcesAsync() && await StartCaptureAsync()) + { + _output.RecalculateTransform(); + return true; + } - if (await CreateSessionAsync() && await SelectSourcesAsync() && await StartCaptureAsync()) - { - _output.RecalculateTransform(); - return true; + Dispose(); + return false; } - Dispose(); - return false; - } - - private async Task CreateSessionAsync() - { - var options = new Dictionary + private async Task CreateSessionAsync() { - ["handle_token"] = _token, - ["session_handle_token"] = _token, - }; - - var state = 0L; - var watcher = await _screenCast.WatchSignalAsync("org.freedesktop.portal.Desktop", - "org.freedesktop.portal.Request", _requestPath!, "Response", - (m, _) => - { - var r = m.GetBodyReader(); - return new ScreenCastResponse - { - Response = r.ReadUInt32(), - Results = r.ReadDictionary() - }; - }, - (e, t) => + var options = new Dictionary { - if (Interlocked.CompareExchange(ref state, -1, 0) != 0) - return; - - if (e != null) - { - Console.WriteLine($"ERR Could not create ScreenCast session: {e.Message}"); - Interlocked.Exchange(ref state, 2); - return; - } - - if (t.Response != 0) - { - Console.WriteLine($"ERR Could not create ScreenCast session: {t.Response}"); - Interlocked.Exchange(ref state, 2); - return; - } - - _sessionPath = t.Results["session_handle"] as string ?? - throw new Exception("Invalid session_handle"); - Interlocked.Exchange(ref state, 1); - }, - false); - - await _screenCast.CreateSessionAsync(options); - - long val; - while ((val = Interlocked.Read(ref state)) <= 0) - await Task.Delay(100); - watcher.Dispose(); - return val == 1; - } - - private async Task SelectSourcesAsync() - { - var options = new Dictionary + ["handle_token"] = _token, + ["session_handle_token"] = _token, + }; + + var state = 0L; + var watcher = await _screenCast.WatchSignalAsync("org.freedesktop.portal.Desktop", + "org.freedesktop.portal.Request", _requestPath!, "Response", + (m, _) => + { + var r = m.GetBodyReader(); + return new ScreenCastResponse + { + Response = r.ReadUInt32(), + Results = r.ReadDictionary() + }; + }, + (e, t) => + { + if (Interlocked.CompareExchange(ref state, -1, 0) != 0) + return; + + if (e != null) + { + Console.WriteLine($"ERR Could not create ScreenCast session: {e.Message}"); + Interlocked.Exchange(ref state, 2); + return; + } + + if (t.Response != 0) + { + Console.WriteLine($"ERR Could not create ScreenCast session: {t.Response}"); + Interlocked.Exchange(ref state, 2); + return; + } + + _sessionPath = t.Results["session_handle"] as string ?? + throw new Exception("Invalid session_handle"); + Interlocked.Exchange(ref state, 1); + }, + false); + + await _screenCast.CreateSessionAsync(options); + + long val; + while ((val = Interlocked.Read(ref state)) <= 0) + await Task.Delay(100); + watcher.Dispose(); + return val == 1; + } + + private async Task SelectSourcesAsync() { - ["handle_token"] = _token, - ["type"] = 1U, - ["cursor_mode"] = 2U, // embedded - ["persist_mode"] = 2U, // persistent - }; - - if (Config.TryGetFile($"screen-{_output.Name}.token", out var file)) - options.Add("restore_token", (await File.ReadAllLinesAsync(file))[0]); - - var state = 0L; - var watcher = await _screenCast.WatchSignalAsync("org.freedesktop.portal.Desktop", - "org.freedesktop.portal.Request", _requestPath!, "Response", - (m, _) => + var options = new Dictionary { - var r = m.GetBodyReader(); - return new ScreenCastResponse - { - Response = r.ReadUInt32(), - Results = r.ReadDictionary() - }; - }, - (e, t) => + ["handle_token"] = _token, + ["type"] = 1U, + ["cursor_mode"] = 2U, // embedded + ["persist_mode"] = 2U, // persistent + }; + + if (Config.TryGetFile($"screen-{_output.Name}.token", out var file)) + options.Add("restore_token", (await File.ReadAllLinesAsync(file))[0]); + + var state = 0L; + var watcher = await _screenCast.WatchSignalAsync("org.freedesktop.portal.Desktop", + "org.freedesktop.portal.Request", _requestPath!, "Response", + (m, _) => + { + var r = m.GetBodyReader(); + return new ScreenCastResponse + { + Response = r.ReadUInt32(), + Results = r.ReadDictionary() + }; + }, + (e, t) => + { + if (Interlocked.CompareExchange(ref state, -1, 0) != 0) + return; + + if (e != null) + { + Console.WriteLine($"ERR Could not create ScreenCast session: {e.Message}"); + Interlocked.Exchange(ref state, 2); + return; + } + if (t.Response != 0) + { + if (t.Response != 1) + Console.WriteLine($"ERR Could not select ScreenCast source: {t.Response}"); + else + Console.WriteLine($"Screen selection cancelled by user"); + Interlocked.Exchange(ref state, 2); + return; + } + + Interlocked.Exchange(ref state, 1); + }, + false); + + await _screenCast.SelectSourcesAsync(_sessionPath!, options); + + long val; + var waited = 0; + var notified = false; + Process? p = null; + while ((val = Interlocked.Read(ref state)) <= 0) { - if (Interlocked.CompareExchange(ref state, -1, 0) != 0) - return; - - if (e != null) - { - Console.WriteLine($"ERR Could not create ScreenCast session: {e.Message}"); - Interlocked.Exchange(ref state, 2); - return; - } - if (t.Response != 0) - { - if (t.Response != 1) - Console.WriteLine($"ERR Could not select ScreenCast source: {t.Response}"); - else - Console.WriteLine($"Screen selection cancelled by user"); - Interlocked.Exchange(ref state, 2); - return; - } - - Interlocked.Exchange(ref state, 1); - }, - false); - - await _screenCast.SelectSourcesAsync(_sessionPath!, options); - - long val; - var waited = 0; - var notified = false; - Process? p = null; - while ((val = Interlocked.Read(ref state)) <= 0) + await Task.Delay(100); + if (waited++ > 2 && !notified) + { + p = ShowNotification(); + notified = true; + } + } + HideNotification(p); + watcher.Dispose(); + return val == 1; + } + + private async Task StartCaptureAsync() { - await Task.Delay(100); - if (waited++ > 2 && !notified) - { - p = ShowNotification(); - notified = true; - } + var options = new Dictionary + { + ["handle_token"] = _token, + }; + + var state = 0L; + var watcher = await _screenCast.WatchSignalAsync("org.freedesktop.portal.Desktop", + "org.freedesktop.portal.Request", _requestPath!, "Response", + (m, _) => + { + var r = m.GetBodyReader(); + var response = new ScreenCastResponse + { + Response = r.ReadUInt32(), + Results = r.ReadDictionary() + }; + + return response; + }, + (e, t) => + { + if (Interlocked.CompareExchange(ref state, -1, 0) != 0) + return; + + if (e != null) + { + Console.WriteLine($"ERR Could not Start ScreenCast session: {e.Message}"); + Interlocked.Exchange(ref state, 2); + return; + } + if (t.Response != 0) + { + if (t.Response != 1) + Console.WriteLine($"ERR Could not Start ScreenCast source: {t.Response}"); + else + Console.WriteLine($"Screen capture cancelled by user"); + Interlocked.Exchange(ref state, 2); + return; + } + + if (!t.Results.TryGetValue("streams", out var maybeStreams) + || !(maybeStreams is ValueTuple>[] streams)) + { + Console.WriteLine($"ERR Could not Start ScreenCast source: Unexpected response"); + Interlocked.Exchange(ref state, 2); + return; + } + + if (t.Results.TryGetValue("restore_token", out var maybeRestoreToken) + && maybeRestoreToken is string restoreToken) + { + if (!Directory.Exists(Config.UserConfigFolder)) + Directory.CreateDirectory(Config.UserConfigFolder); + + var path = Path.Combine(Config.UserConfigFolder, $"screen-{_output.Name}.token"); + File.WriteAllText(path, restoreToken); + } + + if (streams[0].Item2.TryGetValue("size", out var maybeSize) + && maybeSize is ValueTuple size) + _output.Size = new Vector2Int(size.Item1, size.Item2); + else + { + Console.WriteLine($"ERR Could not Start ScreenCast source: Unexpected format: size"); + Interlocked.Exchange(ref state, 2); + return; + } + + NodeId = streams[0].Item1; + Interlocked.Exchange(ref state, 1); + }, + false); + + await _screenCast.StartAsync(_sessionPath!, "", options); + + long val; + while ((val = Interlocked.Read(ref state)) <= 0) + await Task.Delay(100); + watcher.Dispose(); + return val == 1; } - HideNotification(p); - watcher.Dispose(); - return val == 1; - } - - private async Task StartCaptureAsync() - { - var options = new Dictionary + + private struct ScreenCastResponse { - ["handle_token"] = _token, - }; + public uint Response; // 0: success, 1: user cancelled, 2: failed + public Dictionary Results; + } - var state = 0L; - var watcher = await _screenCast.WatchSignalAsync("org.freedesktop.portal.Desktop", - "org.freedesktop.portal.Request", _requestPath!, "Response", - (m, _) => - { - var r = m.GetBodyReader(); - var response = new ScreenCastResponse - { - Response = r.ReadUInt32(), - Results = r.ReadDictionary() - }; - - return response; - }, - (e, t) => - { - if (Interlocked.CompareExchange(ref state, -1, 0) != 0) - return; - - if (e != null) - { - Console.WriteLine($"ERR Could not Start ScreenCast session: {e.Message}"); - Interlocked.Exchange(ref state, 2); - return; - } - if (t.Response != 0) - { - if (t.Response != 1) - Console.WriteLine($"ERR Could not Start ScreenCast source: {t.Response}"); - else - Console.WriteLine($"Screen capture cancelled by user"); - Interlocked.Exchange(ref state, 2); - return; - } - - if (!t.Results.TryGetValue("streams", out var maybeStreams) - || !(maybeStreams is ValueTuple>[] streams)) - { - Console.WriteLine($"ERR Could not Start ScreenCast source: Unexpected response"); - Interlocked.Exchange(ref state, 2); - return; - } - - if (t.Results.TryGetValue("restore_token", out var maybeRestoreToken) - && maybeRestoreToken is string restoreToken) - { - if (!Directory.Exists(Config.UserConfigFolder)) - Directory.CreateDirectory(Config.UserConfigFolder); - - var path = Path.Combine(Config.UserConfigFolder, $"screen-{_output.Name}.token"); - File.WriteAllText(path, restoreToken); - } - - if (streams[0].Item2.TryGetValue("size", out var maybeSize) - && maybeSize is ValueTuple size) - _output.Size = new Vector2Int(size.Item1, size.Item2); - else - { - Console.WriteLine($"ERR Could not Start ScreenCast source: Unexpected format: size"); - Interlocked.Exchange(ref state, 2); - return; - } - - NodeId = streams[0].Item1; - Interlocked.Exchange(ref state, 1); - }, - false); - - await _screenCast.StartAsync(_sessionPath!, "", options); - - long val; - while ((val = Interlocked.Read(ref state)) <= 0) - await Task.Delay(100); - watcher.Dispose(); - return val == 1; - } - - private struct ScreenCastResponse - { - public uint Response; // 0: success, 1: user cancelled, 2: failed - public Dictionary Results; - } - - public void Dispose() - { - _dbus.Dispose(); - } + public void Dispose() + { + _dbus.Dispose(); + } } diff --git a/Input/KeyboardLayout.cs b/Input/KeyboardLayout.cs index d457538..90a68da 100644 --- a/Input/KeyboardLayout.cs +++ b/Input/KeyboardLayout.cs @@ -72,7 +72,8 @@ public static bool Load() public string[] LabelForKey(string key, bool shift = false) { - if (Labels.TryGetValue(key, out var label)) { + if (Labels.TryGetValue(key, out var label)) + { if (label != null && label.Length > 2) return shift ? label[2..] : label[0..1]; return label!; diff --git a/Overlays/Watch.cs b/Overlays/Watch.cs index ba731d9..8e50c60 100644 --- a/Overlays/Watch.cs +++ b/Overlays/Watch.cs @@ -36,9 +36,9 @@ public Watch(BaseOverlay keyboard) : base("Watch") var relative_pos = Config.Instance.WatchPosition ?? new[] { -0.05f, -0.05f, 0.15f }; if (relative_pos.Length != 3) throw new InvalidOperationException("watch_position must be an array of 3 floats!"); - + Vec3RelToHand = new Vector3(relative_pos[0], relative_pos[1], relative_pos[2]); - + Hand = Config.Instance.WatchHand; if (Config.Instance.WatchHand == LeftRight.Right) { diff --git a/Program.cs b/Program.cs index a34da48..31a8497 100644 --- a/Program.cs +++ b/Program.cs @@ -11,40 +11,40 @@ var version = "unknown-version"; try { - version = File.ReadAllText(Path.Combine(Config.AppDir, "Resources", "version.txt")).Trim(); + version = File.ReadAllText(Path.Combine(Config.AppDir, "Resources", "version.txt")).Trim(); } catch { /* */ } Console.WriteLine($"WlxOverlay {version}"); if (!Config.Load()) - return; + return; if (Config.Instance.OverrideEnv != null) - foreach (var pair in Config.Instance.OverrideEnv) - Environment.SetEnvironmentVariable(pair.Key, pair.Value); + foreach (var pair in Config.Instance.OverrideEnv) + Environment.SetEnvironmentVariable(pair.Key, pair.Value); Session.Initialize(); if (args.Contains("--xr")) - XrBackend.UseOpenXR(); + XrBackend.UseOpenXR(); else - XrBackend.UseOpenVR(); + XrBackend.UseOpenVR(); try { - InputProvider.UseUInput(); + InputProvider.UseUInput(); } catch (Exception) { - InputProvider.UseDummy(); + InputProvider.UseDummy(); } void SignalHandler(PosixSignalContext context) { - context.Cancel = true; - Console.WriteLine($"Received signal {context.Signal}. Exiting..."); - MainLoop.Shutdown(); + context.Cancel = true; + Console.WriteLine($"Received signal {context.Signal}. Exiting..."); + MainLoop.Shutdown(); } PosixSignalRegistration.Create(PosixSignal.SIGINT, SignalHandler); @@ -52,15 +52,15 @@ void SignalHandler(PosixSignalContext context) PosixSignalRegistration.Create(PosixSignal.SIGTERM, SignalHandler); if (Config.Instance.LeftUsePtt) - PttHandler.Add(LeftRight.Left); + PttHandler.Add(LeftRight.Left); if (Config.Instance.RightUsePtt) - PttHandler.Add(LeftRight.Right); + PttHandler.Add(LeftRight.Right); if (!KeyboardLayout.Load()) { - Console.WriteLine("[Fatal] Keyboard layout is invalid."); - Environment.Exit(1); + Console.WriteLine("[Fatal] Keyboard layout is invalid."); + Environment.Exit(1); } var keyboard = new KeyboardOverlay(); @@ -68,19 +68,19 @@ void SignalHandler(PosixSignalContext context) if (WaylandSubsystem.TryInitialize(out var wayland)) { - MainLoop.AddSubsystem(wayland); - await wayland.CreateScreensAsync(); + MainLoop.AddSubsystem(wayland); + await wayland.CreateScreensAsync(); } else if (XshmSubsystem.TryInitialize(out var xshm)) { - MainLoop.AddSubsystem(xshm); - xshm.CreateScreens(); + MainLoop.AddSubsystem(xshm); + xshm.CreateScreens(); } AudioManager.Initialize(); if (!string.IsNullOrWhiteSpace(Config.Instance.NotificationsEndpoint)) - NotificationsManager.Initialize(); + NotificationsManager.Initialize(); var watch = new Watch(keyboard); OverlayRegistry.Register(watch);