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

Launching in Russian layout causes Ctrl+C and other signal chars to not work #17197

Open
EntityinArray opened this issue May 6, 2024 · 15 comments
Labels
Area-Input Related to input processing (key presses, mouse, etc.) Issue-Bug It either shouldn't be doing this or needs an investigation. Product-Terminal The new Windows Terminal.
Milestone

Comments

@EntityinArray
Copy link

EntityinArray commented May 6, 2024

Windows Terminal version

1.19.11213.0

Windows build number

10.0.19045.0

Other Software

PSVersion 7.4.2
PSEdition Core
GitCommitId 7.4.2
OS Microsoft Windows 10.0.19045
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0

Steps to reproduce

  • Change your keyboard layout to Russian
  • Open Windows Terminal
  • Try Ctrl+C

Expected Behavior

Sends interrupt

Actual Behavior

Types C

@EntityinArray EntityinArray added Issue-Bug It either shouldn't be doing this or needs an investigation. Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting labels May 6, 2024
@lhecker
Copy link
Member

lhecker commented May 6, 2024

Between which keyboard layouts are you switching? Does the issue persist even if you press Ctrl+C multiple times?

@EntityinArray EntityinArray changed the title Switching keyboard layout causes Ctrl+C and other signal chars to not work Launching in Russian layout causes Ctrl+C and other signal chars to not work May 7, 2024
@EntityinArray
Copy link
Author

Between which keyboard layouts are you switching? Does the issue persist even if you press Ctrl+C multiple times?

Sorry, i made a new discovery. The layout switching is not necessary. Bug occurs when you just start Windows Terminal in Russian layout.

I switch between English and Russian. If Windows Terminal is started with Russian layout, it doesn't accept signal chars at all until app restart, even if you switch layout back to English during runtime.

image

@j4james
Copy link
Collaborator

j4james commented May 7, 2024

I think this is just PowerShell. I can't reproduce it in a cmd shell or WSL bash. I think it's because the C key on the Russian keyboard is actually a Cyrillic с, and PowerShell can't translate that into a control character. You can see the same thing with a Hebrew keyboard layout.

I also found that it seems to be the first time you press a Ctrl key that "locks" the mapping for that tab. So if you open a pwsh tab with the Russian layout, then switch to English, press Ctrl+C, then switch back to Russian, it should work fine. But if you press Ctrl+C when the Russian layout is first active, it'll be broken for the rest of that session.

I also see the same behavior in conhost.

@carlos-zamora carlos-zamora added this to the Terminal v1.22 milestone May 8, 2024
@carlos-zamora carlos-zamora added Area-Input Related to input processing (key presses, mouse, etc.) Product-Terminal The new Windows Terminal. and removed Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting labels May 8, 2024
@j4james
Copy link
Collaborator

j4james commented May 9, 2024

This bug was tracked in the PSReadLine repository in PowerShell/PSReadLine#1393, and it sounds like they've got a partial fix. The Ctrl keys still won't work when your keyboard layout is Russian, but they should work if you switch to English without needing to restart the shell. You'll need the latest beta version of PSReadLine to get that fix, though.

@lhecker
Copy link
Member

lhecker commented May 9, 2024

Apropos @j4james I believe this code may not work in conhost:

const auto hkl = GetKeyboardLayout(GetWindowThreadProcessId(GetForegroundWindow(), nullptr));

If you try something like this:

#include <Windows.h>
#include <cstdio>

int main() {
    for (;;) {
        const auto hkl = GetKeyboardLayout(GetWindowThreadProcessId(GetForegroundWindow(), nullptr));
        printf("0x%p\n", hkl);
        Sleep(1000);
    }
}

you'll see that the layout never changes in conhost. I believe it's because of the window ownership lying that ntuser does where it makes it so that it appears as if cmd/pwsh/wsl owns the window. This seems to also affect GetWindowThreadProcessId which then returns the main thread ID of cmd/pwsh/wsl instead of the actual window handle. (BTW that seems like an OS bug?)

@lhecker
Copy link
Member

lhecker commented May 9, 2024

It seems I may have spoken too soon. I'm currently looking how to solve this in pwsh actually, and I'm not actually testing it in conhost. So I probably shouldn't have written the above without confirming it.

Most importantly I found this comment in GetWindowThreadProcessId:

NB: This has implications on the scenario where the window's owner gets remapped via NtUserConsoleControl / ConsoleSetWindowOwner. If called by thread that owns a window, API will return true TID/PID and not remapped one. This is how it was done historically and we are keeping this behavior.

I guess this explains why the current code may work: The function gets called by conhost itself from threads that may own a window. That's slightly bodgy however of course. 😅

@j4james
Copy link
Collaborator

j4james commented May 9, 2024

@lhecker Note that the code you referenced is only applicable to shells using VT input sequences, like the WSL bash shell, and that doesn't have any problems with the Ctrl keys when using a Russian keyboard layout. But PSReadLine isn't using VT input sequences - they're doing the keyboard translation themselves. And regardless of whether they're picking up the correct layout at runtime, they simply don't handle Ctrl keys on a Russian keyboard.

@github-account1111
Copy link

I think it's because the C key on the Russian keyboard is actually a Cyrillic с, and PowerShell can't translate that into a control character. You can see the same thing with a Hebrew keyboard layout.

No this also happens with Ctrl+a, Ctrl+x and I imagine other Ctrl shortcuts. Given that Microsoft still refuse to ship an up-to-date Powershell with Windows 10 and 11, this needs to be fixed.

@zadjii-msft zadjii-msft modified the milestones: Terminal v1.22, Backlog Oct 28, 2024
@zadjii-msft zadjii-msft added the Needs-Discussion Something that requires a team discussion before we can proceed label Oct 28, 2024
@zadjii-msft
Copy link
Member

Putting this back in the triage queue because it's not clear to my (extremely sleep deprived) brain from the discussion here which one of the following is actually the responsible area path for this bug:

  • OS
  • conhost
  • terminal
  • powershell
  • pwsh
  • PsReadline

@zadjii-msft zadjii-msft added the Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting label Oct 28, 2024
@ftoh
Copy link

ftoh commented Nov 3, 2024

I have two PCs. Only one affected the bug.

Affected
Windows 11 Pro 23H2 (build 22631.4317)
Windows Terminal 1.21.2911.0
PowerShell 7.4.6

Not affected
Windows 11 Pro 22H2 (build 22621.4317)
Windows Terminal 1.21.2911.0
PowerShell 7.4.6

UPD
Affected: PSReadLine 2.4.0 beta-0 (I don't know version was before I update it to latest)
Not Affected: PSReadLine 2.3.5

@carlos-zamora carlos-zamora removed Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting Needs-Discussion Something that requires a team discussion before we can proceed labels Nov 6, 2024
@EntityinArray
Copy link
Author

New interesting discovery:

  1. Launch Terminal in Russian layout (i believe any other non-english layout will work)
  2. Switch to English
  3. Typing with control depressed causes English chars to appear. Typing with control pressed causes Russian chars to appear

I hope this info gives clues to any devs at least somewhat familiar with this Rube Goldbergian mess and what might be happening under the hood

@o-sdn-o
Copy link

o-sdn-o commented Nov 15, 2024

New interesting discovery:

This behavior is typical only for PSReadline (PSReadLine 2.4.0-beta0 xlink: PowerShell/PSReadLine#2865). And it does not matter in which terminal emulator it was launched in Windows Terminal or not. There is no such behavior outside PSReadline.

P.S.: To reproduce this behavior, the use a different input method for each app system option must be disabled.

@dkandrov
Copy link

I have same issue:
Image

@o-sdn-o
Copy link

o-sdn-o commented Nov 21, 2024

I have same issue...

This behavior is not a Windows Terminal issue. It is exactly the same in other terminals. It is a PSReadLine issue.

sdn@megasus_0.2024-11-21.13-38-14.mp4

@dkandrov
Copy link

This behavior is not a Windows Terminal issue. It is exactly the same in other terminals. It is a PSReadLine issue.

I understand this, but no one has added a “screenshot” or screencast, so I've spent some time trying to figure out if I'm having the exact same problem or not. After that I decided to add screen cast.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Input Related to input processing (key presses, mouse, etc.) Issue-Bug It either shouldn't be doing this or needs an investigation. Product-Terminal The new Windows Terminal.
Projects
None yet
Development

No branches or pull requests

9 participants