GraphicalTools: OCGV: Sometimes exits as soon as arrow key is pressed

Prerequisites

  • Write a descriptive title.
  • Make sure you are able to repro it on the latest version
  • Search the existing issues.

Steps to reproduce

This one seems a bit random but ive managed to isolate it a block of code i think can trigger it sometimes. It might take a good few runs of the below code to get it to happen.

$list=@(1..100)
$count =0
do{
[PSCustomObject]$platform = $list  | Out-consoleGridView -verbose -OutputMode Single -Title $count
$platform.name.split()
Write-Host "fgfg"
$count ++
}
while ($count -lt 3)
Write-Host "gh"

I know the split will error on this by design as it seems to help trigger this more often.

What should happen is when running this loop with F8 in VS code sometime the first iteration will skip when you try to arrow down to select one in the list.

Version used is master compiled from source but same exact thing happens with 0.6.2

Expected behavior

OCGV not to skip

Actual behavior

occasionally OCGV exits without allowing you to select anything

Error details

Exception             : 
    Type        : System.Management.Automation.RuntimeException
    ErrorRecord : 
        Exception             : 
            Type    : System.Management.Automation.ParentContainsErrorRecordException
            Message : You cannot call a method on a null-valued expression.
            HResult : -2146233087
        CategoryInfo          : InvalidOperation: (:) [], ParentContainsErrorRecordException
        FullyQualifiedErrorId : InvokeMethodOnNull
        InvocationInfo        : 
            ScriptLineNumber : 3
            OffsetInLine     : 1
            HistoryId        : -1
            Line             : $platform.name.split()
                               
            PositionMessage  : At line:3 char:1
                               + $platform.name.split()
                               + ~~~~~~~~~~~~~~~~~~~~~~
            CommandOrigin    : Internal
        ScriptStackTrace      : at <ScriptBlock>, <No file>: line 3
    TargetSite  : System.Object CallSite.Target(System.Runtime.CompilerServices.Closure, 
System.Runtime.CompilerServices.CallSite, System.Object)
    Message     : You cannot call a method on a null-valued expression.
    Data        : System.Collections.ListDictionaryInternal
    Source      : Anonymously Hosted DynamicMethods Assembly
    HResult     : -2146233087
    StackTrace  : 
   at CallSite.Target(Closure , CallSite , Object )
   at System.Management.Automation.Interpreter.DynamicInstruction`2.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
CategoryInfo          : InvalidOperation: (:) [], RuntimeException
FullyQualifiedErrorId : InvokeMethodOnNull
InvocationInfo        : 
    ScriptLineNumber : 3
    OffsetInLine     : 1
    HistoryId        : -1
    Line             : $platform.name.split()
                       
    PositionMessage  : At line:3 char:1
                       + $platform.name.split()
                       + ~~~~~~~~~~~~~~~~~~~~~~
    CommandOrigin    : Internal
ScriptStackTrace      : at <ScriptBlock>, <No file>: line 3

Environment data

Name                           Value
----                           -----
PSVersion                      7.2.6
PSEdition                      Core
GitCommitId                    7.2.6
OS                             Darwin 21.6.0 Darwin Kernel Version 21.6.0: Wed Aug 10 14:28:23 PDT 2022; root:xnu-8020.141.5~2…
Platform                       Unix
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Version

0.6.3

Visuals

Screen Recording 2022-08-21 at 21 49 08

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 30 (1 by maintainers)

Most upvoted comments

Yep did that and can confirm this fixes it

Found these docs (see below) on the feature I think you are talking about @BDisp. Looks like you can change the setting at runtime with an Environment Variable e.g.

export ESCDELAY=1

Set time taken to release an Escape keystroke to 1ms

I tested setting it to 2000 and saw Esc being delayed so it seems to work.

Although from the docs docs it sounds like the same setting interacts with mouse events:

Environment

The following environment symbols are useful for customizing the runtime behavior of the ncurses library. The most important ones have been already discussed in detail.

[…]

ESCDELAY Specifies the total time, in milliseconds, for which ncurses will await a character sequence, e.g., a function key. The default value, 1000 milliseconds, is enough for most uses. However, it is made a variable to accommodate unusual applications. The most common instance where you may wish to change this value is to work with slow hosts, e.g., running on a network. If the host cannot read characters rapidly enough, it will have the same effect as if the terminal did not send characters rapidly enough. The library will still see a timeout.

Note that xterm mouse events are built up from character sequences received from the xterm. If your application makes heavy use of multiple-clicking, you may wish to lengthen this default value because the timeout applies to the composed multi-click event as well as the individual clicks.

In addition to the environment variable, this implementation provides a global variable with the same name. Portable applications should not rely upon the presence of ESCDELAY in either form, but setting the environment variable rather than the global variable does not create problems when compiling an application.

_https://linux.die.net/man/3/ncurses_

The other potential culprit is the “hack” in OCGV that resets the “Application Cursor” by emitting an ANSI ESC sequence when it closes: https://github.com/PowerShell/GraphicalTools/blob/76dbfcef5c099b8e4a73a55fde6e3f0ff37fb15b/src/Microsoft.PowerShell.ConsoleGuiTools/ConsoleGui.cs#L403

The thought (which may be way off base) is that this ESC sequence is getting echo’d back and causing OCGV to think the user pressed the ESC key.

Thinking better I bet that this is really the culprit, because the CursesDriver already do all clean up on exit to restore the terminal. Sending more escape sequences after exit will getting echoed back and reinitialize the CursesDriver again, like it never close. Try remove it.

Just commented out that line, Still happens unfortunately

@Tigger2014 - did this issue ever reproduce for you when the ESC key was not involved?

Do you have repro that involves ONLY the arrow key causing the cmdlet to exit?

I’ve seen it happen when i think the esc key wasn’t involved but it’s not code i can share unfortunately. Im also not 100% sure ESC wasn’t touched.