Comments (19)
@BDisp thanks again for all your time; I am dopping this for now, using v1.16
In reply to your last lengthy reply
You say: Application.Init() is only required once at your start application. I put in the Popup class because I supposed you have only that class which run TGui.
Application.Init() is in Program.cs; this is a retro text editor --
many classes use Terminal.gui !!!
You say: You are running on Windows in a terminal? Do you are running on another application and call the Popup app with a Process.Start? You need to provide more information because running as your instructions I don't have any exception. What is your OS?
OS = Windows 11; I execute exe headless from Windows Terminal
$ wt -f --pos "200,100" Terminal.exe ......\doc\bug-report.txt
** You are mistaken thinking I "call the Popup app with Process.Start." The shell/spawn has nothing to do with Popup; Popup only displays the text output from the spawn.
** I wrote a test program for the Process.Start; it runs w/o error on 1.17.0
You say: I had to use the [STAThread] to avoid the exception on the call to
System.Windows.Forms.Clipboard.SetText(allText);. // Did you use it too?
YES--
[STAThreadAttribute]
public static void Main(string[] args) {
Terminal.Gui.Application.Init();
...
}
I say: @dodexahedron says he has encountered this problem and "it's avoidable by using a plain Window instead of a Dialog and just using Show instead of Application.Run on it."
You say "I think it would not fix your issue, because it was another problem with a windows refresh not being centering a Window because he was calling the Show method that belongs to the Toplevel of the TGui, which only work if the Toplevel is a MdiContainer and also had some TGui bugs that was then fixed. "
You are correct I'm sure; I did not waste time trying it.
##
## One last thing to try ...
##
got rid of all refs to WindowsForms
FW= net6.0 not net6.0-windows
set Active Config=Release
clean/rebuild
v1.16 ok
v1.17 fails
from terminal.gui.
I created another console project that call the Popup from a process and it run without throwing any exception, by debugging or launching from a terminal.
.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
Program.cs:
using System.Diagnostics;
try
{
using Process process = new Process();
process.StartInfo.UseShellExecute = false;
process.StartInfo.FileName = @"..\..\..\..\PopupDialog\bin\Debug\net6.0-windows\PopupDialog.exe";
process.Start();
process.WaitForExit();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
from terminal.gui.
I suggest looking at the changes from v1.16 to v1.17 and backing each potential cause out to see if you can figure out what caused the change in behavior.
from terminal.gui.
$ wt -f --pos "200,100" Terminal.exe ......\doc\bug-report.txt
I was able to run through the command using TG v1.17.0.
wt -f "path-to-the-exe-file"
It could be some code that is not compatible with v1.17.0, perhaps due to a fixed bug or breaking change which should not have happened. If you could share the code on github, maybe I could help.
from terminal.gui.
This Main
code works:
Application.Init ();
var popup = new Popup ("Popup test!");
popup.Show ();
Application.Shutdown ();
In the Popup
class you have to change the line System.Windows.Forms.Clipboard.SetText (allText);
with Clipboard.Contents = allText;
.
from terminal.gui.
I am using System.Windows.Forms.Clipboard.SetText() because I have
using System.Windows.Forms;
in Program.cs
Again my code works as is with 1.16.0 not 1.17.0
Why should it matter? I can try your
Clipboard.Contents = allText;
in 1.17.0 but if what I have fails I think it should fail in both.
from terminal.gui.
Where you are using Application.Init ();
? This is important to initialize the driver. Can you try using net 7.0 or net 8.0?
from terminal.gui.
v1 calls InternalInit, which sets up the driver, in Run, ultimately, specifically when it reaches Run<T>
, if _initialized == false.
If he's running it within his application already, the driver should already be set up. He's got a working application, so that's already the case. He's just hitting the problem on trying to show a new dialog.
I've encountered that same sort of issue in v1.
Generally, showing a Dialog in an already-running application seems to have that problem, in certain scenarios that I've not traced (I had actually asked a similar question quite a while back, before I started helping out with V2, in fact), and it's avoidable by using a plain Window instead of a Dialog and just using Show instead of Application.Run on it.
Window.Modal can be set if a modal "dialog" type behavior is wanted.
Application.Driver is static, so calling Init again will not do anything new with the driver.
from terminal.gui.
One thing I implemented was Emacs shell-command which shells the DOS command specified by the user and displays the output in a popup
How are you executing the process? There are some important things to consider:
- No native process output should be written to the console (i.e. you must capture all I/O streams)
- Any async calls that update the UI (e.g. events from process) need to be wrapped with See Application.MainLoop.Invoke
from terminal.gui.
@dodexahedron if I remember correctly you used a class derived from Toplevel
where you used the Show
method without having set the IsMdiContainer
property to true, because this method is only used in these conditions. As you used Application.Run<T>
then the driver was automatically loaded.
In this case, the Popup
class is not derived from View
and contains the Show
method to create a Dialog
that is executed by calling Application.Run(dialog);
, hence my question. Unless Application.Init
has already been called explicitly or implicitly, in another routine that @muencht did not show.
But it appears that the exception references 'start' and @tznind may be right in thinking that this is being executed through a process.
from terminal.gui.
@muencht the bellow code works using System.Windows.Forms
and Terminal.Gui v1.17.0
. Now your Popup
class is derived from Dialog
. Maybe the error is due to the shell-command and thus can you provide the code how you are calling from it, please. Thanks
.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<UseWindowsForms>true</UseWindowsForms>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Terminal.Gui" Version="1.17.0" />
</ItemGroup>
</Project>
Program.cs:
using Terminal;
internal static class Program
{
[STAThread]
static void Main()
{
new Popup($"Popup{Environment.NewLine}Dialog{Environment.NewLine}Test!");
}
}
Popup.cs:
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Class: popup
//
// A popup derived from Dialog; the purpose here is to display output from shell-command
//
// new Popup(string text)
//
////////////////////////////////////////////////////////////////////////////////////////////////////
using Terminal.Gui;
using Application = Terminal.Gui.Application;
using BorderStyle = Terminal.Gui.BorderStyle;
using Button = Terminal.Gui.Button;
using ListView = Terminal.Gui.ListView;
using MessageBox = Terminal.Gui.MessageBox;
namespace Terminal
{
class Popup : Dialog
{
// Constructors
public Popup() : this (String.Empty) { }
public Popup(string text)
{
Application.Init();
Title = "Output from shell-command";
Width = Dim.Percent(70f);
Height = Dim.Fill();
Border = new Border()
{
BorderStyle = BorderStyle.Rounded,
DrawMarginFrame = true,
Effect3D = false,
};
ColorScheme = Colors.Dialog;
// convert text to List<>
List<string> list = text.Split(new[] { Environment.NewLine },
StringSplitOptions.None).ToList();
ListView listView = new ListView(list)
{
AllowsMultipleSelection = true,
LayoutStyle = LayoutStyle.Computed,
TextAlignment = TextAlignment.Centered,
X = Pos.At(5),
Y = Pos.At(3),
Width = Dim.Fill(2),
Height = Dim.Percent(80)
};
Add(listView);
// btn to copy to clipboard
Button btnCopy = new Button("Copy")
{
X = Pos.AnchorEnd(8),
Y = Pos.AnchorEnd(2)
};
string allText = "";
btnCopy.Clicked += () => {
allText = "";
for (int i = 0; i < list.Count; i++)
{
listView.SelectedItem = i;
}
// copy to clipbd
System.Windows.Forms.Clipboard.SetText(allText);
MessageBox.Query("Text copied to clipboard.", $"{Environment.NewLine}{allText}", "Ok");
};
listView.SelectedItemChanged += (args) => {
allText += list[listView.SelectedItem] + Environment.NewLine;
};
Add(btnCopy);
// btn to click when done
Button btnClose = new Button("Close")
{
X = Pos.Center(),
Y = Pos.AnchorEnd(1)
};
btnClose.Clicked += () => {
Application.RequestStop();
};
Add(btnClose);
try
{
Application.Run(this);
}
catch (Exception ex)
{
// is ignored
MessageBox.Query(30, 6, "Error", ex.Message, "Ok");
}
Application.Shutdown();
}
}
}
from terminal.gui.
@BDisp thanks for your time spent on this. I made the following changes to class Popup
-
class Popup : Dialog (derived from) <=
better_ but I think what I had should be ok
I have done this many times in core C# -
eliminated .Show() (I like it)(kept it)
this is the way C# does it Form.Show()
-
has Application.Init() in class <=
is this required in every class that uses TGui?
.. not just the main class (here Program) -
Application.Run(this) <=
-
added Application.Shutdown() at end <=
Test #1 (1.16.0) Runs
Test #2 (1.17.0) System.ArgumentException: 'start'
Test #3 (1.17.0) Removed .Show() and put all code in constructor as you have it
System.ArgumentException: 'start'
You said "Maybe the error is due to the shell-command and thus can you provide the code how you are calling from it, please. "
I can't believe this is the problem; I am using the standard System.Diagnostics.Process spawn ... If it is the problem, how can it work in 1.16.0 -?-
The only other difference I can see is your class Program
[STAThread]
static void Main()
{
new Popup($"Popup{Environment.NewLine}Dialog{Environment.NewLine}Test!");
}
where as I said I invoke thus
Popup popup = new Popup(output);
I'm tired of fighting this and will use 1.16.0 until a new version comes out (is one planned?). However I will try a suggestion from @dodexahedron who says he has encountered this problem and
"it's avoidable by using a plain Window instead of a Dialog and just using Show instead of Application.Run on it."
from terminal.gui.
@BDisp thanks for your time spent on this. I made the following changes to class Popup
You welcome.
- class Popup : Dialog (derived from) <=
better_ but I think what I had should be ok
I have done this many times in core C#
But in your case you can't say that is derived from Dialog
because it's a class that create a Dialog
in the Show
method. So it is different.
- eliminated .Show() (I like it)(kept it)
this is the way C# does it Form.Show()
I understand. In this case you can only move the run code to the Show method, like this:
public void Show()
{
try
{
Application.Run(this);
}
catch (Exception ex)
{
// is ignored
MessageBox.Query(30, 6, "Error", ex.Message, "Ok");
}
finally
{
Application.Shutdown();
}
}
- has Application.Init() in class <=
is this required in every class that uses TGui?
.. not just the main class (here Program)
Application.Init()
is only required once at your start application. I put in the Popup class because I supposed you have only that class which run TGui. It's only required when you use the parameter-less method Application.Run()
or the Application.Run(MyTopView)
. If you use the generic one Application.Run<MyTopView>()
you don't need to use it because the InternalInit
will be call to initialize the driver.
- Application.Run(this) <=
Right, now it's a derived class from Dialog and so the this
is used.
- added Application.Shutdown() at end <=
Application.Shutdown()
is also need to call once when the application exit which perform cleanup and restore the terminal. I put it in the Popup
class because I supposed you only that use it, otherwise must be in the class which start calling the TGui.
Test #1 (1.16.0) Runs
Test #2 (1.17.0) System.ArgumentException: 'start'
In my case with the same code as I already submitted using the TG v1.17.0, is running without error. You are running on Windows in a terminal? Do you are running on another application and call the Popup app with a Process.Start? You need to provide more information because running as your instructions I don't have any exception. What is your OS?
Test #3 (1.17.0) Removed .Show() and put all code in constructor as you have it System.ArgumentException: 'start'
That is expected, because the execution is the same.
You said "Maybe the error is due to the shell-command and thus can you provide the code how you are calling from it, please. "
I can't believe this is the problem; I am using the standard System.Diagnostics.Process spawn ... If it is the problem, how can it work in 1.16.0 -?-
That's a start. May be is the cause but please explain how you are using the System.Diagnostics.Process
spawn to I could perform some test. Thus maybe some of TGui v1.17.0 code that was changed from the previous version is causing this, but you need to tell me how you are proceeding to achieve that error. That way maybe I can help you.
The only other difference I can see is your class Program
[STAThread] static void Main() { new Popup($"Popup{Environment.NewLine}Dialog{Environment.NewLine}Test!"); }
where as I said I invoke thus
Popup popup = new Popup(output);
I had to use the [STAThread]
to avoid the exception on the call System.Windows.Forms.Clipboard.SetText(allText);
. Did you use it too?
I'm tired of fighting this and will use 1.16.0 until a new version comes out (is one planned?). However I will try a suggestion from @dodexahedron who says he has encountered this problem and
"it's avoidable by using a plain Window instead of a Dialog and just using Show instead of Application.Run on it."
I think it would not fix your issue, because it was another problem with a windows refresh not being centering a Window because he was calling the Show method that belongs to the Toplevel
of the TGui, which only work if the Toplevel
is a MdiContainer
and also had some TGui bugs that was then fixed.
But if you want to make a quick test you can change your derived class to Popup : Window
or Popup : Toplevel
.
from terminal.gui.
I suggest looking at the changes from v1.16 to v1.17 and backing each potential cause out to see if you can figure out what caused the change in behavior.
For anyone unfamiliar with the feature, you can use the blame
feature in git or github to do exactly this.
It's kind of a silly named command, but fits right in with how git itself was named in the first place. 😆
(Git is pronounced "jit," as in short for "idiot." Thank Linus Torvalds for that one.)
from terminal.gui.
But someone can explain to me why my code that is using the same source and the same TG version isn't throwing any exception? The only main changes that could affect is the adding of the net 8.0 and the netstandard 2.0. But my code isn't failing at all.
from terminal.gui.
That's a good question, and really just requires debugging in-situ plus walking back through the commits to find out what's going on.
Chances are it's just some subtle issue in the application's code which was uncovered by or made more likely to happen by fixes in TG, rather than an actual new bug in TG, but only tracing it can answer it definitively.
There are some idiosyncrasies with v1 that don't have supporting documentation and which can be very unintuitive for various reasons, especially as the consuming application grows in size and complexity. 🤷♂️
from terminal.gui.
I can't debug it to find the cause of an anomaly if I don't have the anomaly that @muencht reported. I believe he is facing this dilemma but I was unable to reproduce it to be able to detect it.
from terminal.gui.
Is this a real bug?
from terminal.gui.
Is this a real bug?
I don't think so.
from terminal.gui.
Related Issues (20)
- Make the PowerShell modules arch-agnostic for now HOT 3
- Fail gracefully for impossible hosts HOT 4
- Rename `StateChangedEventArgs<T>` to `CancelEventArgs<T>` HOT 63
- A more reliable means of avoiding errors caused by stdin or stdout redirection
- (Internal) Better regexes for TODO-list items
- Clicking the StatusBar causes the event to be executed more than once. HOT 1
- `Dim.Auto (Content)` is broken if subviews use `Pos.Center` etc... HOT 3
- `StatusBar` should clip, not overwrite, when last item doesn't fit HOT 1
- `TextField` prevents default `Button` from working in some cases HOT 7
- Some more prep for revamped sourcegens and CI HOT 2
- Enabling trim mode breaks program at runtime (v2 only) HOT 16
- v1 - Example.cs does not work HOT 5
- `Button` with `ShadowStyle.Opaque` is broken HOT 5
- `DateField` unit tests fail on `macos.latest` HOT 4
- The exclusion of `.orig` files in `.gitignore` is no longer working
- Color ToString returns "Red" instead of "# HOT 4
- Release v1.17.1 HOT 1
- Localization not working on self-contained single-file. HOT 19
- Post-V2: Rewrite `TextFormatter`
- Feedback: Example HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from terminal.gui.