mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-12-25 21:07:20 -08:00
Compare commits
3 commits
a8685f2047
...
85b83990a8
Author | SHA1 | Date | |
---|---|---|---|
|
85b83990a8 | ||
|
acf71a30b8 | ||
|
28c59ee0ab |
9 changed files with 118 additions and 93 deletions
|
@ -40,59 +40,7 @@ namespace SourceGit.Commands
|
||||||
|
|
||||||
public bool Exec()
|
public bool Exec()
|
||||||
{
|
{
|
||||||
var start = new ProcessStartInfo();
|
var start = CreateGitStartInfo();
|
||||||
start.FileName = Native.OS.GitExecutable;
|
|
||||||
start.Arguments = "--no-pager -c core.quotepath=off -c credential.helper=manager ";
|
|
||||||
start.UseShellExecute = false;
|
|
||||||
start.CreateNoWindow = true;
|
|
||||||
start.RedirectStandardOutput = true;
|
|
||||||
start.RedirectStandardError = true;
|
|
||||||
start.StandardOutputEncoding = Encoding.UTF8;
|
|
||||||
start.StandardErrorEncoding = Encoding.UTF8;
|
|
||||||
|
|
||||||
// Force using this app as SSH askpass program
|
|
||||||
var selfExecFile = Process.GetCurrentProcess().MainModule!.FileName;
|
|
||||||
if (!OperatingSystem.IsLinux())
|
|
||||||
start.Environment.Add("DISPLAY", "required");
|
|
||||||
start.Environment.Add("SSH_ASKPASS", selfExecFile); // Can not use parameter here, because it invoked by SSH with `exec`
|
|
||||||
start.Environment.Add("SSH_ASKPASS_REQUIRE", "prefer");
|
|
||||||
start.Environment.Add("SOURCEGIT_LAUNCH_AS_ASKPASS", "TRUE");
|
|
||||||
|
|
||||||
// If an SSH private key was provided, sets the environment.
|
|
||||||
if (!string.IsNullOrEmpty(SSHKey))
|
|
||||||
start.Environment.Add("GIT_SSH_COMMAND", $"ssh -o StrictHostKeyChecking=accept-new -i '{SSHKey}'");
|
|
||||||
else
|
|
||||||
start.Environment.Add("GIT_SSH_COMMAND", $"ssh -o StrictHostKeyChecking=accept-new");
|
|
||||||
|
|
||||||
// Force using en_US.UTF-8 locale to avoid GCM crash
|
|
||||||
if (OperatingSystem.IsLinux())
|
|
||||||
start.Environment.Add("LANG", "en_US.UTF-8");
|
|
||||||
|
|
||||||
// Fix sometimes `LSEnvironment` not working on macOS
|
|
||||||
if (OperatingSystem.IsMacOS())
|
|
||||||
start.Environment.Add("PATH", "/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin");
|
|
||||||
|
|
||||||
// Force using this app as git editor.
|
|
||||||
switch (Editor)
|
|
||||||
{
|
|
||||||
case EditorType.CoreEditor:
|
|
||||||
start.Arguments += $"-c core.editor=\"\\\"{selfExecFile}\\\" --core-editor\" ";
|
|
||||||
break;
|
|
||||||
case EditorType.RebaseEditor:
|
|
||||||
start.Arguments += $"-c core.editor=\"\\\"{selfExecFile}\\\" --rebase-message-editor\" -c sequence.editor=\"\\\"{selfExecFile}\\\" --rebase-todo-editor\" -c rebase.abbreviateCommands=true ";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
start.Arguments += "-c core.editor=true ";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append command args
|
|
||||||
start.Arguments += Args;
|
|
||||||
|
|
||||||
// Working directory
|
|
||||||
if (!string.IsNullOrEmpty(WorkingDirectory))
|
|
||||||
start.WorkingDirectory = WorkingDirectory;
|
|
||||||
|
|
||||||
var errs = new List<string>();
|
var errs = new List<string>();
|
||||||
var proc = new Process() { StartInfo = start };
|
var proc = new Process() { StartInfo = start };
|
||||||
var isCancelled = false;
|
var isCancelled = false;
|
||||||
|
@ -186,20 +134,9 @@ namespace SourceGit.Commands
|
||||||
|
|
||||||
public ReadToEndResult ReadToEnd()
|
public ReadToEndResult ReadToEnd()
|
||||||
{
|
{
|
||||||
var start = new ProcessStartInfo();
|
var start = CreateGitStartInfo();
|
||||||
start.FileName = Native.OS.GitExecutable;
|
|
||||||
start.Arguments = "--no-pager -c core.quotepath=off " + Args;
|
|
||||||
start.UseShellExecute = false;
|
|
||||||
start.CreateNoWindow = true;
|
|
||||||
start.RedirectStandardOutput = true;
|
|
||||||
start.RedirectStandardError = true;
|
|
||||||
start.StandardOutputEncoding = Encoding.UTF8;
|
|
||||||
start.StandardErrorEncoding = Encoding.UTF8;
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(WorkingDirectory))
|
|
||||||
start.WorkingDirectory = WorkingDirectory;
|
|
||||||
|
|
||||||
var proc = new Process() { StartInfo = start };
|
var proc = new Process() { StartInfo = start };
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
proc.Start();
|
proc.Start();
|
||||||
|
@ -227,7 +164,68 @@ namespace SourceGit.Commands
|
||||||
return rs;
|
return rs;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnReadline(string line) { }
|
protected virtual void OnReadline(string line)
|
||||||
|
{
|
||||||
|
// Implemented by derived class
|
||||||
|
}
|
||||||
|
|
||||||
|
private ProcessStartInfo CreateGitStartInfo()
|
||||||
|
{
|
||||||
|
var start = new ProcessStartInfo();
|
||||||
|
start.FileName = Native.OS.GitExecutable;
|
||||||
|
start.Arguments = "--no-pager -c core.quotepath=off -c credential.helper=manager ";
|
||||||
|
start.UseShellExecute = false;
|
||||||
|
start.CreateNoWindow = true;
|
||||||
|
start.RedirectStandardOutput = true;
|
||||||
|
start.RedirectStandardError = true;
|
||||||
|
start.StandardOutputEncoding = Encoding.UTF8;
|
||||||
|
start.StandardErrorEncoding = Encoding.UTF8;
|
||||||
|
|
||||||
|
// Force using this app as SSH askpass program
|
||||||
|
var selfExecFile = Process.GetCurrentProcess().MainModule!.FileName;
|
||||||
|
if (!OperatingSystem.IsLinux())
|
||||||
|
start.Environment.Add("DISPLAY", "required");
|
||||||
|
start.Environment.Add("SSH_ASKPASS", selfExecFile); // Can not use parameter here, because it invoked by SSH with `exec`
|
||||||
|
start.Environment.Add("SSH_ASKPASS_REQUIRE", "prefer");
|
||||||
|
start.Environment.Add("SOURCEGIT_LAUNCH_AS_ASKPASS", "TRUE");
|
||||||
|
|
||||||
|
// If an SSH private key was provided, sets the environment.
|
||||||
|
if (!string.IsNullOrEmpty(SSHKey))
|
||||||
|
start.Environment.Add("GIT_SSH_COMMAND", $"ssh -o StrictHostKeyChecking=accept-new -i '{SSHKey}'");
|
||||||
|
else
|
||||||
|
start.Environment.Add("GIT_SSH_COMMAND", $"ssh -o StrictHostKeyChecking=accept-new");
|
||||||
|
|
||||||
|
// Force using en_US.UTF-8 locale to avoid GCM crash
|
||||||
|
if (OperatingSystem.IsLinux())
|
||||||
|
start.Environment.Add("LANG", "en_US.UTF-8");
|
||||||
|
|
||||||
|
// Fix sometimes `LSEnvironment` not working on macOS
|
||||||
|
if (OperatingSystem.IsMacOS())
|
||||||
|
start.Environment.Add("PATH", "/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin");
|
||||||
|
|
||||||
|
// Force using this app as git editor.
|
||||||
|
switch (Editor)
|
||||||
|
{
|
||||||
|
case EditorType.CoreEditor:
|
||||||
|
start.Arguments += $"-c core.editor=\"\\\"{selfExecFile}\\\" --core-editor\" ";
|
||||||
|
break;
|
||||||
|
case EditorType.RebaseEditor:
|
||||||
|
start.Arguments += $"-c core.editor=\"\\\"{selfExecFile}\\\" --rebase-message-editor\" -c sequence.editor=\"\\\"{selfExecFile}\\\" --rebase-todo-editor\" -c rebase.abbreviateCommands=true ";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
start.Arguments += "-c core.editor=true ";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append command args
|
||||||
|
start.Arguments += Args;
|
||||||
|
|
||||||
|
// Working directory
|
||||||
|
if (!string.IsNullOrEmpty(WorkingDirectory))
|
||||||
|
start.WorkingDirectory = WorkingDirectory;
|
||||||
|
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
[GeneratedRegex(@"\d+%")]
|
[GeneratedRegex(@"\d+%")]
|
||||||
private static partial Regex REG_PROGRESS();
|
private static partial Regex REG_PROGRESS();
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace SourceGit.Converters
|
||||||
{
|
{
|
||||||
if (OperatingSystem.IsWindows())
|
if (OperatingSystem.IsWindows())
|
||||||
return v;
|
return v;
|
||||||
|
|
||||||
var home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
|
var home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
|
||||||
var prefixLen = home.EndsWith('/') ? home.Length - 1 : home.Length;
|
var prefixLen = home.EndsWith('/') ? home.Length - 1 : home.Length;
|
||||||
if (v.StartsWith(home, StringComparison.Ordinal))
|
if (v.StartsWith(home, StringComparison.Ordinal))
|
||||||
|
|
|
@ -43,12 +43,13 @@ namespace SourceGit.Models
|
||||||
{
|
{
|
||||||
_mode = mode;
|
_mode = mode;
|
||||||
|
|
||||||
YAxes = [new Axis() {
|
YAxes = [new Axis()
|
||||||
|
{
|
||||||
TextSize = 10,
|
TextSize = 10,
|
||||||
MinLimit = 0,
|
MinLimit = 0,
|
||||||
SeparatorsPaint = new SolidColorPaint(new SKColor(0x40808080)) { StrokeThickness = 1 }
|
SeparatorsPaint = new SolidColorPaint(new SKColor(0x40808080)) { StrokeThickness = 1 }
|
||||||
}];
|
}];
|
||||||
|
|
||||||
if (mode == StaticsticsMode.ThisWeek)
|
if (mode == StaticsticsMode.ThisWeek)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 7; i++)
|
for (int i = 0; i < 7; i++)
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace SourceGit.Models
|
||||||
extension = ".sh";
|
extension = ".sh";
|
||||||
else if (extension == ".kt" || extension == ".kts")
|
else if (extension == ".kt" || extension == ".kts")
|
||||||
extension = ".kotlin";
|
extension = ".kotlin";
|
||||||
|
|
||||||
foreach (var grammar in s_extraGrammars)
|
foreach (var grammar in s_extraGrammars)
|
||||||
{
|
{
|
||||||
if (grammar.Extension.Equals(extension, StringComparison.OrdinalIgnoreCase))
|
if (grammar.Extension.Equals(extension, StringComparison.OrdinalIgnoreCase))
|
||||||
|
@ -87,7 +87,7 @@ namespace SourceGit.Models
|
||||||
public ICollection<string> GetInjections(string scopeName) => _backend.GetInjections(scopeName);
|
public ICollection<string> GetInjections(string scopeName) => _backend.GetInjections(scopeName);
|
||||||
public IRawGrammar GetGrammar(string scopeName) => GrammarUtility.GetGrammar(scopeName, _backend);
|
public IRawGrammar GetGrammar(string scopeName) => GrammarUtility.GetGrammar(scopeName, _backend);
|
||||||
public string GetScope(string filename) => GrammarUtility.GetScope(filename, _backend);
|
public string GetScope(string filename) => GrammarUtility.GetScope(filename, _backend);
|
||||||
|
|
||||||
private readonly RegistryOptions _backend = new(defaultTheme);
|
private readonly RegistryOptions _backend = new(defaultTheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,8 +95,8 @@ namespace SourceGit.Models
|
||||||
{
|
{
|
||||||
public static TextMate.Installation CreateForEditor(TextEditor editor)
|
public static TextMate.Installation CreateForEditor(TextEditor editor)
|
||||||
{
|
{
|
||||||
return editor.InstallTextMate(Application.Current?.ActualThemeVariant == ThemeVariant.Dark ?
|
return editor.InstallTextMate(Application.Current?.ActualThemeVariant == ThemeVariant.Dark ?
|
||||||
new RegistryOptionsWrapper(ThemeName.DarkPlus) :
|
new RegistryOptionsWrapper(ThemeName.DarkPlus) :
|
||||||
new RegistryOptionsWrapper(ThemeName.LightPlus));
|
new RegistryOptionsWrapper(ThemeName.LightPlus));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,8 @@ namespace SourceGit.ViewModels
|
||||||
{
|
{
|
||||||
PopupHost.Active = value;
|
PopupHost.Active = value;
|
||||||
|
|
||||||
if (!_ignoreIndexChange && value is { Data: Repository })
|
if (!_ignoreIndexChange && value is { Data: Repository repo })
|
||||||
ActiveWorkspace.ActiveIdx = Pages.IndexOf(value);
|
ActiveWorkspace.ActiveIdx = ActiveWorkspace.Repositories.IndexOf(repo.FullPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,10 +131,22 @@ namespace SourceGit.ViewModels
|
||||||
|
|
||||||
public void MoveTab(LauncherPage from, LauncherPage to)
|
public void MoveTab(LauncherPage from, LauncherPage to)
|
||||||
{
|
{
|
||||||
|
_ignoreIndexChange = true;
|
||||||
|
|
||||||
var fromIdx = Pages.IndexOf(from);
|
var fromIdx = Pages.IndexOf(from);
|
||||||
var toIdx = Pages.IndexOf(to);
|
var toIdx = Pages.IndexOf(to);
|
||||||
Pages.Move(fromIdx, toIdx);
|
Pages.Move(fromIdx, toIdx);
|
||||||
ActivePage = from;
|
ActivePage = from;
|
||||||
|
|
||||||
|
ActiveWorkspace.Repositories.Clear();
|
||||||
|
foreach (var p in Pages)
|
||||||
|
{
|
||||||
|
if (p.Data is Repository r)
|
||||||
|
ActiveWorkspace.Repositories.Add(r.FullPath);
|
||||||
|
}
|
||||||
|
ActiveWorkspace.ActiveIdx = ActiveWorkspace.Repositories.IndexOf(from.Node.Id);
|
||||||
|
|
||||||
|
_ignoreIndexChange = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GotoNextTab()
|
public void GotoNextTab()
|
||||||
|
@ -164,7 +176,9 @@ namespace SourceGit.ViewModels
|
||||||
var last = Pages[0];
|
var last = Pages[0];
|
||||||
if (last.Data is Repository repo)
|
if (last.Data is Repository repo)
|
||||||
{
|
{
|
||||||
ActiveWorkspace.Repositories.Remove(repo.FullPath);
|
ActiveWorkspace.Repositories.Clear();
|
||||||
|
ActiveWorkspace.ActiveIdx = 0;
|
||||||
|
|
||||||
Models.AutoFetchManager.Instance.RemoveRepository(repo.FullPath);
|
Models.AutoFetchManager.Instance.RemoveRepository(repo.FullPath);
|
||||||
repo.Close();
|
repo.Close();
|
||||||
|
|
||||||
|
@ -180,6 +194,7 @@ namespace SourceGit.ViewModels
|
||||||
App.Quit(0);
|
App.Quit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_ignoreIndexChange = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,6 +228,8 @@ namespace SourceGit.ViewModels
|
||||||
if (Pages.Count == 1)
|
if (Pages.Count == 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
_ignoreIndexChange = true;
|
||||||
|
|
||||||
var id = ActivePage.Node.Id;
|
var id = ActivePage.Node.Id;
|
||||||
foreach (var one in Pages)
|
foreach (var one in Pages)
|
||||||
{
|
{
|
||||||
|
@ -221,12 +238,17 @@ namespace SourceGit.ViewModels
|
||||||
}
|
}
|
||||||
|
|
||||||
Pages = new AvaloniaList<LauncherPage> { ActivePage };
|
Pages = new AvaloniaList<LauncherPage> { ActivePage };
|
||||||
|
ActiveWorkspace.ActiveIdx = 0;
|
||||||
OnPropertyChanged(nameof(Pages));
|
OnPropertyChanged(nameof(Pages));
|
||||||
|
|
||||||
|
_ignoreIndexChange = false;
|
||||||
GC.Collect();
|
GC.Collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CloseRightTabs()
|
public void CloseRightTabs()
|
||||||
{
|
{
|
||||||
|
_ignoreIndexChange = true;
|
||||||
|
|
||||||
var endIdx = Pages.IndexOf(ActivePage);
|
var endIdx = Pages.IndexOf(ActivePage);
|
||||||
for (var i = Pages.Count - 1; i > endIdx; i--)
|
for (var i = Pages.Count - 1; i > endIdx; i--)
|
||||||
{
|
{
|
||||||
|
@ -234,6 +256,7 @@ namespace SourceGit.ViewModels
|
||||||
Pages.Remove(Pages[i]);
|
Pages.Remove(Pages[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_ignoreIndexChange = false;
|
||||||
GC.Collect();
|
GC.Collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,7 +293,6 @@ namespace SourceGit.ViewModels
|
||||||
};
|
};
|
||||||
|
|
||||||
repo.Open();
|
repo.Open();
|
||||||
ActiveWorkspace.AddRepository(repo.FullPath);
|
|
||||||
Models.AutoFetchManager.Instance.AddRepository(repo.FullPath, repo.GitDir);
|
Models.AutoFetchManager.Instance.AddRepository(repo.FullPath, repo.GitDir);
|
||||||
|
|
||||||
if (page == null)
|
if (page == null)
|
||||||
|
@ -294,6 +316,16 @@ namespace SourceGit.ViewModels
|
||||||
}
|
}
|
||||||
|
|
||||||
ActivePage = page;
|
ActivePage = page;
|
||||||
|
|
||||||
|
ActiveWorkspace.Repositories.Clear();
|
||||||
|
foreach (var p in Pages)
|
||||||
|
{
|
||||||
|
if (p.Data is Repository r)
|
||||||
|
ActiveWorkspace.Repositories.Add(r.FullPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_ignoreIndexChange)
|
||||||
|
ActiveWorkspace.ActiveIdx = ActiveWorkspace.Repositories.IndexOf(node.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DispatchNotification(string pageId, string message, bool isError)
|
public void DispatchNotification(string pageId, string message, bool isError)
|
||||||
|
|
|
@ -51,12 +51,6 @@ namespace SourceGit.ViewModels
|
||||||
get => new SolidColorBrush(_color);
|
get => new SolidColorBrush(_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddRepository(string repo)
|
|
||||||
{
|
|
||||||
if (!Repositories.Contains(repo))
|
|
||||||
Repositories.Add(repo);
|
|
||||||
}
|
|
||||||
|
|
||||||
private string _name = string.Empty;
|
private string _name = string.Empty;
|
||||||
private uint _color = 4278221015;
|
private uint _color = 4278221015;
|
||||||
private bool _isActive = false;
|
private bool _isActive = false;
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace SourceGit.Views
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!e.Handled && e.Key != Key.Space)
|
if (!e.Handled && e.Key != Key.Space)
|
||||||
base.OnKeyDown(e);
|
base.OnKeyDown(e);
|
||||||
}
|
}
|
||||||
|
@ -166,10 +166,10 @@ namespace SourceGit.Views
|
||||||
{
|
{
|
||||||
if (lastUnselected == -1)
|
if (lastUnselected == -1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastUnselected = i;
|
lastUnselected = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -186,10 +186,10 @@ namespace SourceGit.Views
|
||||||
{
|
{
|
||||||
if (lastUnselected == -1)
|
if (lastUnselected == -1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastUnselected = i;
|
lastUnselected = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,7 +244,7 @@ namespace SourceGit.Views
|
||||||
_disableSelectionChangingEvent = true;
|
_disableSelectionChangingEvent = true;
|
||||||
|
|
||||||
var selected = new List<Models.Change>();
|
var selected = new List<Models.Change>();
|
||||||
if (sender is ListBox { SelectedItems: {} selectedItems })
|
if (sender is ListBox { SelectedItems: { } selectedItems })
|
||||||
{
|
{
|
||||||
foreach (var item in selectedItems)
|
foreach (var item in selectedItems)
|
||||||
{
|
{
|
||||||
|
|
|
@ -117,7 +117,7 @@ namespace SourceGit.Views
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!e.Handled)
|
if (!e.Handled)
|
||||||
base.OnKeyDown(e);
|
base.OnKeyDown(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace SourceGit.Views
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RepositoryListBox : ListBox
|
public class RepositoryListBox : ListBox
|
||||||
{
|
{
|
||||||
protected override Type StyleKeyOverride => typeof(ListBox);
|
protected override Type StyleKeyOverride => typeof(ListBox);
|
||||||
|
@ -40,7 +40,7 @@ namespace SourceGit.Views
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!e.Handled)
|
if (!e.Handled)
|
||||||
base.OnKeyDown(e);
|
base.OnKeyDown(e);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue