Skip to content

Commit

Permalink
Merge branch 'v2_develop' into ansi-parser
Browse files Browse the repository at this point in the history
  • Loading branch information
tznind authored Dec 7, 2024
2 parents de64116 + a9769e9 commit 903a886
Show file tree
Hide file tree
Showing 12 changed files with 178 additions and 43 deletions.
26 changes: 21 additions & 5 deletions Terminal.Gui/Application/Application.Initialization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ internal static void InternalInit (
try
{
MainLoop = Driver!.Init ();
SubscribeDriverEvents ();
}
catch (InvalidOperationException ex)
{
Expand All @@ -163,11 +164,6 @@ internal static void InternalInit (
);
}

Driver.SizeChanged += Driver_SizeChanged;
Driver.KeyDown += Driver_KeyDown;
Driver.KeyUp += Driver_KeyUp;
Driver.MouseEvent += Driver_MouseEvent;

SynchronizationContext.SetSynchronizationContext (new MainLoopSyncContext ());

SupportedCultures = GetSupportedCultures ();
Expand All @@ -176,6 +172,26 @@ internal static void InternalInit (
InitializedChanged?.Invoke (null, new (init));
}

internal static void SubscribeDriverEvents ()
{
ArgumentNullException.ThrowIfNull (Driver);

Driver.SizeChanged += Driver_SizeChanged;
Driver.KeyDown += Driver_KeyDown;
Driver.KeyUp += Driver_KeyUp;
Driver.MouseEvent += Driver_MouseEvent;
}

internal static void UnsubscribeDriverEvents ()
{
ArgumentNullException.ThrowIfNull (Driver);

Driver.SizeChanged -= Driver_SizeChanged;
Driver.KeyDown -= Driver_KeyDown;
Driver.KeyUp -= Driver_KeyUp;
Driver.MouseEvent -= Driver_MouseEvent;
}

private static void Driver_SizeChanged (object? sender, SizeChangedEventArgs e) { OnSizeChanging (e); }
private static void Driver_KeyDown (object? sender, Key e) { RaiseKeyDownEvent (e); }
private static void Driver_KeyUp (object? sender, Key e) { RaiseKeyUpEvent (e); }
Expand Down
5 changes: 1 addition & 4 deletions Terminal.Gui/Application/Application.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,7 @@ internal static void ResetState (bool ignoreDisposed = false)
// Driver stuff
if (Driver is { })
{
Driver.SizeChanged -= Driver_SizeChanged;
Driver.KeyDown -= Driver_KeyDown;
Driver.KeyUp -= Driver_KeyUp;
Driver.MouseEvent -= Driver_MouseEvent;
UnsubscribeDriverEvents ();
Driver?.End ();
Driver = null;
}
Expand Down
12 changes: 6 additions & 6 deletions Terminal.Gui/Text/TextFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1411,7 +1411,7 @@ public static string ClipAndJustify (

if (textFormatter is { Alignment: Alignment.Center })
{
return GetRangeThatFits (runes, Math.Max ((runes.Count - width) / 2, 0), text, width, tabWidth, textDirection);
return GetRangeThatFits (runes, Math.Max ((runes.Count - width - zeroLength) / 2, 0), text, width, tabWidth, textDirection);
}

return GetRangeThatFits (runes, 0, text, width, tabWidth, textDirection);
Expand All @@ -1426,7 +1426,7 @@ public static string ClipAndJustify (

if (textFormatter is { VerticalAlignment: Alignment.Center })
{
return GetRangeThatFits (runes, Math.Max ((runes.Count - width) / 2, 0), text, width, tabWidth, textDirection);
return GetRangeThatFits (runes, Math.Max ((runes.Count - width - zeroLength) / 2, 0), text, width, tabWidth, textDirection);
}

return GetRangeThatFits (runes, 0, text, width, tabWidth, textDirection);
Expand All @@ -1451,7 +1451,7 @@ public static string ClipAndJustify (
}
else if (textFormatter is { Alignment: Alignment.Center })
{
return GetRangeThatFits (runes, Math.Max ((runes.Count - width) / 2, 0), text, width, tabWidth, textDirection);
return GetRangeThatFits (runes, Math.Max ((runes.Count - width - zeroLength) / 2, 0), text, width, tabWidth, textDirection);
}
else if (GetRuneWidth (text, tabWidth, textDirection) > width)
{
Expand All @@ -1470,7 +1470,7 @@ public static string ClipAndJustify (
}
else if (textFormatter is { VerticalAlignment: Alignment.Center })
{
return GetRangeThatFits (runes, Math.Max ((runes.Count - width) / 2, 0), text, width, tabWidth, textDirection);
return GetRangeThatFits (runes, Math.Max ((runes.Count - width - zeroLength) / 2, 0), text, width, tabWidth, textDirection);
}
else if (runes.Count - zeroLength > width)
{
Expand Down Expand Up @@ -1526,7 +1526,7 @@ public static string Justify (
}
else
{
textCount = words.Sum (arg => arg.GetRuneCount ());
textCount = words.Sum (arg => arg.GetRuneCount ()) - text.EnumerateRunes ().Sum (r => r.GetColumns () == 0 ? 1 : 0);
}

int spaces = words.Length > 1 ? (width - textCount) / (words.Length - 1) : 0;
Expand Down Expand Up @@ -1936,7 +1936,7 @@ private static int GetRuneWidth (List<Rune> runes, int tabWidth, TextDirection t

private static int GetRuneWidth (Rune rune, int tabWidth, TextDirection textDirection = TextDirection.LeftRight_TopBottom)
{
int runeWidth = IsHorizontalDirection (textDirection) ? rune.GetColumns () : 1;
int runeWidth = IsHorizontalDirection (textDirection) ? rune.GetColumns () : rune.GetColumns () == 0 ? 0 : 1;

if (rune.Value == '\t')
{
Expand Down
10 changes: 5 additions & 5 deletions Terminal.Gui/View/View.Keyboard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -690,11 +690,11 @@ public bool IsHotKeyBound (Key key, out View? boundView)

#if DEBUG

if (Application.KeyBindings.TryGet (key, out KeyBinding b))
{
Debug.WriteLine (
$"WARNING: InvokeKeyBindings ({key}) - An Application scope binding exists for this key. The registered view will not invoke Command.");
}
//if (Application.KeyBindings.TryGet (key, out KeyBinding b))
//{
// Debug.WriteLine (
// $"WARNING: InvokeKeyBindings ({key}) - An Application scope binding exists for this key. The registered view will not invoke Command.");
//}

// TODO: This is a "prototype" debug check. It may be too annoying vs. useful.
// Scour the bindings up our View hierarchy
Expand Down
5 changes: 3 additions & 2 deletions Terminal.Gui/View/View.Layout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -561,8 +561,9 @@ public bool SetRelativeLayout (Size superviewContentSize)
{
SuperView?.SetNeedsDraw ();
}
else
else if (Application.TopLevels.Count == 1)
{
// If this is the only TopLevel, we need to redraw the screen
Application.ClearScreenNextIteration = true;
}
}
Expand Down Expand Up @@ -801,7 +802,7 @@ public void SetNeedsLayout ()
{
foreach (Toplevel tl in Application.TopLevels)
{
// tl.SetNeedsDraw ();
// tl.SetNeedsDraw ();
}
}

Expand Down
2 changes: 1 addition & 1 deletion UICatalog/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
},
"All Views Tester": {
"commandName": "Project",
"commandLineArgs": "\"All Views Tester\" -b"
"commandLineArgs": "\"All Views Tester\" -b -t 5000"
},
"Charmap": {
"commandName": "Project",
Expand Down
19 changes: 10 additions & 9 deletions UICatalog/Scenario.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,14 +148,15 @@ public static ObservableCollection<Scenario> GetScenarios ()
/// </summary>
public virtual void Main () { }

private const uint MAX_NATURAL_ITERATIONS = 500; // not including needed for demo keys
private const uint ABORT_TIMEOUT_MS = 2500;
private const int DEMO_KEY_PACING_MS = 1; // Must be non-zero
private const uint BENCHMARK_MAX_NATURAL_ITERATIONS = 500; // not including needed for demo keys
private const int BENCHMARK_KEY_PACING = 1; // Must be non-zero

public static uint BenchmarkTimeout { get; set; } = 2500;

private readonly object _timeoutLock = new ();
private object? _timeout;
private Stopwatch? _stopwatch;
private readonly BenchmarkResults _benchmarkResults = new BenchmarkResults ();
private readonly BenchmarkResults _benchmarkResults = new ();

public void StartBenchmark ()
{
Expand All @@ -178,7 +179,7 @@ public BenchmarkResults EndBenchmark ()
return _benchmarkResults;
}

private List<Key> _demoKeys;
private List<Key>? _demoKeys;
private int _currentDemoKey = 0;

private void OnApplicationOnInitializedChanged (object? s, EventArgs<bool> a)
Expand All @@ -187,7 +188,7 @@ private void OnApplicationOnInitializedChanged (object? s, EventArgs<bool> a)
{
lock (_timeoutLock!)
{
_timeout = Application.AddTimeout (TimeSpan.FromMilliseconds (ABORT_TIMEOUT_MS), ForceCloseCallback);
_timeout = Application.AddTimeout (TimeSpan.FromMilliseconds (BenchmarkTimeout), ForceCloseCallback);
}

Application.Iteration += OnApplicationOnIteration;
Expand Down Expand Up @@ -218,7 +219,7 @@ private void OnApplicationOnInitializedChanged (object? s, EventArgs<bool> a)
private void OnApplicationOnIteration (object? s, IterationEventArgs a)
{
BenchmarkResults.IterationCount++;
if (BenchmarkResults.IterationCount > MAX_NATURAL_ITERATIONS + (_demoKeys.Count* DEMO_KEY_PACING_MS))
if (BenchmarkResults.IterationCount > BENCHMARK_MAX_NATURAL_ITERATIONS + (_demoKeys.Count * BENCHMARK_KEY_PACING))
{
Application.RequestStop ();
}
Expand All @@ -232,7 +233,7 @@ private void OnApplicationNotifyNewRunState (object? sender, RunStateEventArgs e
_demoKeys = GetDemoKeyStrokes ();

Application.AddTimeout (
new TimeSpan (0, 0, 0, 0, DEMO_KEY_PACING_MS),
new TimeSpan (0, 0, 0, 0, BENCHMARK_KEY_PACING),
() =>
{
if (_currentDemoKey >= _demoKeys.Count)
Expand Down Expand Up @@ -271,7 +272,7 @@ private bool ForceCloseCallback ()
}
}

Debug.WriteLine ($@" Failed to Quit with {Application.QuitKey} after {ABORT_TIMEOUT_MS}ms and {BenchmarkResults.IterationCount} iterations. Force quit.");
Debug.WriteLine ($@" Failed to Quit with {Application.QuitKey} after {BenchmarkTimeout}ms and {BenchmarkResults.IterationCount} iterations. Force quit.");

Application.RequestStop ();

Expand Down
18 changes: 15 additions & 3 deletions UICatalog/UICatalog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@ private static int Main (string [] args)
benchmarkFlag.AddAlias ("-b");
benchmarkFlag.AddAlias ("--b");

Option<uint> benchmarkTimeout = new Option<uint> ("--timeout", getDefaultValue: () => Scenario.BenchmarkTimeout, $"The maximum time in milliseconds to run a benchmark for. Default is {Scenario.BenchmarkTimeout}ms.");
benchmarkTimeout.AddAlias ("-t");
benchmarkTimeout.AddAlias ("--t");

Option<string> resultsFile = new Option<string> ("--file", "The file to save benchmark results to. If not specified, the results will be displayed in a TableView.");
resultsFile.AddAlias ("-f");
resultsFile.AddAlias ("--f");
Expand All @@ -165,7 +169,7 @@ private static int Main (string [] args)

var rootCommand = new RootCommand ("A comprehensive sample library for Terminal.Gui")
{
scenarioArgument, benchmarkFlag, resultsFile, driverOption,
scenarioArgument, benchmarkFlag, benchmarkTimeout, resultsFile, driverOption,
};

rootCommand.SetHandler (
Expand All @@ -176,6 +180,7 @@ private static int Main (string [] args)
Scenario = context.ParseResult.GetValueForArgument (scenarioArgument),
Driver = context.ParseResult.GetValueForOption (driverOption) ?? string.Empty,
Benchmark = context.ParseResult.GetValueForOption (benchmarkFlag),
BenchmarkTimeout = context.ParseResult.GetValueForOption (benchmarkTimeout),
ResultsFile = context.ParseResult.GetValueForOption (resultsFile) ?? string.Empty,
/* etc. */
};
Expand All @@ -197,6 +202,8 @@ private static int Main (string [] args)
return 0;
}

Scenario.BenchmarkTimeout = _options.BenchmarkTimeout;

UICatalogMain (_options);

return 0;
Expand Down Expand Up @@ -332,6 +339,7 @@ private static void UICatalogMain (Options options)
// regardless of what's in a config file.
Application.ForceDriver = _forceDriver = options.Driver;


// If a Scenario name has been provided on the commandline
// run it and exit when done.
if (options.Scenario != "none")
Expand Down Expand Up @@ -788,7 +796,8 @@ public UICatalogTopLevel ()
{
if (_statusBar.NeedsLayout)
{
// throw new LayoutException ("DimFunc.Fn aborted because dependent View needs layout.");
throw new LayoutException ("DimFunc.Fn aborted because dependent View needs layout.");
//_statusBar.Layout ();
}
return _statusBar.Frame.Height;
})),
Expand Down Expand Up @@ -817,7 +826,8 @@ public UICatalogTopLevel ()
{
if (_statusBar.NeedsLayout)
{
// throw new LayoutException ("DimFunc.Fn aborted because dependent View needs layout.");
throw new LayoutException ("DimFunc.Fn aborted because dependent View needs layout.");
//_statusBar.Layout ();
}
return _statusBar.Frame.Height;
})),
Expand Down Expand Up @@ -1378,6 +1388,8 @@ private struct Options

public string Scenario;

public uint BenchmarkTimeout;

public bool Benchmark;

public string ResultsFile;
Expand Down
20 changes: 20 additions & 0 deletions UnitTests/Application/ApplicationScreenTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,24 @@ public void ClearContents_Called_When_Top_Frame_Changes ()
Application.Top = null;
Application.Shutdown ();
}

[Fact]
public void Screen_Changes_OnSizeChanged_Without_Call_Application_Init ()
{
// Arrange
Application.ResetState (true);
Assert.Null (Application.Driver);
Application.Driver = new FakeDriver { Rows = 25, Cols = 25 };
Application.SubscribeDriverEvents ();
Assert.Equal (new (0, 0, 25, 25), Application.Screen);

// Act
(((FakeDriver)Application.Driver)!).SetBufferSize (120, 30);

// Assert
Assert.Equal (new (0, 0, 120, 30), Application.Screen);

// Cleanup
Application.ResetState (true);
}
}
6 changes: 6 additions & 0 deletions UnitTests/Application/ApplicationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,12 @@ public void Screen_Size_Changes ()
Application.Shutdown ();
}

[Fact]
public void InitState_Throws_If_Driver_Is_Null ()
{
Assert.Throws<ArgumentNullException> (static () => Application.SubscribeDriverEvents ());
}

private void Init ()
{
Application.Init (new FakeDriver ());
Expand Down
14 changes: 6 additions & 8 deletions UnitTests/TestHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -197,14 +197,9 @@ public override void After (MethodInfo methodUnderTest)
// Turn off diagnostic flags in case some test left them on
View.Diagnostics = ViewDiagnosticFlags.Off;

if (Application.Driver is { })
{
((FakeDriver)Application.Driver).Rows = 25;
((FakeDriver)Application.Driver).Cols = 25;
((FakeDriver)Application.Driver).End ();
}

Application.Driver = null;
Application.ResetState (true);
Assert.Null (Application.Driver);
Assert.Equal (new (0, 0, 2048, 2048), Application.Screen);
base.After (methodUnderTest);
}

Expand All @@ -215,6 +210,9 @@ public override void Before (MethodInfo methodUnderTest)
Application.ResetState (true);
Assert.Null (Application.Driver);
Application.Driver = new FakeDriver { Rows = 25, Cols = 25 };
Assert.Equal (new (0, 0, 25, 25), Application.Screen);
// Ensures subscribing events, at least for the SizeChanged event
Application.SubscribeDriverEvents ();

base.Before (methodUnderTest);
}
Expand Down
Loading

0 comments on commit 903a886

Please sign in to comment.