Skip to content

Commit 903a886

Browse files
authored
Merge branch 'v2_develop' into ansi-parser
2 parents de64116 + a9769e9 commit 903a886

File tree

12 files changed

+178
-43
lines changed

12 files changed

+178
-43
lines changed

Terminal.Gui/Application/Application.Initialization.cs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ internal static void InternalInit (
150150
try
151151
{
152152
MainLoop = Driver!.Init ();
153+
SubscribeDriverEvents ();
153154
}
154155
catch (InvalidOperationException ex)
155156
{
@@ -163,11 +164,6 @@ internal static void InternalInit (
163164
);
164165
}
165166

166-
Driver.SizeChanged += Driver_SizeChanged;
167-
Driver.KeyDown += Driver_KeyDown;
168-
Driver.KeyUp += Driver_KeyUp;
169-
Driver.MouseEvent += Driver_MouseEvent;
170-
171167
SynchronizationContext.SetSynchronizationContext (new MainLoopSyncContext ());
172168

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

175+
internal static void SubscribeDriverEvents ()
176+
{
177+
ArgumentNullException.ThrowIfNull (Driver);
178+
179+
Driver.SizeChanged += Driver_SizeChanged;
180+
Driver.KeyDown += Driver_KeyDown;
181+
Driver.KeyUp += Driver_KeyUp;
182+
Driver.MouseEvent += Driver_MouseEvent;
183+
}
184+
185+
internal static void UnsubscribeDriverEvents ()
186+
{
187+
ArgumentNullException.ThrowIfNull (Driver);
188+
189+
Driver.SizeChanged -= Driver_SizeChanged;
190+
Driver.KeyDown -= Driver_KeyDown;
191+
Driver.KeyUp -= Driver_KeyUp;
192+
Driver.MouseEvent -= Driver_MouseEvent;
193+
}
194+
179195
private static void Driver_SizeChanged (object? sender, SizeChangedEventArgs e) { OnSizeChanging (e); }
180196
private static void Driver_KeyDown (object? sender, Key e) { RaiseKeyDownEvent (e); }
181197
private static void Driver_KeyUp (object? sender, Key e) { RaiseKeyUpEvent (e); }

Terminal.Gui/Application/Application.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,7 @@ internal static void ResetState (bool ignoreDisposed = false)
177177
// Driver stuff
178178
if (Driver is { })
179179
{
180-
Driver.SizeChanged -= Driver_SizeChanged;
181-
Driver.KeyDown -= Driver_KeyDown;
182-
Driver.KeyUp -= Driver_KeyUp;
183-
Driver.MouseEvent -= Driver_MouseEvent;
180+
UnsubscribeDriverEvents ();
184181
Driver?.End ();
185182
Driver = null;
186183
}

Terminal.Gui/Text/TextFormatter.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,7 +1411,7 @@ public static string ClipAndJustify (
14111411

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

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

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

14321432
return GetRangeThatFits (runes, 0, text, width, tabWidth, textDirection);
@@ -1451,7 +1451,7 @@ public static string ClipAndJustify (
14511451
}
14521452
else if (textFormatter is { Alignment: Alignment.Center })
14531453
{
1454-
return GetRangeThatFits (runes, Math.Max ((runes.Count - width) / 2, 0), text, width, tabWidth, textDirection);
1454+
return GetRangeThatFits (runes, Math.Max ((runes.Count - width - zeroLength) / 2, 0), text, width, tabWidth, textDirection);
14551455
}
14561456
else if (GetRuneWidth (text, tabWidth, textDirection) > width)
14571457
{
@@ -1470,7 +1470,7 @@ public static string ClipAndJustify (
14701470
}
14711471
else if (textFormatter is { VerticalAlignment: Alignment.Center })
14721472
{
1473-
return GetRangeThatFits (runes, Math.Max ((runes.Count - width) / 2, 0), text, width, tabWidth, textDirection);
1473+
return GetRangeThatFits (runes, Math.Max ((runes.Count - width - zeroLength) / 2, 0), text, width, tabWidth, textDirection);
14741474
}
14751475
else if (runes.Count - zeroLength > width)
14761476
{
@@ -1526,7 +1526,7 @@ public static string Justify (
15261526
}
15271527
else
15281528
{
1529-
textCount = words.Sum (arg => arg.GetRuneCount ());
1529+
textCount = words.Sum (arg => arg.GetRuneCount ()) - text.EnumerateRunes ().Sum (r => r.GetColumns () == 0 ? 1 : 0);
15301530
}
15311531

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

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

19411941
if (rune.Value == '\t')
19421942
{

Terminal.Gui/View/View.Keyboard.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -690,11 +690,11 @@ public bool IsHotKeyBound (Key key, out View? boundView)
690690

691691
#if DEBUG
692692

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

699699
// TODO: This is a "prototype" debug check. It may be too annoying vs. useful.
700700
// Scour the bindings up our View hierarchy

Terminal.Gui/View/View.Layout.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -561,8 +561,9 @@ public bool SetRelativeLayout (Size superviewContentSize)
561561
{
562562
SuperView?.SetNeedsDraw ();
563563
}
564-
else
564+
else if (Application.TopLevels.Count == 1)
565565
{
566+
// If this is the only TopLevel, we need to redraw the screen
566567
Application.ClearScreenNextIteration = true;
567568
}
568569
}
@@ -801,7 +802,7 @@ public void SetNeedsLayout ()
801802
{
802803
foreach (Toplevel tl in Application.TopLevels)
803804
{
804-
// tl.SetNeedsDraw ();
805+
// tl.SetNeedsDraw ();
805806
}
806807
}
807808

UICatalog/Properties/launchSettings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
},
4343
"All Views Tester": {
4444
"commandName": "Project",
45-
"commandLineArgs": "\"All Views Tester\" -b"
45+
"commandLineArgs": "\"All Views Tester\" -b -t 5000"
4646
},
4747
"Charmap": {
4848
"commandName": "Project",

UICatalog/Scenario.cs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -148,14 +148,15 @@ public static ObservableCollection<Scenario> GetScenarios ()
148148
/// </summary>
149149
public virtual void Main () { }
150150

151-
private const uint MAX_NATURAL_ITERATIONS = 500; // not including needed for demo keys
152-
private const uint ABORT_TIMEOUT_MS = 2500;
153-
private const int DEMO_KEY_PACING_MS = 1; // Must be non-zero
151+
private const uint BENCHMARK_MAX_NATURAL_ITERATIONS = 500; // not including needed for demo keys
152+
private const int BENCHMARK_KEY_PACING = 1; // Must be non-zero
153+
154+
public static uint BenchmarkTimeout { get; set; } = 2500;
154155

155156
private readonly object _timeoutLock = new ();
156157
private object? _timeout;
157158
private Stopwatch? _stopwatch;
158-
private readonly BenchmarkResults _benchmarkResults = new BenchmarkResults ();
159+
private readonly BenchmarkResults _benchmarkResults = new ();
159160

160161
public void StartBenchmark ()
161162
{
@@ -178,7 +179,7 @@ public BenchmarkResults EndBenchmark ()
178179
return _benchmarkResults;
179180
}
180181

181-
private List<Key> _demoKeys;
182+
private List<Key>? _demoKeys;
182183
private int _currentDemoKey = 0;
183184

184185
private void OnApplicationOnInitializedChanged (object? s, EventArgs<bool> a)
@@ -187,7 +188,7 @@ private void OnApplicationOnInitializedChanged (object? s, EventArgs<bool> a)
187188
{
188189
lock (_timeoutLock!)
189190
{
190-
_timeout = Application.AddTimeout (TimeSpan.FromMilliseconds (ABORT_TIMEOUT_MS), ForceCloseCallback);
191+
_timeout = Application.AddTimeout (TimeSpan.FromMilliseconds (BenchmarkTimeout), ForceCloseCallback);
191192
}
192193

193194
Application.Iteration += OnApplicationOnIteration;
@@ -218,7 +219,7 @@ private void OnApplicationOnInitializedChanged (object? s, EventArgs<bool> a)
218219
private void OnApplicationOnIteration (object? s, IterationEventArgs a)
219220
{
220221
BenchmarkResults.IterationCount++;
221-
if (BenchmarkResults.IterationCount > MAX_NATURAL_ITERATIONS + (_demoKeys.Count* DEMO_KEY_PACING_MS))
222+
if (BenchmarkResults.IterationCount > BENCHMARK_MAX_NATURAL_ITERATIONS + (_demoKeys.Count * BENCHMARK_KEY_PACING))
222223
{
223224
Application.RequestStop ();
224225
}
@@ -232,7 +233,7 @@ private void OnApplicationNotifyNewRunState (object? sender, RunStateEventArgs e
232233
_demoKeys = GetDemoKeyStrokes ();
233234

234235
Application.AddTimeout (
235-
new TimeSpan (0, 0, 0, 0, DEMO_KEY_PACING_MS),
236+
new TimeSpan (0, 0, 0, 0, BENCHMARK_KEY_PACING),
236237
() =>
237238
{
238239
if (_currentDemoKey >= _demoKeys.Count)
@@ -271,7 +272,7 @@ private bool ForceCloseCallback ()
271272
}
272273
}
273274

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

276277
Application.RequestStop ();
277278

UICatalog/UICatalog.cs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,10 @@ private static int Main (string [] args)
148148
benchmarkFlag.AddAlias ("-b");
149149
benchmarkFlag.AddAlias ("--b");
150150

151+
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.");
152+
benchmarkTimeout.AddAlias ("-t");
153+
benchmarkTimeout.AddAlias ("--t");
154+
151155
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.");
152156
resultsFile.AddAlias ("-f");
153157
resultsFile.AddAlias ("--f");
@@ -165,7 +169,7 @@ private static int Main (string [] args)
165169

166170
var rootCommand = new RootCommand ("A comprehensive sample library for Terminal.Gui")
167171
{
168-
scenarioArgument, benchmarkFlag, resultsFile, driverOption,
172+
scenarioArgument, benchmarkFlag, benchmarkTimeout, resultsFile, driverOption,
169173
};
170174

171175
rootCommand.SetHandler (
@@ -176,6 +180,7 @@ private static int Main (string [] args)
176180
Scenario = context.ParseResult.GetValueForArgument (scenarioArgument),
177181
Driver = context.ParseResult.GetValueForOption (driverOption) ?? string.Empty,
178182
Benchmark = context.ParseResult.GetValueForOption (benchmarkFlag),
183+
BenchmarkTimeout = context.ParseResult.GetValueForOption (benchmarkTimeout),
179184
ResultsFile = context.ParseResult.GetValueForOption (resultsFile) ?? string.Empty,
180185
/* etc. */
181186
};
@@ -197,6 +202,8 @@ private static int Main (string [] args)
197202
return 0;
198203
}
199204

205+
Scenario.BenchmarkTimeout = _options.BenchmarkTimeout;
206+
200207
UICatalogMain (_options);
201208

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

342+
335343
// If a Scenario name has been provided on the commandline
336344
// run it and exit when done.
337345
if (options.Scenario != "none")
@@ -788,7 +796,8 @@ public UICatalogTopLevel ()
788796
{
789797
if (_statusBar.NeedsLayout)
790798
{
791-
// throw new LayoutException ("DimFunc.Fn aborted because dependent View needs layout.");
799+
throw new LayoutException ("DimFunc.Fn aborted because dependent View needs layout.");
800+
//_statusBar.Layout ();
792801
}
793802
return _statusBar.Frame.Height;
794803
})),
@@ -817,7 +826,8 @@ public UICatalogTopLevel ()
817826
{
818827
if (_statusBar.NeedsLayout)
819828
{
820-
// throw new LayoutException ("DimFunc.Fn aborted because dependent View needs layout.");
829+
throw new LayoutException ("DimFunc.Fn aborted because dependent View needs layout.");
830+
//_statusBar.Layout ();
821831
}
822832
return _statusBar.Frame.Height;
823833
})),
@@ -1378,6 +1388,8 @@ private struct Options
13781388

13791389
public string Scenario;
13801390

1391+
public uint BenchmarkTimeout;
1392+
13811393
public bool Benchmark;
13821394

13831395
public string ResultsFile;

UnitTests/Application/ApplicationScreenTests.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,24 @@ public void ClearContents_Called_When_Top_Frame_Changes ()
6565
Application.Top = null;
6666
Application.Shutdown ();
6767
}
68+
69+
[Fact]
70+
public void Screen_Changes_OnSizeChanged_Without_Call_Application_Init ()
71+
{
72+
// Arrange
73+
Application.ResetState (true);
74+
Assert.Null (Application.Driver);
75+
Application.Driver = new FakeDriver { Rows = 25, Cols = 25 };
76+
Application.SubscribeDriverEvents ();
77+
Assert.Equal (new (0, 0, 25, 25), Application.Screen);
78+
79+
// Act
80+
(((FakeDriver)Application.Driver)!).SetBufferSize (120, 30);
81+
82+
// Assert
83+
Assert.Equal (new (0, 0, 120, 30), Application.Screen);
84+
85+
// Cleanup
86+
Application.ResetState (true);
87+
}
6888
}

UnitTests/Application/ApplicationTests.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,12 @@ public void Screen_Size_Changes ()
641641
Application.Shutdown ();
642642
}
643643

644+
[Fact]
645+
public void InitState_Throws_If_Driver_Is_Null ()
646+
{
647+
Assert.Throws<ArgumentNullException> (static () => Application.SubscribeDriverEvents ());
648+
}
649+
644650
private void Init ()
645651
{
646652
Application.Init (new FakeDriver ());

0 commit comments

Comments
 (0)