1
0
Files
Toak/IO/Injectors/WlClipboardTextInjector.cs

112 lines
3.8 KiB
C#

using System.Diagnostics;
using Toak.Core;
using Toak.Core.Interfaces;
namespace Toak.IO.Injectors;
/// <summary>
/// Text injector that writes text to the Wayland clipboard via <c>wl-copy</c>
/// and then pastes it using Ctrl+V via <c>wtype</c>.
/// </summary>
public class WlClipboardTextInjector(INotifications notifications) : ITextInjector
{
private readonly INotifications _notifications = notifications;
public Task InjectTextAsync(string text)
{
Logger.LogDebug("Injecting text using wl-clipboard...");
if (string.IsNullOrWhiteSpace(text)) return Task.CompletedTask;
try
{
// Write the full text to wl-copy via stdin
var copyInfo = new ProcessStartInfo
{
FileName = Constants.Commands.ClipboardWayland,
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardInput = true
};
using var copyProcess = Process.Start(copyInfo);
if (copyProcess != null)
{
copyProcess.StandardInput.Write(text);
copyProcess.StandardInput.Close();
copyProcess.WaitForExit();
}
Task.Delay(100).Wait();
// Simulate Ctrl+V to paste into the focused window
var pasteInfo = new ProcessStartInfo
{
FileName = Constants.Commands.TypeWayland,
Arguments = "-M ctrl -k v -m ctrl",
UseShellExecute = false,
CreateNoWindow = true
};
var pasteProcess = Process.Start(pasteInfo);
pasteProcess?.WaitForExit();
}
catch (Exception ex)
{
Console.WriteLine($"[WlClipboardTextInjector] 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)
{
Logger.LogDebug("Setting up stream injection using wl-clipboard...");
var fullText = string.Empty;
try
{
// Collect all tokens first
await foreach (var token in tokenStream)
{
Logger.LogDebug($"Buffering token: '{token}'");
fullText += token;
}
// Write the full text to wl-copy via stdin
var copyInfo = new ProcessStartInfo
{
FileName = Constants.Commands.ClipboardWayland,
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardInput = true
};
using var copyProcess = Process.Start(copyInfo);
if (copyProcess != null)
{
await copyProcess.StandardInput.WriteAsync(fullText);
copyProcess.StandardInput.Close();
await copyProcess.WaitForExitAsync();
}
await Task.Delay(100);
// Simulate Ctrl+V to paste into the focused window
var pasteInfo = new ProcessStartInfo
{
FileName = Constants.Commands.TypeWayland,
Arguments = "-M ctrl -k v -m ctrl",
UseShellExecute = false,
CreateNoWindow = true
};
using var pasteProcess = Process.Start(pasteInfo);
if (pasteProcess != null) await pasteProcess.WaitForExitAsync();
}
catch (Exception ex)
{
Console.WriteLine($"[WlClipboardTextInjector] Error injecting text stream: {ex.Message}");
_notifications.Notify("Injection Error", "Could not type text stream into window.");
}
return fullText;
}
}