-
-
Notifications
You must be signed in to change notification settings - Fork 112
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
feat(core): ldml improve key-not-found 🙀 #10090
Conversation
- distinguish between unmapped and 0-length output strings - don't do any processing for 0-length output strings - no change to developer, that will be next - remove a comment referencing transform=no For: #9451
User Test ResultsTest specification and instructions User tests are not required Test Artifacts
|
PTAL and see if it makes sense. The NEXT step will be to change kmc to actually emit some kind of pseudo-gap ( essentially |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking pretty close. There are some questions around modifier keys and key combinations that I think we need to cover
|
||
if (key_str.empty()) { | ||
if (!found) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to exclude modifiers (incl. Caps) from this test. Press and release Ctrl or Shift should not invalidate context. Press and release Alt on Windows is a special case -- because it opens the menu. But it may not need to invalidate context because other actions will do that anyway.
However, Ctrl+A should invalidate context. So we need to be aware of the modifier state of key combinations and invalidate context for missing key events. And if we define Ctrl+Q in the keyboard, does that mean that all other Ctrl+key combinations will be treated as gap? Philosophy time.
Also, I wonder how many keyboard developers will get annoyed when their spacebar doesn't work until they add a key for it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- we're only on key down here, for one thing. key up events are silently ignored. (line 185) - should that change?
- if Ctrl-A was assigned as a key, then it should not invalidate context. So I'm going to need some more details here...
- space - we could detect space here and simply send it to the OS, invalidating context. But, since we already have an implied
space
key in LDML, kmc could simply slip that one in unless it's otherwise defined. (i.e. instead of gap). The net effect would be that if you define no keys you'll get a keyboard with one functional key- the spacebar. - seems like there's enough here that it's time for a CLDR ticket: https://unicode-org.atlassian.net/browse/CLDR-17262
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- we're only on key down here, for one thing. key up events are silently ignored. (line 185) - should that change?
The key up events don't tend to harm if the key is already up (in my experience). So should be okay to go through.
- if Ctrl-A was assigned as a key, then it should not invalidate context. So I'm going to need some more details here...
If Ctrl+A is assigned, then yes, it gets processed as normal. If it isn't assigned, however, and falls back through to the app (as a user would expect), doing a select-all on Windows for example, then we would want a context reset.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
key up
I don't think you mean "all keyup events trigger passthrough/context reset" as that would be disruptive to markers. so I'm not sure what the code should do different here.
ctrl=A
OK so far.
I'm still unclear on which vkeys need to be passed through to the OS, causing a context reset. is there a list? should the list be in CLDR?
the other question is how in the world can i best test this besides with a debugger? |
- restructure keyup/keydown code some - new utility function emit_invalidate_passthrough_keystroke() For: #9451
@mcdurdin I've restructured a bit to make it easier to pass-through keys as needed pending that discussion. |
- unused nit fix For: #9451
the heuristic of losing markers is actually pretty good. |
Seems a little in direct, but I'll give it a try |
little bit of a side excursion fixing a markers issue. #9468 Commit is now much improved, but overproducing markers in the context:
Still to-do is to get back to the key-not-found logic. |
- don't skip markers when calling context_to_string()! Oops. - update docs on ldml_processor::remove_text() - update remove_text() to handle markers in the context string. This is really: #9468
@@ -279,7 +285,7 @@ size_t ldml_processor::process_output(km_core_state *state, const std::u32string | |||
assert(ldml::normalize_nfd_markers(nfd_str)); // TODO-LDML: else fail? | |||
// extract context string, in NFD | |||
std::u32string old_ctxtstr_nfd; | |||
(void)context_to_string(state, old_ctxtstr_nfd, false); | |||
(void)context_to_string(state, old_ctxtstr_nfd, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure enough, it was NOT INCLUDING MARKERS until this was turned to true. (that's what 'false' means)
@@ -316,8 +322,8 @@ size_t ldml_processor::process_output(km_core_state *state, const std::u32string | |||
|
|||
// Ok. We've done all the happy manipulations. | |||
|
|||
/** NFD and no markers */ | |||
std::u32string ctxtstr_cleanedup = ldml::remove_markers(ctxtstr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure enough it was, surprisingly, REMOVING MARKERS
// TODO-LDML: need to emit marker here - need to emit text w/ markers, and handle appropriately. | ||
// // TODO-LDML: 1-marker hack! need to support a string with intermixed markers. | ||
if (str.length() == 3 && str[0] == LDML_UC_SENTINEL && str[1] == LDML_MARKER_CODE) { | ||
emit_marker(state, str[2]); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
core/src/ldml/ldml_processor.cpp
Outdated
void ldml_processor::emit_invalidate_passthrough_keystroke(km_core_state *state) { | ||
state->actions().push_invalidate_context(); | ||
state->actions().push_emit_keystroke(); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
encapsulating this in case it needs to change later. i guess I could pass the vkey here?
@@ -27,12 +27,12 @@ static const uint16_t BOTH_ALT = LALTFLAG | RALTFLAG; | |||
static const uint16_t BOTH_CTRL = LCTRLFLAG | RCTRLFLAG; | |||
|
|||
std::u16string | |||
vkeys::lookup(km_core_virtual_key vk, uint16_t modifier_state) const { | |||
vkeys::lookup(km_core_virtual_key vk, uint16_t modifier_state, bool &found) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
empty string return now means "no output", distinct from "not found"
at this point I'm not going to try to split this into two PRs, key-not-found vs markers. If I realized the test cases were going to bump up against that so quickly, i might have done so. |
Test it with markers, they said. What could go wrong, they said. If test plans can be faithful wounds, this is one of 'em! 😆 |
- copy exception table for reset from VKScanCodes.cpp - update test For: #9451
I copied the table from VKScanCodes.cpp , it seemed to be what i wanted, ptal… |
I wonder if we should be trying to centralize that as a common shared file under /common/cpp/scancodes/some_file_name_here.cpp? |
maybe a good item for a future PR? ? |
core/src/ldml/ldml_processor.cpp
Outdated
|
||
|
||
void ldml_processor::emit_invalidate_passthrough_keystroke(km_core_state *state, km_core_virtual_key vk, uint16_t _kmn_unused(modifier_state)) { | ||
if (ldml_VKContextReset[vk]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need to vk<256
? assert() for debug builds?
core/src/ldml/ldml_processor.cpp
Outdated
// from VKScanCodes.cpp | ||
static const int ldml_VKContextReset[256] = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should probably be in Core as a separate .cpp, rather than embedded in ldml_processor.cpp
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, pending the assert just noted and if possible moving the vkscancodes stuff into a separate cpp
- move vkey_to_contextreset table into a common spot in core - assert that vk < 0x100 to avoid running off the table For: #9451
Changes in this pull request will be available for download in Keyman version 17.0.229-alpha |
For: #9451
@keymanapp-test-bot skip