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

Fixing escape key getting filtered on Windows #3304

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

Neko-Box-Coder
Copy link
Contributor

This should fix #2947

I will put a comment once I have tested this on a Windows and Linux machine.

This should fix zyedidia#2947
I will test this on a Windows machine and Linux machine
@Neko-Box-Coder
Copy link
Contributor Author

Just tested both on Windows and Linux. It indeed fixes the problem for Windows and doesn't affect Linux.
Someone else can test this if needed. Otherwise I think we can merge this small fix @dmaluka @JoeKar

@Neko-Box-Coder
Copy link
Contributor Author

Neko-Box-Coder commented May 20, 2024

I have changed the test to simulate windows behavior to get it pass. I have searched the codebase on how we are handling escape for a few hours but just left me scratching my head to be honest.

I don't understand why it breaks for Linux when rune is set to 27 (that special case) because it is just additional information, we still have the key code set to escape anyway.

And somehow Windows is the exact opposite which requires that extra rune.

I guess it is because we are doing exact match so that additional rune information causes it to not match? I have no idea.

I am open to any suggestions, I have tested it both on Linux and Windows so it is working.

Comment on lines +181 to +182
// Special case for escape for unix, for some reason tcell doesn't send it with the esc character
if code < 256 && (runtime.GOOS == "windows" || code != 27) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is nothing we should handle within micro (at least not here with a GOOS check), because it's exactly what tcell is used for...it abstracts the terminal/-input.

From my perspective the correct way would be to handle it consistent within tcell, e.g. by...
https://github.com/zyedidia/tcell/blob/450b22f579b33147c4013c18db0fb33391d6e01d/console_win.go#L644-L650

...setting the NewEventKey(KeyEscape, 0, ModNone, "") in case krec.ch == vkEscape like here...
https://github.com/zyedidia/tcell/blob/450b22f579b33147c4013c18db0fb33391d6e01d/tscreen.go#L1574
...which works too.

@gdamore:
Hopefully it's ok to add you once more here...
Am I right that the upstream ESC key handling is still slightly different between Linux and Windows?
At least I can't find a big difference between the fork and your main regarding this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't know we are using zyedida's tcell until you mentioned it. Why are we not using upstream's tcell?

Not having escape working out of the box is quite a big turn off I think and for me this is a major issue (For example cannot abort a command or have to choose between overwrite or discard what I have when the file gets updated by something else).

I would like to at least get this sorted when we release v2.0.14, given that we have (seem to be) 1 item left before releasing.

I don't mind creating a PR for the tcell we are using as long as it can get merged quickly by zyedidia, though I don't know how likely this will be.

I agree this should be handled by tcell and should not have a special case.

But if there are no other options that can resolve this before the release, would this workaround be good enough for now and we can create an issue(s) to resolve this properly?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I fully agree, that the current ESC behavior within the windows builds is fully broken. It doesn't work at (most probably) every place where it should. Especially in the moments a prompt is active, which gives the advice to press esc. I tested it yesterday by my own and was quite surprised that it's broken over such a long time span.

You provided a workaround...which works...but the problem with such "fixes" is that they sometimes stay longer as they should especially when the generalization is already spotted at a different location (at least from my perspective).

As you discovered the workaround needs an adaption within the tests too, which isn't that nice.

For me the most important question is:
Should tcell treat these key codes (!= KeyRune) in general with or without the related rune/character?

@dmaluka:
What's your opinion about the workaround provided with this PR?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I would like to at least get this sorted when we release v2.0.14, given that we have (seem to be) 1 item left before releasing.

Don't worry, 1 item left doesn't mean that v2.0.14 release is gonna happen soon. We don't know when will it happen.

Copy link

Choose a reason for hiding this comment

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

So I'm a little confused here. There shouldn't really be a difference between Linux and Windows, except that in the case of Linux we have to scan for a bit because it might be a lone escape key, or it might be part of an escape sequence. (There is a plan to use some new style reporting that doesn't suffer this ambiguity, but I just haven't had time to do the work.)

Certainly, applications should not have to have different handling for this key.

Copy link

Choose a reason for hiding this comment

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

In fact, looking at this block makes me very sad.

I understand why it exists... because Control key handling is so different between Windows and legacy TTY based terminals. I intend to fix all that, but the change will probably be breaking for some applications.

Copy link

Choose a reason for hiding this comment

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

In fact, this whole block seems misguided if I understand it correctly. Codes < 32 (the space character) should not be considered as possible control sequences (mixed with the control key) -- they are in fact sometimes control keys (e.g. Control-I is also the TAB sequence). This is the problem with these sequences ... on UNIX ttys you cannot easily discriminate between someone pressing Control-I (for example) or hitting TAB.

Modern terminals do have a reporting scheme that fixes this, but it is incompatible with legacy apps, and tcell has not been updated for the new style reporting.

I apologize for this mess -- had I had a clearer picture about this years ago, I would not have conflated these.

I will disentangle them, but not today.

Having said that, code 27 is ESCAPE, and corresponds to Control-] -- you should not allow anyone to bind a key to that. It will break lots of stuff. :-)

Note that some key bindings, such as Control-J -- will be impossible to make work portably because of the legacy conflation (in that case it's a new line). Again I hope to fix that, but it will only be supported in "new" terminals that support the new reporting. (This conflation does not exist for Windows.)

Comment on lines +197 to +198
// Special case for escape for unix, for some reason tcell doesn't send it with the esc character
if code < 256 && (runtime.GOOS == "windows" || code != 27) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

ditto

@Neko-Box-Coder
Copy link
Contributor Author

Neko-Box-Coder commented May 24, 2024

@JoeKar
So currently the proposed solution is to create different event key depending on OS which we match later when user invokes any event.

Alternatively, I can try to handle the escape case when we process the event like what I proposed similarly in #3305 where I tried different combinations (i.e. both the escape keycode or the escape rune or both) unless we match something.

In which case we can avoid an OS check all together and I don't need to modify the test file.

However, this still doesn't change the fact that we are handling special cases and the more I think about it, the less I am sure if this is an upstream problem as tcell is just spitting out things on what it receives without modifying it (mostly)

I am happy to do whatever to get this merged quickly.
I do apologize to be frequently replying and raising issues/PRs as I am an impatient guy 😅

Would the solution I mentioned above be better or do we need more time for people to decide what to do with this?

@JoeKar
Copy link
Collaborator

JoeKar commented May 24, 2024

So currently the proposed solution is to create different event key depending on OS which we match later when user invokes any event.

No, I proposed that micro should receive the same key under both OSs and that this should be abstracted by tcell.
tcell should generate it either with or without rune for both, but not different between those.
I already tried it without the rune in Windows, where it then worked without further modification of micro.

@gdamore
Copy link

gdamore commented May 24, 2024 via email

@Neko-Box-Coder
Copy link
Contributor Author

@JoeKar
Yep cool. I can apply what you proposed to tcell to fix this problem. But we will need to update tcell. I don't think I can get my PR merged quickly if I want to update the one we are using, unless @zyedidia is available to do so.

Otherwise should I try to get micro working with upstream tcell or do we want to fork our current tcell and apply the changes?

@JoeKar
Copy link
Collaborator

JoeKar commented May 25, 2024

@JoeKar Yep cool. I can apply what you proposed to tcell to fix this problem.

You can patch your local copy of tcell with win-esc.patch.txt and rebuild micro.
I was waiting for the confirmation/correction upstream, to directly propose the original backport.

But we will need to update tcell. I don't think I can get my PR merged quickly if I want to update the one we are using, unless @zyedidia is available to do so.

Correct, only he can do the merges in the currently used tcell.

Otherwise should I try to get micro working with upstream tcell or do we want to fork our current tcell and apply the changes?

No, the upstream version wouldn't work oob, since the fork was done to add some additional changes not present upstream (e.g. the raw escape sequences).
Zachary already created a much newer fork (see micro-editor/tcell vs zyedidia/tcell) within the micro-editor organization. Maybe it's common in the near future, that we switch to that. But even there we can't perform merges yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Windows: ESC key only works in "raw" tab (regression, patch inside)
4 participants