Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #3692++ - Rearchitects drivers #3837

Open
wants to merge 167 commits into
base: v2_develop
Choose a base branch
from

Conversation

tznind
Copy link
Collaborator

@tznind tznind commented Nov 19, 2024

This is a super set of #3791 and exists to see diff and direction of v2 drivers as discussed in #3821

Fixes

Metrics

You can now see metrics on ant Terminal.Gui program by using its exe name and a metrics tool e.g.

 dotnet-counters monitor -n UICatalog --counters Terminal.Gui

Implementation uses System.Diagnostics.Metrics making it integrate easily with tools such as OpenTelemetry

Logging

You can enable logging of internals of Terminal.Gui by setting Logging.Logger to any Microsoft.Extensions.Logging compatible logging framework (nlog, serilog etc).

Naturally you must not use a console logger

For example with Serilog to a file:

Logging.Logger = CreateLogger ();

...

private static ILogger CreateLogger ()
{
	// Configure Serilog to write logs to a file
	Log.Logger = new LoggerConfiguration ()
				 .MinimumLevel.Verbose () // Verbose includes Trace and Debug
				 .WriteTo.File ("logs/logfile.txt", rollingInterval: RollingInterval.Day)
				 .CreateLogger ();

	// Create a logger factory compatible with Microsoft.Extensions.Logging
	using var loggerFactory = LoggerFactory.Create (builder =>
						{
							builder
								.AddSerilog (dispose: true) // Integrate Serilog with ILogger
								.SetMinimumLevel (LogLevel.Trace); // Set minimum log level
						});
	// Get an ILogger instance
	return loggerFactory.CreateLogger ("Global Logger");
}

Progress

  • Keyboard
    • Exit
    • Typing
    • Backspace
  • Views
    • Run/RequestStop
    • MenuBar
  • Mouse (see MouseInterpreter)
    • Button 1 click
    • Multi clicks
    • All buttons
    • Scroll wheel
  • Other
    • Clipboard

Proposed Changes/Todos

Splits drivers up into logical components, simplifies and centralizes shared code patterns.

image

Pull Request checklist:

  • I've named my PR in the form of "Fixes #issue. Terse description."
  • My code follows the style guidelines of Terminal.Gui - if you use Visual Studio, hit CTRL-K-D to automatically reformat your files before committing.
  • My code follows the Terminal.Gui library design guidelines
  • I ran dotnet test before commit
  • I have made corresponding changes to the API documentation (using /// style comments)
  • My changes generate no new warnings
  • I have checked my code and corrected any poor grammar or misspellings
  • I conducted basic QA to assure all features are working

@tig tig changed the title V2 drivers Fixes #3692++ - Rearchitects drivers Nov 23, 2024
@tig
Copy link
Collaborator

tig commented Nov 23, 2024

Hope you're ok with me updating the title & first post...

@tznind
Copy link
Collaborator Author

tznind commented Nov 23, 2024

Hope you're ok with me updating the title & first post...

No problem! Always appreciate a clear naming

Now we have fledgling support for

  • Keyboard
  • Mouse
  • Screen size

Net (i.e. native dotnet) and Windows (i.e win 32 api) are the two implementations - I assume we can drop curses and don't need to port?

resize-etc

@tznind tznind mentioned this pull request Nov 23, 2024
@BDisp
Copy link
Collaborator

BDisp commented Jan 14, 2025

@BDisp @tig any feedback on this PR would be appreciated.

I'm in vacancy mode sorry.

@tig
Copy link
Collaborator

tig commented Jan 15, 2025

@BDisp @tig any feedback on this PR would be appreciated.

Yes.

My lighthouse beam is focused on other things right now.

But it's swinging around and will be back on TG real soon now.

I'm really excited about this PR!

@tznind
Copy link
Collaborator Author

tznind commented Jan 18, 2025

@BDisp the EscSeqUtils.MapConsoleKeyInfo is broken for some keys e.g.

new ConsoleKeyInfo ('}', ConsoleKey.Oem6, true, false, false) 

Gets returned as

new ConsoleKeyInfo('}', ConsoleKey.None, true, false, false);

This then breaks EscSeqUtils.MapKey

MapConsoleKeyInfo and MapKey are the two methods I am chaining to turn ConsoleKeyInfo into Key

For now I am using workaround:

 /// <summary>
 /// Converts terminal raw input class <see cref="ConsoleKeyInfo"/> into
 /// common Terminal.Gui event model for keypresses (<see cref="Key"/>)
 /// </summary>
 /// <param name="input"></param>
 /// <returns></returns>
 public static Key ConsoleKeyInfoToKey (ConsoleKeyInfo input)
 {
     ConsoleKeyInfo adjustedInput = EscSeqUtils.MapConsoleKeyInfo (input);
     
     // TODO : EscSeqUtils.MapConsoleKeyInfo is wrong for e.g. '{' - it winds up clearing the Key
     //        So if the method nuked it then we should just work with the original.
     if (adjustedInput.Key == ConsoleKey.None && input.Key != ConsoleKey.None)
     {
         return EscSeqUtils.MapKey (input);
     }

     return EscSeqUtils.MapKey (adjustedInput);
 }

@tig
Copy link
Collaborator

tig commented Jan 29, 2025

Starting my review...

Some things I noticed in pulling down and running locally. This is with "ConsoleDriverFacade(win)"

  • Incorrect drawing:
    image

  • Window drag doesn't work

  • App hotkeys don't work (Ctrl-A) for UI Catalog about box.

  • Exiting UI Catalog about box causes an exception

This stuff leads me to believe this isn't really ready for merge, right?

But you want me to review the code?

@tig
Copy link
Collaborator

tig commented Jan 29, 2025

Running UICatalog "All Views Tester" -b -t 5000 --driver v2net

Shows lots of issues.

Copy link
Collaborator

@tig tig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments here.

My review was pretty superficial. I didn't actually dive deep into the tests.

What is your thinking on how we move forward with this?

It appears that unless you explicitly enable the new drivers, everything works swell.

Is the intent to merge with the new drivers "broken" and then fix them off of v2_develop?

Terminal.Gui/ConsoleDrivers/V2/Logging.cs Show resolved Hide resolved
@tznind
Copy link
Collaborator Author

tznind commented Jan 30, 2025

I would like to fix bugs. Especially any crash bugs.

Biggest issue I noticed was with menus. They seem to be 'special case' for Top and have explicit code in Application that interacts with them.

I was hoping that if we could get it so any view can have menus and they work just like any other subview - then the issues might become less opaque and/or disappear.

Let me try the all views tester. I have run many scenarios in isolation but it's unclear what some of them are meant to do upon cursory examinations.

It would be great to have help identifying the main outstanding 'show stopper bugs' in terms of behaviour.

@tznind
Copy link
Collaborator Author

tznind commented Jan 30, 2025

I want to solve all the 'driver level' bugs but then address 'view specific' issues later e.g. HexView always reporting that it NeedsLayout/NeedsRedraw constantly true.

The new 'main loop' is more trusting of the views reporting their state.

For example there are no longer any 'out of band' screen Refresh allowed. Console is only flushed/updated after loop iteration and only once (and only if a View was needs draw true).

But for that to work properly the views have to behave. The logging helps identify which views are misbehaving in this regard.

@tznind
Copy link
Collaborator Author

tznind commented Jan 30, 2025

Running UICatalog "All Views Tester" -b -t 5000 --driver v2net

I've not used this before, I will have a look into it thanks.

I also see that the behaviour of app is different when launch from UICatalog vs visual studio e.g. black colors. Maybe something to do with configuration file/paths

image

@tznind
Copy link
Collaborator Author

tznind commented Jan 30, 2025

Looks like AllView tester is double booting. And the LayoutEditor is constantly reporting true for redraw.

Probably this should be an Exception though or ignored not bad behaviour

2025-01-30 18:40:02.825 +00:00 [INF] Main Loop Coordinator booting...
2025-01-30 18:40:02.842 +00:00 [INF] Creating NetOutput
2025-01-30 18:40:02.844 +00:00 [INF] Creating NetInput
2025-01-30 18:40:02.846 +00:00 [INF] Main Loop Coordinator booting complete
2025-01-30 18:40:02.849 +00:00 [INF] Main Loop Coordinator booting...
2025-01-30 18:40:02.849 +00:00 [INF] Creating NetOutput
2025-01-30 18:40:02.849 +00:00 [INF] Creating NetInput
2025-01-30 18:40:02.849 +00:00 [INF] Main Loop Coordinator booting complete
2025-01-30 18:40:02.942 +00:00 [INF] Run 'Window(Esc to Quit - Scenario: All Views Tester){X=0,Y=0,Width=0,Height=0}'
2025-01-30 18:40:03.002 +00:00 [VRB] Window triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:03.003 +00:00 [INF] Console size changes from '{Width=0, Height=0}' to {Width=120, Height=30}
2025-01-30 18:40:03.128 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:03.184 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:03.247 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:03.309 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:03.372 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:03.434 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:03.498 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:03.561 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:03.625 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:03.688 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:03.751 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:03.813 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:03.877 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:03.940 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:04.003 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:04.067 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:04.129 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:04.191 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:04.255 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:04.318 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:04.379 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:04.442 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:04.505 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:04.568 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:04.631 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:04.691 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:04.753 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:04.814 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:04.875 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:04.938 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:04.999 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:05.061 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:05.124 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:05.186 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:05.248 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:05.311 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:05.373 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:05.436 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:05.498 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:05.552 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:05.607 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:05.670 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:05.732 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:05.794 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:05.857 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:05.919 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:05.983 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:06.045 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:06.108 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:06.171 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:06.233 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:06.296 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:06.358 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:06.420 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:06.483 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:06.545 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:06.608 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:06.669 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:06.732 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:06.793 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:06.855 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:06.918 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:06.981 +00:00 [VRB] AnsiResponseParser releasing '�'
2025-01-30 18:40:06.984 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:07.043 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:07.106 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:07.170 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:07.233 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:07.295 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:07.358 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:07.420 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:07.483 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:07.544 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:07.607 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:07.669 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:07.732 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:07.795 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:07.857 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:07.919 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:07.981 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:08.044 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:08.106 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:08.168 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:08.231 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:08.294 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:08.356 +00:00 [VRB] LayoutEditor triggered redraw (NeedsDraw=True NeedsLayout=True) 
2025-01-30 18:40:08.420 +00:00 [INF] RequestStop ''

@tig
Copy link
Collaborator

tig commented Jan 30, 2025

I would like to fix bugs. Especially any crash bugs.

Biggest issue I noticed was with menus. They seem to be 'special case' for Top and have explicit code in Application that interacts with them.

Hence the Issues and PRs around Top and rewriting Menu. See those.

I was hoping that if we could get it so any view can have menus and they work just like any other subview - then the issues might become less opaque and/or disappear.

Yes. See related menu PRs.

- Ignore double init
- Raise init changed event
@tznind
Copy link
Collaborator Author

tznind commented Jan 31, 2025

All views tester now working, was just missing raising init event. Looks like configuration manager doesnt work same either as its monochrome - I will look into this

dotnet run -- "All Views Tester" -b -t 5000 --driver v2nwin

allviews

@tznind
Copy link
Collaborator Author

tznind commented Jan 31, 2025

Colors fixed, I just wasn't calling the init on config manager from the new bootstrapping Application2 class init

private void HackLayoutDrawIfTopChanged ()
{
// TODO: This fixes closing a modal not making its host (below) refresh
// until you click. This should not be the job of the main loop!
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. That must be an Application job.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Somehow, it seems to work with the original drivers but not the v2 ones.

V2 drivers only listen to these properties (needs layout/draw). There are no manual or triggered draws, so possibly that is why this hack is needed for now.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand, but I think that if you do the same thing in the Application.LayoutAndDraw method you'll will obtain the same result, but I could be wrong.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my code, layout and draw is only called if a subview of Top wants redrawn or layed out... I will look into it some more later

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment