Conversation
| uint32_t TerminalInput::_codepointToLower(uint32_t cp) noexcept | ||
| { | ||
| auto cb = _codepointToBuffer(cp); | ||
| // NOTE: MSDN states that `lpSrcStr == lpDestStr` is valid for LCMAP_LOWERCASE. |
Check failure
Code scanning / check-spelling
Unrecognized Spelling
src/terminal/input/terminalInput.cpp
Outdated
| { | ||
| auto cb = _codepointToBuffer(cp); | ||
| // NOTE: MSDN states that `lpSrcStr == lpDestStr` is valid for LCMAP_LOWERCASE. | ||
| const auto len = LCMapStringW(LOCALE_INVARIANT, LCMAP_LOWERCASE, cb.buf, cb.len, cb.buf, gsl::narrow_cast<int>(std::size(cb.buf))); |
Check failure
Code scanning / check-spelling
Unrecognized Spelling
| case CsiActionCodes::ANSISYSRC_CursorRestore: | ||
| _dispatch->CursorRestoreState(); | ||
| break; | ||
| case CsiActionCodes::KKP_KittyKeyboardSet: |
Check failure
Code scanning / check-spelling
Unrecognized Spelling
| case CsiActionCodes::KKP_KittyKeyboardSet: | ||
| _dispatch->SetKittyKeyboardProtocol(parameters.at(0), parameters.at(1)); | ||
| break; | ||
| case CsiActionCodes::KKP_KittyKeyboardQuery: |
Check failure
Code scanning / check-spelling
Unrecognized Spelling
| case CsiActionCodes::KKP_KittyKeyboardQuery: | ||
| _dispatch->QueryKittyKeyboardProtocol(); | ||
| break; | ||
| case CsiActionCodes::KKP_KittyKeyboardPush: |
Check failure
Code scanning / check-spelling
Unrecognized Spelling
| case CsiActionCodes::KKP_KittyKeyboardPush: | ||
| _dispatch->PushKittyKeyboardProtocol(parameters.at(0)); | ||
| break; | ||
| case CsiActionCodes::KKP_KittyKeyboardPop: |
Check failure
Code scanning / check-spelling
Unrecognized Spelling
| DECSLRM_SetLeftRightMargins = VTID("s"), | ||
| DTTERM_WindowManipulation = VTID("t"), // NOTE: Overlaps with DECSLPP. Fix when/if implemented. | ||
| ANSISYSRC_CursorRestore = VTID("u"), | ||
| KKP_KittyKeyboardSet = VTID("=u"), |
Check failure
Code scanning / check-spelling
Unrecognized Spelling
DHowett
left a comment
There was a problem hiding this comment.
we are unfortunately going to need some tests. or something. of the weird corner cases.
src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw
Outdated
Show resolved
Hide resolved
src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw
Outdated
Show resolved
Hide resolved
DHowett
left a comment
There was a problem hiding this comment.
Almost all the way done. Can you explain the conhost win32im thing? Should we actually use Kitty as our internal protocol?
|
I'm working on a version that's a lot easier to read. The problem is that it also doesn't quite work. 😄 Still working on that. |
|
(cc: @j4james, as this completely restructures your code to fit in Kitty's event-type field into the classic CSI sequences.) I think the logic and "idea of a structure" is solid now. If you want to test it, I think now it's ready for that. 🙂 The code is not final, however. I'm trying to further improve its structure, because this is still beyond ugly and unmaintainable. |
This comment has been minimized.
This comment has been minimized.
|
I'm sorry, I never got around to writing unit tests for all the keyboard mapping edge cases, and I know from last time that there's a lot of testing that's required. I can't do a build myself, so I can't test an in-progress PR anyway, but even if I could, I just wouldn't have the time to do that level of testing. My suggestion would be to go through all the linked issues on #16511, and also look for follow up issues like #16641 and #16642. You're going to want to test with lots of international keyboard layouts, looking out for things like dead keys, and AltGr key combos, especially when mixed all the Ctrl/Alt/Shift modifiers. Make sure you test Hebrew and Cyrillic. The various touch-screen/on-screen keyboards can also cause issues - I think some things are not expected to work, but they should at least work as well as they did before. I also vaguely remember remote desktop introducing some complications, so that's possibly worth testing too. |
a4df1f4 to
4f86d4c
Compare
This comment has been minimized.
This comment has been minimized.
|
@j4james Thanks for the pointers! I hope I'll do your implementation justice. I wouldn't say that I'm happy with my new implementation, but I also hope it's not too awful. (One thing I'm still uncertain about is my decision to let Kitty's encoding use your encoding table as a fallback. This is what required the rewrite from a hashmap --> a switch case in the first place. I could've also just duplicated the table into the Kitty path. Not sure what decision would've been better...) |
|
@lhecker I had hoped you would just be able to add additional mappings to my encoding table for kitty's disambiguate mode, and then the more advanced "report everything" modes would get their own code path the same as win32 input mode. If that wasn't feasible, I would probably be inclined to implement all of the kitty functionality in its own code path. I have to say I really don't like the switch/case approach - the whole reason for my mapping table refactor was to avoid that sort of thing. But maybe you can still come up with a better solution. I don't know enough about the kitty protocol to know what complications you need to deal with, but I can understand that it's probably a bit of a pain. |
|
I started with splitting up your encoding table into a switch case when I started implementing the "event type" enhancement flag. It requires reporting key up and repeat events as a sub-parameter to the modifier field, e.g. Looking at your encoding table for such CSI sequences, it looked very daunting. It gave me the impression that I may have to add complex encoding logic into the Kitty path. That sprouted the idea of turning your encoding table into a switch case and re-using it. At the time I didn't realize that Kitty only requires about a dozen or so "legacy" CSI sequences. |
DHowett
left a comment
There was a problem hiding this comment.
reviewed everything except terminalInput itself
src/host/VtIo.cpp
Outdated
| CATCH_RETURN(); | ||
| } | ||
|
|
||
| // TODO: Avoid translating win32im sequences to Kitty Keyboard Protocol temporarily. |
| // The KKP CSI u sequence is a superset of other CSI sequences: | ||
| // CSI unicode-key-code:alternate-key-code-shift:alternate-key-code-base ; modifiers:event-type ; text-as-codepoint u | ||
| uint32_t csiUnicodeKeyCode; | ||
| uint32_t csiAltKeyCodeShifted; // KKP-specific |
There was a problem hiding this comment.
if KKP-specific, we could call it kkpAltKey...?
There was a problem hiding this comment.
Hmm no I'd like everything to have the same csi prefix. Makes it easier in my mind since all of them logically belong together.
|
@j4james FWIW I made a small test utility for this: https://github.com/lhecker/keyboard-layout-switcher |
DHowett
left a comment
There was a problem hiding this comment.
I'm pretty much ready to sign off, having read the implementations side by side, but I have just a few questions.
| // it must be the generated character from an Alt-Numpad composition. | ||
| if (WI_IsFlagSet(key.controlKeyState, NUMLOCK_ON) && key.virtualKey == VK_MENU && key.codepoint != 0) | ||
| { | ||
| return _makeCharOutput(key.codepoint); |
There was a problem hiding this comment.
This means that alt numpad (raw Unicode) inputs will not be encoded in kitty's "everything is escape sequences and (optionally) includes text/codepoint" mode
| if (key.virtualKey == VK_PACKET || key.virtualKey == 0) | ||
| { | ||
| _lastVirtualKeyCode = std::nullopt; | ||
| return _makeCharOutput(key.codepoint); |
| // of length two, with two identical characters. This is because the system | ||
| // sees this as a second press of the dead key, which would typically result | ||
| // in the combining character representation being transmit twice. | ||
| auto length = ToUnicodeEx(virtualKeyCode, 0, keyState.data(), buffer.data(), bufferSize, flags, hkl); |
There was a problem hiding this comment.
How does the new implementation handle dead keys?
|
I did appreciate the simplicity of the defineKey lambdas, but I also get that there's a lot of complexity here. I don't mind the switch/case but getting to the point where I was reading it was hard! |
This essentially rewrites
TerminalInputfrom scratch.There's significant overlap between what kind of information
the Kitty protocol needs from the OS and our existing code.
The rewrite allows us to share large parts of the implementation.
Closes #11509
Validation Steps Performed
kitten show-key -m kitty✅