Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
a64b4bc
touching publish.yml
tig Mar 21, 2025
e089108
Fixes #4000. Named colors as enums. (#4005)
TheTonttu Mar 29, 2025
cabe411
Fixes #3691 - Adds `ViewArrangement.Popover` (#3852)
tig Mar 29, 2025
ac5c7e5
Partially Fixes #2975 - Replaces old `ContextMenu` with new `Bar/Shor…
tig Mar 31, 2025
47833bf
Partially Fixes #2975 - Upgrades UICatalog to `Menuv2` (#4011)
tig Apr 2, 2025
4d87d5f
Fixes #4009 - fix tree ordering (#4015)
tznind Apr 5, 2025
eaa9ee1
Fixes #4022 file dialog tests and bugfix for cancellation (#4024)
tznind Apr 16, 2025
e311cad
Partial on #2975 - Replaces Menu v1 in many places with v2 (#4040)
tig Apr 24, 2025
5c03b96
Fixes #3966. TextField crashes app when pasting unicode surrogate pai…
BDisp Apr 24, 2025
a53e674
Goblin fighter (#4037)
tznind Apr 24, 2025
7fe6fd9
Fixes #4046 - Moves examples into `./Examples` and fixes `./Tests` (#…
tig Apr 25, 2025
0a23df7
Fixes #4027. Add collection search matcher (#4029)
tznind Apr 28, 2025
50c6273
Fixes #4051 - Adds `cancellable_work_pattern.md` (#4052)
tig Apr 28, 2025
d2cf744
Update getting-started.md (#4063)
bgiromini Apr 30, 2025
a08ea41
Fixes #4035 - FileDialog keeps path when selecting folder (optionally…
tznind May 9, 2025
f12e548
Allow hotkey specifier to be at any position in label (#4067)
YourRobotOverlord May 9, 2025
e3e02e9
Fixes #4053. v2 WindowsDriver and v2win doesn't show any scenario in …
BDisp May 9, 2025
6f6c2d3
Fixes #4023 - Changes `CommandEventArgs` to be based on `HandledEvent…
tig May 9, 2025
38c6f38
Fixes #4076 cursor text field (#4077)
tznind May 11, 2025
697810b
Fixes #4074 - Popover eats `Key.Space` (#4075)
tig May 11, 2025
40602ee
Addresses #4058. Basic support for non-color text styles. (#4071)
Error-String-Expected-Got-Nil May 12, 2025
18cc7a9
More on #4058 - Adds `TextStyle` Scenario (#4079)
tig May 12, 2025
2a9af8b
Fixes #4070 - `GetContentSize()` api docs (#4081)
tig May 14, 2025
1bd5e55
Fixes #4070 - `GetContentSize()` API docs -2nd try (#4082)
tig May 14, 2025
5547187
Fixes 4088 mouse released flag cannot be combined safely with report …
tznind May 18, 2025
f6f052a
added more mouse under tests
tig May 27, 2025
3e2eebf
Fixes #4057 - MASSIVE! Fully implements `ColorScheme`->`Scheme` + `Vi…
tig May 29, 2025
f272584
Merge branch 'v2_develop' of tig:tig/Terminal.Gui into v2_develop
tig May 29, 2025
7bced23
Removed dead code
tig May 29, 2025
238b86c
Fixed concurrency issues
tig May 29, 2025
a288a24
Fixed namespace issues
tig May 29, 2025
0b447c8
Fixed namespace issues 2
tig May 29, 2025
74540a7
Fixed namespace issues 3
tig May 29, 2025
3be4a7f
Fixed concurrency issues 2
tig May 29, 2025
0ea0595
Merge branch 'v2_develop' into v2-Protect_Application_Toplevels
tig May 29, 2025
b371d3f
Merge branch 'v2_develop' into v2-Protect_Application_Toplevels
tig May 29, 2025
49e8e01
Merge branch 'v2_develop' into v2-Protect_Application_Toplevels
tig May 29, 2025
b0d2884
Merge branch 'v2-Protect_Application_Toplevels' of tig:tig/Terminal.G…
tig May 29, 2025
40a4c43
Fixed error due to merge
tig May 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Examples/UICatalog/Scenarios/VkeyPacketSimulator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using System.Threading;
using System.Threading.Tasks;
using Terminal.Gui;
using Terminal.Gui.ConsoleDrivers;

namespace UICatalog.Scenarios;

Expand Down
20 changes: 9 additions & 11 deletions Terminal.Gui/Application/Application.Run.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,10 @@ public static RunState Begin (Toplevel toplevel)
}
}

if (TopLevels.FindDuplicates (new ToplevelEqualityComparer ()).Count > 0)
{
throw new ArgumentException ("There are duplicates Toplevel IDs");
}
//if (TopLevels.FindDuplicates (new ToplevelEqualityComparer ()).Count > 0)
//{
// throw new ArgumentException ("There are duplicates Toplevel IDs");
//}
}

if (Top is null)
Expand Down Expand Up @@ -588,25 +588,23 @@ public static void End (RunState runState)

// End the RunState.Toplevel
// First, take it off the Toplevel Stack
if (TopLevels.Count > 0)
if (TopLevels.TryPop (out Toplevel? topOfStack))
{
if (TopLevels.Peek () != runState.Toplevel)
if (topOfStack != runState.Toplevel)
{
// If the top of the stack is not the RunState.Toplevel then
// this call to End is not balanced with the call to Begin that started the RunState
throw new ArgumentException ("End must be balanced with calls to Begin");
}

TopLevels.Pop ();
}

// Notify that it is closing
runState.Toplevel?.OnClosed (runState.Toplevel);

if (TopLevels.Count > 0)
if (TopLevels.TryPeek (out Toplevel? newTop))
{
Top = TopLevels.Peek ();
Top.SetNeedsDraw ();
Top = newTop;
Top?.SetNeedsDraw ();
}

if (runState.Toplevel is { HasFocus: true })
Expand Down
16 changes: 15 additions & 1 deletion Terminal.Gui/Application/Application.Toplevel.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
#nullable enable
using System.Collections.Concurrent;

namespace Terminal.Gui;

public static partial class Application // Toplevel handling
{
// BUGBUG: Technically, this is not the full lst of TopLevels. There be dragons here, e.g. see how Toplevel.Id is used. What

private static readonly ConcurrentStack<Toplevel> _topLevels = new ();
private static readonly object _topLevelsLock = new ();

/// <summary>Holds the stack of TopLevel views.</summary>
internal static Stack<Toplevel> TopLevels { get; } = new ();
internal static ConcurrentStack<Toplevel> TopLevels
{
get
{
lock (_topLevelsLock)
{
return _topLevels;
}
}
}

/// <summary>The <see cref="Toplevel"/> that is currently active.</summary>
/// <value>The top.</value>
Expand Down
21 changes: 11 additions & 10 deletions Terminal.Gui/Configuration/ConfigurationManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Serialization;
using Terminal.Gui.Configuration;

namespace Terminal.Gui;

Expand Down Expand Up @@ -150,7 +149,7 @@ internal static bool IsInitialized ()
private static ImmutableSortedDictionary<string, ConfigProperty>? _uninitializedConfigPropertiesCache;

#pragma warning disable IDE1006 // Naming Styles
private static readonly object __uninitializedConfigPropertiesCacheCacheLock = new ();
private static readonly object _uninitializedConfigPropertiesCacheCacheLock = new ();
#pragma warning restore IDE1006 // Naming Styles

/// <summary>
Expand Down Expand Up @@ -181,7 +180,7 @@ internal static void Initialize ()
ConfigProperty.Initialize ();

// Cache all configuration properties
lock (__uninitializedConfigPropertiesCacheCacheLock)
lock (_uninitializedConfigPropertiesCacheCacheLock)
{
// _allConfigProperties: for ordered, iterable access (LINQ-friendly)
// _frozenConfigPropertyCache: for high-speed key lookup (frozen)
Expand Down Expand Up @@ -777,15 +776,17 @@ public static string GetHardCodedConfig ()
return _uninitializedConfigPropertiesCache;
}

// Filter properties by scope using the cached ScopeType property instead of reflection
IEnumerable<KeyValuePair<string, ConfigProperty>>? filtered = _uninitializedConfigPropertiesCache?.Where (cp => cp.Value.ScopeType == scopeType);

Debug.Assert (filtered is { });
lock (_uninitializedConfigPropertiesCacheCacheLock)
{
// Filter properties by scope using the cached ScopeType property instead of reflection
IEnumerable<KeyValuePair<string, ConfigProperty>>? filtered = _uninitializedConfigPropertiesCache?.Where (cp => cp.Value.ScopeType == scopeType);

IEnumerable<KeyValuePair<string, ConfigProperty>> configPropertiesByScope = filtered as KeyValuePair<string, ConfigProperty> [] ?? filtered.ToArray ();
Debug.Assert (configPropertiesByScope.All (v => !v.Value.HasValue));
Debug.Assert (filtered is { });

return configPropertiesByScope;
IEnumerable<KeyValuePair<string, ConfigProperty>> configPropertiesByScope = filtered as KeyValuePair<string, ConfigProperty> [] ?? filtered.ToArray ();
Debug.Assert (configPropertiesByScope.All (v => !v.Value.HasValue));
return configPropertiesByScope;
}
}

/// <summary>
Expand Down
33 changes: 22 additions & 11 deletions Terminal.Gui/Configuration/DeepCloner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -285,21 +285,32 @@ private static object CloneDictionary (object source, ConcurrentDictionary<objec
IDictionary tempDict = CreateDictionaryInstance (dictType, comparer);
visited.TryAdd (source, tempDict);

// Clone all key-value pairs
foreach (object? key in sourceDict.Keys)
{
object? clonedKey = DeepCloneInternal (key, visited);
object? clonedValue = DeepCloneInternal (sourceDict [key], visited);

if (tempDict.Contains (clonedKey!))
{
tempDict [clonedKey!] = clonedValue;
}
else
object? lastKey = null;
try
{
// Clone all key-value pairs
foreach (object? key in sourceDict.Keys)
{
tempDict.Add (clonedKey!, clonedValue);
lastKey = key;
object? clonedKey = DeepCloneInternal (key, visited);
object? clonedValue = DeepCloneInternal (sourceDict [key], visited);

if (tempDict.Contains (clonedKey!))
{
tempDict [clonedKey!] = clonedValue;
}
else
{
tempDict.Add (clonedKey!, clonedValue);
}
}
}
catch (InvalidOperationException ex)
{
// Handle cases where the dictionary is modified during enumeration
throw new InvalidOperationException ($"Error cloning dictionary ({source}) (last key was \"{lastKey}\"). Ensure the source dictionary is not modified during cloning.", ex);
}

// If the original dictionary type has a parameterless constructor, create a new instance
if (type.GetConstructor (Type.EmptyTypes) != null)
Expand Down
2 changes: 1 addition & 1 deletion Terminal.Gui/Configuration/SourcesManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using System.Reflection;
using System.Text.Json;

namespace Terminal.Gui.Configuration;
namespace Terminal.Gui;

/// <summary>
/// Manages the <see cref="ConfigurationManager"/> Sources and provides the API for loading them. Source is a location where a configuration can be stored. Sources are defined in <see cref="ConfigLocations"/>.
Expand Down
4 changes: 4 additions & 0 deletions Terminal.Gui/Configuration/ThemeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ public static ImmutableList<string> GetThemeNames ()
/// <returns></returns>
public static string GetCurrentThemeName () { return Theme!; }

// TODO: Add a lock around Theme and Themes
// TODO: For now, this test can't run in parallel with other tests that access Theme or Themes.
// TODO: ThemeScopeList_WithThemes_ClonesSuccessfully

/// <summary>
/// Gets the Themes dictionary. <see cref="GetThemes"/> is preferred.
/// The backing store is <c><see cref="ConfigurationManager.Settings"/> ["Themes"]</c>.
Expand Down
2 changes: 1 addition & 1 deletion Terminal.Gui/ConsoleDrivers/ConsoleKeyMapping.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Globalization;
using System.Runtime.InteropServices;

namespace Terminal.Gui.ConsoleDrivers;
namespace Terminal.Gui;

// QUESTION: This class combines Windows specific code with cross-platform code. Should this be split into two classes?
/// <summary>Helper class to handle the scan code and virtual key from a <see cref="ConsoleKey"/>.</summary>
Expand Down
1 change: 0 additions & 1 deletion Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
//

using System.Runtime.InteropServices;
using Terminal.Gui.ConsoleDrivers;
using Unix.Terminal;

namespace Terminal.Gui;
Expand Down Expand Up @@ -729,7 +728,7 @@
while (wch2 == Curses.KeyMouse)
{
// BUGBUG: Fix this nullable issue.
Key kea = null;

Check warning on line 731 in Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs

View workflow job for this annotation

GitHub Actions / Parallel Unit Tests (windows-latest)

Converting null literal or possible null value to non-nullable type.

Check warning on line 731 in Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs

View workflow job for this annotation

GitHub Actions / build_and_test_debug (windows-latest)

Converting null literal or possible null value to non-nullable type.

Check warning on line 731 in Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs

View workflow job for this annotation

GitHub Actions / Non-Parallel Unit Tests (windows-latest)

Converting null literal or possible null value to non-nullable type.

ConsoleKeyInfo [] cki =
{
Expand All @@ -739,7 +738,7 @@
};
code = 0;
// BUGBUG: Fix this nullable issue.
HandleEscSeqResponse (ref code, ref k, ref wch2, ref kea, ref cki);

Check warning on line 741 in Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs

View workflow job for this annotation

GitHub Actions / Parallel Unit Tests (windows-latest)

Possible null reference assignment.

Check warning on line 741 in Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs

View workflow job for this annotation

GitHub Actions / build_and_test_debug (windows-latest)

Possible null reference assignment.

Check warning on line 741 in Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs

View workflow job for this annotation

GitHub Actions / Non-Parallel Unit Tests (windows-latest)

Possible null reference assignment.
}

return;
Expand Down Expand Up @@ -801,7 +800,7 @@
}

// BUGBUG: Fix this nullable issue.
Key key = null;

Check warning on line 803 in Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs

View workflow job for this annotation

GitHub Actions / Parallel Unit Tests (windows-latest)

Converting null literal or possible null value to non-nullable type.

if (code == 0)
{
Expand Down
15 changes: 7 additions & 8 deletions Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#nullable enable
using System.Globalization;
using static Terminal.Gui.ConsoleDrivers.ConsoleKeyMapping;

namespace Terminal.Gui;

Expand Down Expand Up @@ -1159,7 +1158,7 @@ public static ConsoleKeyInfo MapConsoleKeyInfo (ConsoleKeyInfo consoleKeyInfo)

break;
default:
uint ck = MapKeyCodeToConsoleKey ((KeyCode)consoleKeyInfo.KeyChar, out bool isConsoleKey);
uint ck = ConsoleKeyMapping.MapKeyCodeToConsoleKey ((KeyCode)consoleKeyInfo.KeyChar, out bool isConsoleKey);

if (isConsoleKey)
{
Expand Down Expand Up @@ -1415,12 +1414,12 @@ internal static KeyCode MapKey (ConsoleKeyInfo keyInfo)
if (keyInfo.Modifiers != ConsoleModifiers.Shift)
{
// If Shift wasn't down we don't need to do anything but return the keyInfo.KeyChar
return MapToKeyCodeModifiers (keyInfo.Modifiers, (KeyCode)keyInfo.KeyChar);
return ConsoleKeyMapping.MapToKeyCodeModifiers (keyInfo.Modifiers, (KeyCode)keyInfo.KeyChar);
}

// Strip off Shift - We got here because they KeyChar from Windows is the shifted char (e.g. "Ç")
// and passing on Shift would be redundant.
return MapToKeyCodeModifiers (keyInfo.Modifiers & ~ConsoleModifiers.Shift, (KeyCode)keyInfo.KeyChar);
return ConsoleKeyMapping.MapToKeyCodeModifiers (keyInfo.Modifiers & ~ConsoleModifiers.Shift, (KeyCode)keyInfo.KeyChar);
}

// Handle control keys whose VK codes match the related ASCII value (those below ASCII 33) like ESC
Expand All @@ -1431,14 +1430,14 @@ internal static KeyCode MapKey (ConsoleKeyInfo keyInfo)
return KeyCode.Tab;
}

return MapToKeyCodeModifiers (keyInfo.Modifiers, (KeyCode)(uint)keyInfo.Key);
return ConsoleKeyMapping.MapToKeyCodeModifiers (keyInfo.Modifiers, (KeyCode)(uint)keyInfo.Key);
}

// Handle control keys (e.g. CursorUp)
if (keyInfo.Key != ConsoleKey.None
&& Enum.IsDefined (typeof (KeyCode), (uint)keyInfo.Key + (uint)KeyCode.MaxCodePoint))
{
return MapToKeyCodeModifiers (keyInfo.Modifiers, (KeyCode)((uint)keyInfo.Key + (uint)KeyCode.MaxCodePoint));
return ConsoleKeyMapping.MapToKeyCodeModifiers (keyInfo.Modifiers, (KeyCode)((uint)keyInfo.Key + (uint)KeyCode.MaxCodePoint));
}

if ((ConsoleKey)keyInfo.KeyChar is >= ConsoleKey.A and <= ConsoleKey.Z)
Expand Down Expand Up @@ -1469,7 +1468,7 @@ internal static KeyCode MapKey (ConsoleKeyInfo keyInfo)
|| keyInfo.Modifiers.HasFlag (ConsoleModifiers.Control))
{
// NetDriver doesn't support Shift-Ctrl/Shift-Alt combos
return MapToKeyCodeModifiers (keyInfo.Modifiers & ~ConsoleModifiers.Shift, (KeyCode)keyInfo.Key);
return ConsoleKeyMapping.MapToKeyCodeModifiers (keyInfo.Modifiers & ~ConsoleModifiers.Shift, (KeyCode)keyInfo.Key);
}

if (keyInfo.Modifiers == ConsoleModifiers.Shift)
Expand All @@ -1484,7 +1483,7 @@ internal static KeyCode MapKey (ConsoleKeyInfo keyInfo)
return (KeyCode)keyInfo.Key;
}

return MapToKeyCodeModifiers (keyInfo.Modifiers, (KeyCode)keyInfo.KeyChar);
return ConsoleKeyMapping.MapToKeyCodeModifiers (keyInfo.Modifiers, (KeyCode)keyInfo.KeyChar);
}

private static async Task ProcessButtonClickedAsync ()
Expand Down
2 changes: 0 additions & 2 deletions Terminal.Gui/ConsoleDrivers/FakeDriver/FakeConsole.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// FakeConsole.cs: A fake .NET Windows Console API implementation for unit tests.
//

using Terminal.Gui.ConsoleDrivers;

namespace Terminal.Gui;

#pragma warning disable RCS1138 // Add summary to documentation comment.
Expand Down
1 change: 0 additions & 1 deletion Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

using System.Diagnostics;
using System.Runtime.InteropServices;
using Terminal.Gui.ConsoleDrivers;

// Alias Console to MockConsole so we don't accidentally use Console

Expand Down
1 change: 0 additions & 1 deletion Terminal.Gui/ConsoleDrivers/V2/WindowsKeyConverter.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#nullable enable
using Terminal.Gui.ConsoleDrivers;

namespace Terminal.Gui;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Collections.Concurrent;
using System.ComponentModel;
using System.Runtime.InteropServices;
using Terminal.Gui.ConsoleDrivers;

namespace Terminal.Gui;

Expand Down
Loading
Loading