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

Incorrect Shift / Meta / Control bits set in xterm mouse mode #8291

Closed
chaosemer opened this issue Nov 16, 2020 · 11 comments · Fixed by #8379
Closed

Incorrect Shift / Meta / Control bits set in xterm mouse mode #8291

chaosemer opened this issue Nov 16, 2020 · 11 comments · Fixed by #8379
Assignees
Labels
Area-VT Virtual Terminal sequence support Impact-Correctness It be wrong. Issue-Bug It either shouldn't be doing this or needs an investigation. Priority-2 A description (P2) Product-Conhost For issues in the Console codebase Product-Terminal The new Windows Terminal. Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release.
Milestone

Comments

@chaosemer
Copy link

chaosemer commented Nov 16, 2020

Environment

  • Windows build number: Microsoft Windows [Version 10.0.19042.630]
  • Windows Terminal version (if applicable): 1.4.3141.0
    • (This also applies to the legacy Windows Command Prompt app.)
  • Debian version (cat /etc/debian_version): 10.6

Steps to reproduce

  1. Run debian.
  2. Enable xterm mouse tracking mode:
    $ echo -e '\e[?1000h'
  3. Click on the upper right-most character with the left mouse button. Try doing this with a mix of Ctrl, Alt, and/or Shift held down.

Expected behavior

Per https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking, we should get back six characters on a mouse button down event followed by an additional six characters on a mouse button up event. The first three characters (ESC [ M) will not be displayed, only the last three characters per event get displayed - this is not a bug, it is just important to understand.

  • A mouse button 1 down event with no modifiers held should display the following three characters: Space ! !
  • A mouse button 1 down event with control held should display the following three characters: 0 ! !
  • A mouse button 1 down event with alt held should be treated as meta and display the following three characters: ( ! !
  • A mouse button 1 down event with shift held should display the following three characters: $ ! !
  • A mouse button 1 down event with control and alt held should display the following three characters: 8 ! !

Actual behavior

  • With control held, you get ( ! ! as if meta is held.
  • With alt held, you get Space ! !, as if nothing is held.
  • With shift held, you select characters (This is likely not a bug, just an override that I did not disable.)
  • With control and alt held, you get ( ! !, as if only meta is held.
@ghost ghost added Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting Needs-Tag-Fix Doesn't match tag requirements labels Nov 16, 2020
@DHowett
Copy link
Member

DHowett commented Nov 16, 2020

Whoa. You're right. How did we miss this?

@DHowett
Copy link
Member

DHowett commented Nov 16, 2020

// Next three bits indicate modifier keys:
// 0x04 - shift (This never makes it through, as our emulator is skipped when shift is pressed.)
// 0x08 - ctrl
// 0x10 - meta

// Shift will never pass through to us, because shift is used by the host to skip VT mouse and use the default handler.
// TODO: MSFT:8804719 Add an option to disable/remap shift as a bypass for VT mousemode handling
// xvalue += (modifierKeyState & MK_SHIFT) ? 0x04 : 0x00;
xvalue += (modifierKeyState & MK_CONTROL) ? 0x08 : 0x00;
// Unfortunately, we don't get meta/alt as a part of mouse events. Only Ctrl and Shift.
// xvalue += (modifierKeyState & MK_META) ? 0x10 : 0x00;

That's not great.

@DHowett DHowett added Area-VT Virtual Terminal sequence support Product-Conhost For issues in the Console codebase Product-Terminal The new Windows Terminal. Impact-Correctness It be wrong. Issue-Bug It either shouldn't be doing this or needs an investigation. Priority-2 A description (P2) labels Nov 16, 2020
@ghost ghost removed the Needs-Tag-Fix Doesn't match tag requirements label Nov 16, 2020
@DHowett DHowett added this to the Terminal v1.6 milestone Nov 16, 2020
@chaosemer
Copy link
Author

Yup. The control fix is easy enough. It's just wrong in those comments and code. Control should add 0x10 and meta should add 0x08.

@DHowett
Copy link
Member

DHowett commented Nov 17, 2020

I'm alarmed that we missed this for every windows release after (and including) 14393! It was introduced broken back then 😄 and hasn't been caught, or fixed, since.

I guess I have to recommend SGR encoding for now. ☹️

EDIT: I rescind the frowning face above since SGR encoding is superior in every way.

@DHowett DHowett removed the Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting label Nov 17, 2020
@jdebp
Copy link

jdebp commented Nov 17, 2020

The ECMA-48 conformant format of DEC private mode 1006 is indeed the better format of mouse report, and isn't just a "for now" recommendation, really. It's a "from now on" recommendation.

Yes, a terminal emulator should get the mouse report formats of DEC private modes 9, 1005, and 1015 right if it supports them at all, but they are part of an evolutionary process that the world of XTerm and RXVT went through back around 2010 to 2012, with DEC private mode 1006, and the conseqential private control sequence CSI < M , being the upshot.

Applications that use terminfo will nowadays use DEC private mode 1006 on a wide variety of terminal types, from genuine XTerm through iTerm2 and Konsole to libVTE terminal emulators, and won't in fact use DEC private modes 1005 or 1015 on any terminal type, as no entry in a modern terminfo database employs them. Terminfo applications will furthermore only use the old X10/X11 report format with just three remaining terminal types: screen, terminology, and iTerm.

Interestingly, the current terminfo database doesn't yet list Windows Terminal (ms-terminal) as having an XM capability.

When that is updated, then tput XM 1 should suffice for setting mouse reports on from the command line, rather than emitting control sequences longhand, as should setterm -7 --xterm-mouse-reports all with my portable setterm tool.

@DHowett
Copy link
Member

DHowett commented Nov 17, 2020

Alas, that terminfo entry was built when Terminal 0.2 shipped without considering the things supported by the underlying console host. We’ve had XM (apparently with the caveats mentioned here) for three or so years 😄
We’ve been in touch with the maintainer on and off since then. We’re closer to xterm+indirect with a few capabilities blanked than to the ms-terminal entry that has been shipping.

@jdebp
Copy link

jdebp commented Nov 17, 2020

Unfortunately, I couldn't get mouse reporting to work at all here with 1.4.3141.0, but I suspect that ssh being in the mix in my testing of it is partly the cause of that.

terminfo is a side issue here. So see #8303. Back to mouseInput.cpp. ☺

@DHowett
Copy link
Member

DHowett commented Nov 17, 2020

Ah yes, the SSH client shipped inbox (calls itself 7.7) synthesizes its own VT input from console event records. By 8.1+, we’d finally convinced them to let us handle it with ENABLE_VIRTUAL_TERMINAL_INPUT 😁

@DHowett DHowett self-assigned this Nov 18, 2020
@DHowett
Copy link
Member

DHowett commented Nov 18, 2020

Looking inside, I'm deeply horrified by what I see.

  • We made the same mistake for X10 and SGR encoding - control comes out as meta.
  • Terminal (uniquely) treats left/right control, left/right shift and left/right alt differently
    • We pass those control key states through indiscriminately as MK mouse key values
    • This means that left control is meta (until we fix it) and right control is shift (if we re-enable support for MK_SHIFT)

It's almost enough to suggest that perhaps no version of Terminal has ever really supported mouse mode, and conhost has only barely done so until you held down a modifier.

DHowett added a commit that referenced this issue Nov 23, 2020
This commit also fixes an observed issue in Windows Terminal where we
were passing in a console-style modifiers enum when MouseInput is
expecting MK_ constants.

I decided to unify MouseInput around the console-style modifier
constants because they have support for META (which MK_ does not) and
can differentiate between left/right alt/ctrl.

Our tests are fundamentally flawed here: they use a copy of the
modifier key generating logic _themselves_, so we got a bit of "error
carried forward."

I did not fix the tests to use known-good control sequences, I simply
replaced the character generator with another copy of the modifier code.
I did, however, extend them to test ctrl|meta and left/right modifiers.

Fixes #8291
@ghost ghost added the In-PR This issue has a related PR label Nov 23, 2020
@ghost ghost closed this as completed in #8379 Nov 30, 2020
@ghost ghost added Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release. and removed In-PR This issue has a related PR labels Nov 30, 2020
ghost pushed a commit that referenced this issue Nov 30, 2020
We had the xterm and SGR codings for meta/ctrl backwards. Oops.

This commit also fixes an observed issue in Windows Terminal where we
were passing in a console-style modifiers enum when MouseInput is
expecting MK_ constants.

I decided to unify MouseInput around the console-style modifier
constants because they have support for META (which MK_ does not) and
can differentiate between left/right alt/ctrl.

Our tests are fundamentally flawed here: they use a copy of the
modifier key generating logic _themselves_, so we got a bit of "error
carried forward."

I did not fix the tests to use known-good control sequences, I simply
replaced the character generator with another copy of the modifier code.
I did, however, extend them to test ctrl|meta and left/right modifiers.

Fixes #8291
DHowett added a commit that referenced this issue Jan 25, 2021
We had the xterm and SGR codings for meta/ctrl backwards. Oops.

This commit also fixes an observed issue in Windows Terminal where we
were passing in a console-style modifiers enum when MouseInput is
expecting MK_ constants.

I decided to unify MouseInput around the console-style modifier
constants because they have support for META (which MK_ does not) and
can differentiate between left/right alt/ctrl.

Our tests are fundamentally flawed here: they use a copy of the
modifier key generating logic _themselves_, so we got a bit of "error
carried forward."

I did not fix the tests to use known-good control sequences, I simply
replaced the character generator with another copy of the modifier code.
I did, however, extend them to test ctrl|meta and left/right modifiers.

Fixes #8291

(cherry picked from commit b1e1c7c)
@ghost
Copy link

ghost commented Jan 28, 2021

🎉This issue was addressed in #8379, which has now been successfully released as Windows Terminal v1.5.10271.0.:tada:

Handy links:

@ghost
Copy link

ghost commented Jan 28, 2021

🎉This issue was addressed in #8379, which has now been successfully released as Windows Terminal Preview v1.6.10272.0.:tada:

Handy links:

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-VT Virtual Terminal sequence support Impact-Correctness It be wrong. Issue-Bug It either shouldn't be doing this or needs an investigation. Priority-2 A description (P2) Product-Conhost For issues in the Console codebase Product-Terminal The new Windows Terminal. Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants