using System.Diagnostics; using Toak.Core; using Toak.Core.Interfaces; namespace Toak.IO.Injectors; /// /// Text injector that uses xdotool to type text on X11. /// public class XdotoolTextInjector(INotifications notifications) : ITextInjector { private readonly INotifications _notifications = notifications; public Task InjectTextAsync(string text) { Logger.LogDebug("Injecting text using xdotool..."); if (string.IsNullOrWhiteSpace(text)) return Task.CompletedTask; try { var pInfo = new ProcessStartInfo { FileName = Constants.Commands.TypeX11, Arguments = $"type --clearmodifiers --delay {Constants.Defaults.DefaultTypeDelayMs} \"{text.Replace("\"", "\\\"")}\"", UseShellExecute = false, CreateNoWindow = true }; var p = Process.Start(pInfo); p?.WaitForExit(); } catch (Exception ex) { Console.WriteLine($"[XdotoolTextInjector] 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 xdotool..."); var fullText = string.Empty; try { var pInfo = new ProcessStartInfo { FileName = Constants.Commands.TypeX11, Arguments = $"type --clearmodifiers --delay {Constants.Defaults.DefaultTypeDelayMs} --file -", UseShellExecute = false, CreateNoWindow = true, RedirectStandardInput = true }; using var process = Process.Start(pInfo); if (process == null) return string.Empty; Logger.LogDebug("Started xdotool stream process, waiting for tokens..."); await foreach (var token in tokenStream) { Logger.LogDebug($"Injecting token: '{token}'"); fullText += token; await process.StandardInput.WriteAsync(token); await process.StandardInput.FlushAsync(); } Logger.LogDebug("Stream injection complete. Closing standard input."); process.StandardInput.Close(); await process.WaitForExitAsync(); } catch (Exception ex) { Console.WriteLine($"[XdotoolTextInjector] Error injecting text stream: {ex.Message}"); _notifications.Notify("Injection Error", "Could not type text stream into window."); } return fullText; } }