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;
}
}