-
-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix paste performance issue on windows and linux #249
base: main
Are you sure you want to change the base?
Changes from 27 commits
532a5af
037a737
714e610
2195755
86160a4
3061ac5
0e92466
b355734
b18075f
3784019
d1dc7b9
e403559
da7b7a9
a85aef0
988380b
2090e28
bb01b75
690143f
3e7f3ef
a3c37eb
a0de64a
56c8c1c
2d23c1e
407dc9d
b6237cd
ce09026
b0fe142
e2d8827
55e5c7d
b1e1ff2
a157136
40cc7ec
8aecf8e
6188132
f953816
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
using System; | ||
using System.Threading.Tasks; | ||
using Avalonia.Input; | ||
using Avalonia.Input.Platform; | ||
|
||
namespace Consolonia.Core.Infrastructure | ||
{ | ||
/// <summary> | ||
/// This clipboard only stores memory in the same process, so it is not useful for sharing data between processes. | ||
/// </summary> | ||
public class NaiveClipboard : IClipboard | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. typo? |
||
{ | ||
private string _text = String.Empty; | ||
|
||
#pragma warning disable CA1822 // Mark members as static | ||
public async Task ClearAsync() | ||
{ | ||
await Task.CompletedTask; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can be replaced by |
||
_text = String.Empty; | ||
} | ||
|
||
public Task<object> GetDataAsync(string format) | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
|
||
public Task<string[]> GetFormatsAsync() | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
|
||
public async Task<string> GetTextAsync() | ||
{ | ||
await Task.CompletedTask; | ||
return _text; | ||
} | ||
|
||
public Task SetDataObjectAsync(IDataObject data) | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
tomlm marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
public async Task SetTextAsync(string text) | ||
{ | ||
await Task.CompletedTask; | ||
_text = text; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,18 +42,21 @@ public CONSOLE_INPUT_MODE ConsoleMode | |
} | ||
} | ||
|
||
const int bufferSize = 0xffff; | ||
private static INPUT_RECORD[] s_inputBuffer = new INPUT_RECORD[bufferSize]; | ||
|
||
public INPUT_RECORD[] ReadConsoleInput() | ||
{ | ||
const int bufferSize = 1; | ||
var records = new INPUT_RECORD[bufferSize]; | ||
|
||
if (!Kernel32.ReadConsoleInput(InputHandle, records, bufferSize, | ||
out var numberEventsRead)) | ||
throw GetLastError().GetException(); | ||
lock (s_inputBuffer) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like we can assume ReadConsoleInput can be not thread-safe |
||
{ | ||
|
||
return numberEventsRead == 0 | ||
? Array.Empty<INPUT_RECORD>() | ||
: records; | ||
if (!Kernel32.ReadConsoleInput(InputHandle, s_inputBuffer, bufferSize, | ||
out var numberEventsRead)) | ||
throw GetLastError().GetException(); | ||
INPUT_RECORD[] recordsToReturn = new INPUT_RECORD[numberEventsRead]; | ||
Array.Copy(s_inputBuffer, recordsToReturn, numberEventsRead); | ||
return recordsToReturn; | ||
} | ||
tomlm marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace Consolonia.PlatformSupport.Clipboard | ||
{ | ||
/// <summary> | ||
/// Helper class for console drivers to invoke shell commands to interact with the clipboard. | ||
/// </summary> | ||
internal static class ClipboardProcessRunner | ||
{ | ||
public static (int exitCode, string result) Bash( | ||
string commandLine, | ||
string inputText = "", | ||
bool waitForOutput = false | ||
) | ||
{ | ||
var arguments = $"-c \"{commandLine}\""; | ||
(int exitCode, string result) = Process("bash", arguments, inputText, waitForOutput); | ||
|
||
return (exitCode, result.TrimEnd()); | ||
} | ||
tomlm marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
public static bool DoubleWaitForExit(this Process process) | ||
{ | ||
bool result = process.WaitForExit(500); | ||
|
||
if (result) | ||
{ | ||
process.WaitForExit(); | ||
} | ||
|
||
return result; | ||
} | ||
|
||
public static bool FileExists(this string value) { return !string.IsNullOrEmpty(value) && !value.Contains("not found", StringComparison.Ordinal); } | ||
tomlm marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
public static (int exitCode, string result) Process( | ||
string cmd, | ||
string arguments, | ||
string input = null, | ||
bool waitForOutput = true | ||
) | ||
{ | ||
var output = string.Empty; | ||
|
||
using (var process = new Process | ||
{ | ||
StartInfo = new() | ||
{ | ||
FileName = cmd, | ||
Arguments = arguments, | ||
RedirectStandardOutput = true, | ||
RedirectStandardError = true, | ||
RedirectStandardInput = true, | ||
UseShellExecute = false, | ||
CreateNoWindow = true | ||
} | ||
Check warning on line 61 in src/Consolonia.PlatformSupport/Clipboard/ClipboardProcessRunner.cs GitHub Actions / build
|
||
}) | ||
{ | ||
TaskCompletionSource<bool> eventHandled = new(); | ||
process.Start(); | ||
|
||
if (!string.IsNullOrEmpty(input)) | ||
{ | ||
process.StandardInput.Write(input); | ||
process.StandardInput.Close(); | ||
} | ||
|
||
if (!process.WaitForExit(5000)) | ||
{ | ||
var timeoutError = | ||
$@"Process timed out. Command line: {process.StartInfo.FileName} {process.StartInfo.Arguments}."; | ||
|
||
throw new TimeoutException(timeoutError); | ||
} | ||
|
||
if (waitForOutput && process.StandardOutput.Peek() != -1) | ||
{ | ||
output = process.StandardOutput.ReadToEnd(); | ||
} | ||
|
||
if (process.ExitCode > 0) | ||
{ | ||
output = $@"Process failed to run. Command line: {cmd} {arguments}. | ||
Output: {output} | ||
Error: {process.StandardError.ReadToEnd()}"; | ||
} | ||
|
||
return (process.ExitCode, output); | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do we use from skia?