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

windows console input sometimes drop leading charactors. #6328

Merged
merged 3 commits into from
Sep 8, 2022

Conversation

YO4
Copy link
Contributor

@YO4 YO4 commented Sep 5, 2022

In win32.c, is_readable_console() drops some kind of valid input character.
As a result, the first character(s) of STDIN.gets can be lost.

  1. codepoint(in unicode) lower bytes has 0x00. \u0100,\u0400,\u2200, CJK charactors, etc.
  2. ALT+NUMPAD sequence, via classic console(conhost.exe). They generates VK_ALT, key_up, UnicodeChar != 0.

This fixes both situations.

UnicodeChar with lower byte == 0 has dropped accidentaly
this is additional fix for ruby#5634
classic console(conhost.exe) reports an input with ALT+NUMPAD as VK_MENU, KeyUp, and uChar!=0.
additional fix for ruby#5634
@nobu
Copy link
Member

nobu commented Sep 5, 2022

Thank you for the patch.

Why the magic number instead of VK_MENU?

I think the condition can be like the following:

            if (ir.EventType == KEY_EVENT &&
                (ir.Event.KeyEvent.bKeyDown ||
                 ir.Event.KeyEvent.wVirtualKeyCode == VK_MENU) &&
                ir.Event.KeyEvent.uChar.UnicodeChar) {

@YO4
Copy link
Contributor Author

YO4 commented Sep 6, 2022

I was concerned about VK_MENU having a different name than the ALT key, but VK_MENU is widely used.
Nevertheless, VK_MENU /* ALT key */ was better than using a magic number.
(And it's more kindness to non windows programmer. but of cource, there are already many Windows specific manner in codes)

In the next code,
It seems to GetConsoleInput() not generate (bKeyDown, VK_MENU, UnicodeChar != 0),
and I once considered a similar code, but it depends on that Windows behavior and I avoid it.
so my code is like this

            if (ir.EventType == KEY_EVENT &&
                (ir.Event.KeyEvent.bKeyDown ||
                 (!ir.Event.KeyEvent.bKeyDown && ir.Event.KeyEvent.wVirtualKeyCode == VK_MENU))
                ir.Event.KeyEvent.uChar.UnicodeChar) {
                ret = 1;
            }

I thought it was a bit confusing and two conditions represents different situation.
So I want to leave it straightforward and let the compiler handle it.
Which code style would you prefer?

@YO4
Copy link
Contributor Author

YO4 commented Sep 7, 2022

modified proposal here.

            if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.uChar.UnicodeChar &&
                (ir.Event.KeyEvent.bKeyDown ||
                !ir.Event.KeyEvent.bKeyDown && ir.Event.KeyEvent.wVirtualKeyCode == VK_MENU)) {
                ret = 1;
            }

This includes all conditions, I think.
If it looks good, I would like to commit.

Copy link
Member

@nobu nobu left a comment

Choose a reason for hiding this comment

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

Either is ok.

@nobu nobu merged commit 28030f7 into ruby:master Sep 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
2 participants