114 lines
3.9 KiB
C#
114 lines
3.9 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 Shift+Insert via <c>wtype</c>.
|
|
/// Whitespace-only content is typed directly with <c>wtype</c> to avoid
|
|
/// wl-copy silently stripping leading/trailing spaces from clipboard content.
|
|
/// </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 Shift+Insert to paste into the focused window
|
|
var pasteInfo = new ProcessStartInfo
|
|
{
|
|
FileName = Constants.Commands.TypeWayland,
|
|
Arguments = "-M shift -k Insert -m shift",
|
|
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 Shift+Insert to paste into the focused window
|
|
var pasteInfo = new ProcessStartInfo
|
|
{
|
|
FileName = Constants.Commands.TypeWayland,
|
|
Arguments = "-M shift -k Insert -m shift",
|
|
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;
|
|
}
|
|
}
|