diff --git a/Directory.Build.props b/Directory.Build.props
index d7d9108..5ab21bf 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -12,7 +12,7 @@
gui-cs
Copyright (c) gui-cs and contributors
- 0.2.0-develop
+ 0.2.1-develop
https://github.com/gui-cs/cli
https://github.com/gui-cs/cli
git
diff --git a/src/Terminal.Gui.Cli/CliHost.cs b/src/Terminal.Gui.Cli/CliHost.cs
index db07974..73194e1 100644
--- a/src/Terminal.Gui.Cli/CliHost.cs
+++ b/src/Terminal.Gui.Cli/CliHost.cs
@@ -257,12 +257,24 @@ private async Task RunWithTerminalGuiAsync (ICliCommand command,
CancellationToken cancellationToken)
{
var useInline = command.Kind == CommandKind.Input && !runOptions.Fullscreen;
+
+ // Application.AppModel is process-wide state; restore it after dispatch so later
+ // Terminal.Gui sessions in the same process (embedding, headless rendering) do not
+ // inherit this command's app model.
+ AppModel previousAppModel = Application.AppModel;
Application.AppModel = useInline ? AppModel.Inline : AppModel.FullScreen;
- using IApplication app = Application.Create ();
- app.Init ();
+ try
+ {
+ using IApplication app = Application.Create ();
+ app.Init ();
- return await command.RunAsync (app, runOptions.Initial, runOptions, cancellationToken);
+ return await command.RunAsync (app, runOptions.Initial, runOptions, cancellationToken);
+ }
+ finally
+ {
+ Application.AppModel = previousAppModel;
+ }
}
private void WriteRootFlag (ArgParser.RootFlag rootFlag, TextWriter stdout)
diff --git a/tests/Terminal.Gui.Cli.IntegrationTests/AppModelDispatchTests.cs b/tests/Terminal.Gui.Cli.IntegrationTests/AppModelDispatchTests.cs
index 59d94de..0323ef8 100644
--- a/tests/Terminal.Gui.Cli.IntegrationTests/AppModelDispatchTests.cs
+++ b/tests/Terminal.Gui.Cli.IntegrationTests/AppModelDispatchTests.cs
@@ -5,10 +5,85 @@ namespace Terminal.Gui.Cli.IntegrationTests;
///
/// Verifies that CliHost.RunWithTerminalGuiAsync sets IApplication.AppModel
-/// correctly based on CommandKind and the --fullscreen option.
+/// correctly based on CommandKind and the --fullscreen option, initializes the
+/// application before dispatching (issue #18), and restores the process-wide
+/// Application.AppModel after dispatch (issue #26).
///
public sealed class AppModelDispatchTests
{
+ [Fact]
+ public async Task InputCommand_Inline_ReceivesInitializedApplication ()
+ {
+ // ICliCommand.RunAsync contract: commands run after the host has initialized
+ // Terminal.Gui, including on the inline input path (issue #18).
+ bool? initialized = null;
+ SpyInputCommand spy = new (app => initialized = app.Initialized);
+
+ CliHost host = new ();
+ host.Registry.Register (spy);
+ using StringWriter stdout = new ();
+ using StringWriter stderr = new ();
+
+ await host.RunAsync (["spy-input"], TestContext.Current.CancellationToken, stdout, stderr);
+
+ Assert.True (initialized);
+ }
+
+ [Fact]
+ public async Task InputCommand_Inline_RestoresAppModelAfterDispatch ()
+ {
+ // Application.AppModel is process-wide; leaving it set to Inline after dispatch
+ // makes later Terminal.Gui sessions in the same process inherit it (issue #26).
+ AppModel before = Application.AppModel;
+
+ try
+ {
+ Application.AppModel = AppModel.FullScreen;
+ SpyInputCommand spy = new (_ => { });
+
+ CliHost host = new ();
+ host.Registry.Register (spy);
+ using StringWriter stdout = new ();
+ using StringWriter stderr = new ();
+
+ await host.RunAsync (["spy-input"], TestContext.Current.CancellationToken, stdout, stderr);
+
+ Assert.Equal (AppModel.FullScreen, Application.AppModel);
+ }
+ finally
+ {
+ Application.AppModel = before;
+ }
+ }
+
+ [Fact]
+ public async Task InputCommand_ThrowsCancellation_RestoresAppModel ()
+ {
+ // The restore must also happen when the command throws (issue #26).
+ AppModel before = Application.AppModel;
+
+ try
+ {
+ Application.AppModel = AppModel.FullScreen;
+ SpyInputCommand spy = new (_ => throw new OperationCanceledException ());
+
+ CliHost host = new ();
+ host.Registry.Register (spy);
+ using StringWriter stdout = new ();
+ using StringWriter stderr = new ();
+
+ var exitCode = await host.RunAsync (["spy-input"], TestContext.Current.CancellationToken, stdout,
+ stderr);
+
+ Assert.Equal (ExitCodes.Cancelled, exitCode);
+ Assert.Equal (AppModel.FullScreen, Application.AppModel);
+ }
+ finally
+ {
+ Application.AppModel = before;
+ }
+ }
+
[Fact]
public async Task InputCommand_WithoutFullscreen_SetsInlineAppModel ()
{