using System.Diagnostics; using Toak.Core; using Toak.Core.Interfaces; namespace Toak.IO.Injectors; /// /// Text injector that uses ydotool to type text via virtual input (works on both X11 and Wayland). /// public class YdotoolTextInjector(INotifications notifications) : ITextInjector { private readonly INotifications _notifications = notifications; public Task InjectTextAsync(string text) { Logger.LogDebug("Injecting text using ydotool..."); if (string.IsNullOrWhiteSpace(text)) return Task.CompletedTask; try { var pInfo = new ProcessStartInfo { FileName = Constants.Commands.TypeYdotool, Arguments = $"type \"{text.Replace("\"", "\\\"")}\"", UseShellExecute = false, CreateNoWindow = true }; var p = Process.Start(pInfo); p?.WaitForExit(); } catch (Exception ex) { Console.WriteLine($"[YdotoolTextInjector] Error injecting text: {ex.Message}"); _notifications.Notify("Injection Error", "Could not type text into window."); } return Task.CompletedTask; } public async Task InjectStreamAsync(IAsyncEnumerable tokenStream) { Logger.LogDebug("Setting up stream injection using ydotool (chunked)..."); var fullText = string.Empty; try { await foreach (var token in tokenStream) { Logger.LogDebug($"Injecting token: '{token}'"); fullText += token; var chunkInfo = new ProcessStartInfo { FileName = Constants.Commands.TypeYdotool, Arguments = $"type \"{token.Replace("\"", "\\\"")}\"", UseShellExecute = false, CreateNoWindow = true }; var chunkP = Process.Start(chunkInfo); if (chunkP != null) await chunkP.WaitForExitAsync(); } } catch (Exception ex) { Console.WriteLine($"[YdotoolTextInjector] Error injecting text stream: {ex.Message}"); _notifications.Notify("Injection Error", "Could not type text stream into window."); } return fullText; } }