138 lines
5.3 KiB
C#
138 lines
5.3 KiB
C#
using System.Diagnostics;
|
|
using Toak.Core;
|
|
using Toak.Core.Interfaces;
|
|
|
|
namespace Toak.IO;
|
|
|
|
public class TextInjector(INotifications notifications) : ITextInjector
|
|
{
|
|
private readonly INotifications _notifications = notifications;
|
|
|
|
public Task InjectTextAsync(string text, string backend = "xdotool")
|
|
{
|
|
Logger.LogDebug($"Injecting text: '{text}' with {backend}");
|
|
if (string.IsNullOrWhiteSpace(text)) return Task.CompletedTask;
|
|
|
|
try
|
|
{
|
|
ProcessStartInfo pInfo;
|
|
if (backend.ToLowerInvariant() == "wtype")
|
|
{
|
|
Logger.LogDebug($"Injecting text using wtype...");
|
|
pInfo = new ProcessStartInfo
|
|
{
|
|
FileName = Constants.Commands.TypeWayland,
|
|
Arguments = $"-d {Constants.Defaults.DefaultTypeDelayMs} \"{text.Replace("\"", "\\\"")}\"",
|
|
UseShellExecute = false,
|
|
CreateNoWindow = true
|
|
};
|
|
}
|
|
else if (backend.ToLowerInvariant() == "ydotool")
|
|
{
|
|
Logger.LogDebug($"Injecting text using ydotool...");
|
|
pInfo = new ProcessStartInfo
|
|
{
|
|
FileName = Constants.Commands.TypeYdotool,
|
|
Arguments = $"type \"{text.Replace("\"", "\\\"")}\"",
|
|
UseShellExecute = false,
|
|
CreateNoWindow = true
|
|
};
|
|
}
|
|
else // xdotool
|
|
{
|
|
Logger.LogDebug($"Injecting text using xdotool...");
|
|
pInfo = new ProcessStartInfo
|
|
{
|
|
FileName = Constants.Commands.TypeX11,
|
|
Arguments = $"type --clearmodifiers --delay {Constants.Defaults.DefaultTypeDelayMs} \"{text.Replace("\"", "\\\"")}\"",
|
|
UseShellExecute = false,
|
|
CreateNoWindow = true
|
|
};
|
|
}
|
|
var process = Process.Start(pInfo);
|
|
process?.WaitForExit();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"[TextInjector] Error injecting text: {ex.Message}");
|
|
_notifications.Notify("Injection Error", "Could not type text into window.");
|
|
}
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public async Task<string> InjectStreamAsync(IAsyncEnumerable<string> tokenStream, string backend)
|
|
{
|
|
var fullText = string.Empty;
|
|
try
|
|
{
|
|
ProcessStartInfo pInfo;
|
|
if (backend.ToLowerInvariant() == "wtype")
|
|
{
|
|
Logger.LogDebug($"Setting up stream injection using wtype...");
|
|
pInfo = new ProcessStartInfo
|
|
{
|
|
FileName = Constants.Commands.TypeWayland,
|
|
Arguments = $"-d {Constants.Defaults.DefaultTypeDelayMs} -",
|
|
UseShellExecute = false,
|
|
CreateNoWindow = true,
|
|
RedirectStandardInput = true
|
|
};
|
|
}
|
|
else if (backend.ToLowerInvariant() == "ydotool")
|
|
{
|
|
Logger.LogDebug($"Setting up stream injection using ydotool (chunked)...");
|
|
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();
|
|
}
|
|
return fullText;
|
|
}
|
|
else // xdotool
|
|
{
|
|
Logger.LogDebug($"Setting up stream injection using xdotool...");
|
|
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 stream injection 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($"[TextInjector] Error injecting text stream: {ex.Message}");
|
|
_notifications.Notify("Injection Error", "Could not type text stream into window.");
|
|
}
|
|
return fullText;
|
|
}
|
|
}
|