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

Shift+key denied by text field as "control character" on remote systems #2008

Closed
heinrich-ulbricht opened this issue Sep 13, 2022 · 13 comments · Fixed by #2032
Closed

Shift+key denied by text field as "control character" on remote systems #2008

heinrich-ulbricht opened this issue Sep 13, 2022 · 13 comments · Fixed by #2032
Labels

Comments

@heinrich-ulbricht
Copy link

heinrich-ulbricht commented Sep 13, 2022

Describe the bug
I cannot type any character with Shift modifier - no uppercase chars, no colon, no nothing. This does not happen on all systems.

To Reproduce
Steps to reproduce the behavior:

  1. Pull the Terminal.GUI
  2. Start the unmodified UICatalog project
  3. Put the cursor in any text input field
  4. Type Shift+a - nothing happens
  5. Type a - a is typed

Expected behavior
I expect A to be typed when pressing Shift+a

Screenshots
It seems like the key is discarded as "control character". So the InsertText (kb) is never reached.

image

This does not happen on all systems, but on the one I have the debugger running ^^ Either the check should ignore the Shift modifier, or in an earlier step a conversion of Shift+a to uppercase A fails. Not sure how it is supposed to work.

(Note: removing the numlock modifier makes no difference.)

Here is the corresponding KeyEventRecord:
image

Desktop (please complete the following information):

  • OS: Windows 11, English UI language, German keyboard language, through RDP session
  • Version: relatively recent dev version: 3866e65

Additional context

Call stack:

>	Terminal.Gui.dll!Terminal.Gui.TextField.ProcessKey(Terminal.Gui.KeyEvent kb) Line 565	C#
 	Terminal.Gui.dll!Terminal.Gui.View.ProcessHotKey(Terminal.Gui.KeyEvent keyEvent) Line 1881	C#
 	Terminal.Gui.dll!Terminal.Gui.Application.ProcessKeyEvent(Terminal.Gui.KeyEvent ke) Line 431	C#
 	Terminal.Gui.dll!Terminal.Gui.WindowsDriver.ProcessInput(Terminal.Gui.WindowsConsole.InputRecord inputEvent) Line 859	C#
 	Terminal.Gui.dll!Terminal.Gui.WindowsDriver.PrepareToRun.AnonymousMethod__34_0(Terminal.Gui.WindowsConsole.InputRecord e) Line 759	C#
 	Terminal.Gui.dll!Terminal.Gui.WindowsMainLoop.Terminal.Gui.IMainLoopDriver.MainIteration() Line 1881	C#
 	Terminal.Gui.dll!Terminal.Gui.MainLoop.MainIteration() Line 295	C#
 	Terminal.Gui.dll!Terminal.Gui.Application.RunMainLoopIteration(ref Terminal.Gui.Application.RunState state, bool wait, ref bool firstIteration) Line 1014	C#
 	Terminal.Gui.dll!Terminal.Gui.Application.RunLoop(Terminal.Gui.Application.RunState state, bool wait) Line 996	C#
 	Terminal.Gui.dll!Terminal.Gui.Application.Run(Terminal.Gui.Toplevel view, System.Func<System.Exception, bool> errorHandler) Line 1172	C#
 	UICatalog.dll!UICatalog.Scenario.Run() Line 200	C#
 	UICatalog.dll!UICatalog.UICatalogApp.Main(string[] args) Line 111	C#
@tznind
Copy link
Collaborator

tznind commented Sep 13, 2022

Thanks for reporting this. Does disabling the numlock toggle on the keyboard have any effect?

If you run UICatalog and go to the 'Keys' Scenario. What appears when you hit Shift+A in the 'Key stroke log'

keys

@heinrich-ulbricht
Copy link
Author

heinrich-ulbricht commented Sep 13, 2022

No A for me:
image
(Note: KeyUp: Enter is from key-navigating to the scenario.)
Switching off NumLock does make no difference. Above was without, here is with NumLock on:
image

@tznind
Copy link
Collaborator

tznind commented Sep 13, 2022

Very strange. Does it make any difference if you launch with -usc?

Also what does your $TERM environment variable say (echo $TERM)

Also just to rule it out, I take it scroll lock or function lock are also off?

Looking at that Key value in your first screen shot it definitely looks like there is another flag bit set:

00010000000000000000000001000001
Decimal to Binary: 268435521

Can you please reproduce the first screenshot without numlock and we can see what the value of KeyValue is in watch window?

@heinrich-ulbricht
Copy link
Author

heinrich-ulbricht commented Sep 13, 2022

I toggled scroll lock and function lock to be sure, no difference.
Something is up with the way the command line is started, or hosted or whatever. Did some more tests:

  1. cmd.exe run via Win+R -> does not work, no A
    • EDIT: FIXED BY -usc !!
  2. new fancy Windows Terminal with cmd.exe tab -> does work
  3. PowerShell 7 -> does work in Terminal tab, not standalone
  4. PowerShell 5.1 -> does work in Terminal tab, not standalone

Looking at the process explorer I see different processes created around the application depending on how it's started.

Regarding the flag I suppose this is Key.ShiftMask - if you mean the left-most 1:
image

First screenshot without numlock:
image

Hex values:
image

And by the way: -usc fixes it for case 1! What is this? EDIT: I see, it switches from WindowsDriver to NetDriver.

EDIT: Screenshot for -usc:
image

@tznind
Copy link
Collaborator

tznind commented Sep 13, 2022

Yes. -usc is Application.UseSystemConsole=true, it changes which ConsoleDriver implementation is used. Without usc it is CursesDriver or WindowsDriver (depending on OS). With usc it is NetDriver.

Definitely looks like kb.Key is getting the extra bit mask in one driver but not the other. I'll have a closer look tomorrow and see if I can get to the bottom of this or @BDisp might have some suggestions.

Thanks for sticking with this and sharing those screenshots its very helpful!

@BDisp
Copy link
Collaborator

BDisp commented Sep 13, 2022

I already test with all the related terminals and I didn't get the issue with the WindowsDriver. I can digit Shift+A and I get the A on the TextField. What I thinking it could might happens is some Germain layout keyboard conflict on Windows using the WindowsDriver. Another think is some racing condition which restarting the machine could fix something.

@tznind
Copy link
Collaborator

tznind commented Sep 14, 2022

Ok so I have a hacky workaround which is to strip the Shift bit from the Key variable in the global key delegate. Make sure you put it after Init (or scenario.Init (Application.Top, _baseColorScheme); in UICatalog):

Application.RootKeyEvent = (k) => {
        // strip shift mask from key code
	k.Key = (Key)(k.KeyValue & (uint)0x0fffffff);
	return false;
};

But I would still like to get to the bottom of this. The entry point for key handling is

public WindowsConsole.ConsoleKeyInfoEx ToConsoleKeyInfoEx (WindowsConsole.KeyEventRecord keyEvent)

If you could put a conditional break point in there (e.g. see below). We should be able to see if that extra bit is being fed in by windows or is being introduced by Terminal.Gui. Note that you may need to add the shift mask to that conditional expression if it isn't hit in your environment.

image

I think what is supposed to happen is that keyEvent.dwControlKeyState stores the modifiers while keyEvent.wVirtualKeyCode and keyEvent.UnicodeChar both store only the letter.

@heinrich-ulbricht
Copy link
Author

Will do as soon as I'm back on my Linux machine! When I'm RDPing from Windows it apparently... works.
So Windows 10 -> Windows 11 via on-board RDP client works.
But Linux -> Windows 11 via Remmina RDP client doesn't.

Not sure what to make of that. Is Remmina doing shenanigans there? We'll see.

@BDisp
Copy link
Collaborator

BDisp commented Sep 14, 2022

In Windows Terminal I had to delete some shortcut keys to be able to manage with some Terminal.Gui views. One I remember was the Ctrl+Shift+D, but a simple Shift+A which is necessary for display the upper case A letter, should never be used by applications. Since you only having this issue from Linux to Windows may be the Remmina isn't send the correct bit for the Windows desktop.

@heinrich-ulbricht
Copy link
Author

heinrich-ulbricht commented Sep 14, 2022

@tznind Here is a screenshot at the position you asked for:
image

Call stack:

>	Terminal.Gui.dll!Terminal.Gui.WindowsDriver.ToConsoleKeyInfoEx(Terminal.Gui.WindowsConsole.KeyEventRecord keyEvent) Line 1222	C#
 	Terminal.Gui.dll!Terminal.Gui.WindowsDriver.ProcessInput(Terminal.Gui.WindowsConsole.InputRecord inputEvent) Line 789	C#
 	Terminal.Gui.dll!Terminal.Gui.WindowsDriver.PrepareToRun.AnonymousMethod__34_0(Terminal.Gui.WindowsConsole.InputRecord e) Line 759	C#
 	Terminal.Gui.dll!Terminal.Gui.WindowsMainLoop.Terminal.Gui.IMainLoopDriver.MainIteration() Line 1881	C#
 	Terminal.Gui.dll!Terminal.Gui.MainLoop.MainIteration() Line 295	C#
 	Terminal.Gui.dll!Terminal.Gui.Application.RunMainLoopIteration(ref Terminal.Gui.Application.RunState state, bool wait, ref bool firstIteration) Line 1014	C#
 	Terminal.Gui.dll!Terminal.Gui.Application.RunLoop(Terminal.Gui.Application.RunState state, bool wait) Line 996	C#
 	Terminal.Gui.dll!Terminal.Gui.Application.Run(Terminal.Gui.Toplevel view, System.Func<System.Exception, bool> errorHandler) Line 1172	C#
 	UICatalog.dll!UICatalog.Scenario.Run() Line 200	C#
 	UICatalog.dll!UICatalog.UICatalogApp.Main(string[] args) Line 111	C#

Screenshot of the app after continuing:
image

And I'm stupid. With my last test I still had the -usc parameter version selected in Visual Studio, so the error might still be there with the Windows to Windows RDP connection. Will check again, when I'm back at the Windows machine... fyi @BDisp

@tznind
Copy link
Collaborator

tznind commented Sep 14, 2022

Thanks for the screenshot wVirtualKeyCode is 231 in the image. The ConsoleKey Enum value for that is 'Packet':

Packet | 231 | The PACKET key (used to pass Unicode characters with keystrokes).

https://docs.microsoft.com/en-us/dotnet/api/system.consolekey?view=net-6.0

Not sure if that means anything but tomorrow I can try hacking my codebase to force every keystroke to those values and then step through the debugger to see if its being misinterpreted.

VK_PACKET 0xE7 Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP

@heinrich-ulbricht
Copy link
Author

heinrich-ulbricht commented Sep 14, 2022

Seems to be connected to remote connecting to systems. Did a Google. Here is somebody experiencing this as well with AnyDesk: https://stackoverflow.com/q/73076917
more: https://www.autohotkey.com/boards/viewtopic.php?p=411629&sid=9c697f02b387bb791ef865bd52b8bdf8#p411629
more: microsoft/terminal#12977 Fix for Terminal and UTF-16: microsoft/terminal#13667 (comment)

The dates seem recent. Might be something new?

@BDisp
Copy link
Collaborator

BDisp commented Sep 14, 2022

Well I believe there some way to handle that PACKET key so the right keystroke is filtered. I'm curious :-)

@tig tig added the bug label Sep 15, 2022
heinrich-ulbricht added a commit to WikiTransformationProject/Terminal.Gui that referenced this issue Sep 19, 2022
heinrich-ulbricht added a commit to WikiTransformationProject/Terminal.Gui that referenced this issue Sep 19, 2022
@tig tig changed the title Shift+key denied by text field as "control character" Shift+key denied by text field as "control character" on remote systems Sep 20, 2022
@tig tig closed this as completed in #2032 Oct 31, 2022
tig added a commit that referenced this issue Oct 31, 2022
Fixes #2008 - Shift+key denied by text field as "control character" on remote systems
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants