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

bug(core): LDML processor handling "Enter" frame keys etc does not reset/invalidate the context for non-compliant apps #10955

Closed
rc-swag opened this issue Mar 6, 2024 · 10 comments · Fixed by #11172
Assignees
Labels
bug core/ Keyman Core
Milestone

Comments

@rc-swag
Copy link
Contributor

rc-swag commented Mar 6, 2024

Edit: Update after further investigation.
When a Enter is pressed with any app non-compliant or compliant, the KMX process will reset(invalidate) the context. What happens on the following keystroke for a compliant app is the context is read again which includes the newline marker and then is set in the core with km_core_state_context_set_if_needed api call.

With the LDML processor, the context is not reset. There is no LF character inserted into the context either, however, that would be incorrect, why because not being context away the enter could have moved the cursor to a new text field.

LDML processor after
aEnterc
Process_Event_Core: context cache after: |ac| (len: 2) [ U+0061 U+0063 ]
KMX processor after
aEnterc
Process_Event_Core: context cache after: |c| (len: 1) [ U+0063 ]

KMX Processor Log for non-compliant
aEnter

kmtip: _KeymanProcessKeystroke (d 1c0001   ex=0)
130	TIPProcessKey: Enter VirtualKey=['Enter' 0xd] lParam=1c0001   IsUp=0 Extended=0 Updateable=0 Preserved=0
164	Key pressed: ['Enter' 0xd] Context '|a| (len: 1) [ U+0061 ]'
47 kmtip: KeymanGetContext: Exit: Context does not support manipulation.  Using legacy interaction
287	AITIP::ReadContext: transitory context, so use buffered context [Updateable=0]
108	ProcessEvent: vkey[13] ShiftState[0] isDown[1]
121	Process_Event_Core: context app before:   |a| (len: 1) [ U+0061 ]
122	Process_Event_Core: context app after:    || (len: 0) [ ]
123	Process_Event_Core: context cache before: |a| (len: 1) [ U+0061 ]
124	Process_Event_Core: context cache after:  || (len: 0) [ ]
149	ProcessActionsNonUpdatableParse EMIT_KEYSTROKE
214	TIPProcessKey: Success, res=0

d

164	Key pressed: ['B' 0x42] Context '|| (len: 0) [ ]'
47	kmtip: KeymanGetContext: Exit: Context does not support manipulation.  Using legacy interaction
287	AITIP::ReadContext: transitory context, so use buffered context [Updateable=0]
108	ProcessEvent: vkey[66] ShiftState[0] isDown[1]
121	Process_Event_Core: context app before:   || (len: 0) [ ]
122	Process_Event_Core: context app after:    |b| (len: 1) [ U+0062 ]
123	Process_Event_Core: context cache before: || (len: 0) [ ]
124	Process_Event_Core: context cache after:  |b| (len: 1) [ U+0062 ]
214	TIPProcessKey: Success, res=1

WordPad Compliant app
aEnter

kmtip: GetLeftOfSelection(63) = U+0061  [1 fetched]
         282	AITIP::ReadContext: full context [Updateable=1] U+0061 
	100	Process_Event_Core: set_if_needed result: 0
	108	ProcessEvent: vkey[13] ShiftState[0] isDown[1]
	121	Process_Event_Core: context app before:   |a| (len: 1) [ U+0061 ]
	122	Process_Event_Core: context app after:    || (len: 0) [ ]
	123	Process_Event_Core: context cache before: |a| (len: 1) [ U+0061 ]
	124	Process_Event_Core: context cache after:  || (len: 0) [ ]
@keymanapp-test-bot keymanapp-test-bot bot added bug core/ Keyman Core labels Mar 6, 2024
@mcdurdin
Copy link
Member

mcdurdin commented Mar 6, 2024

The reason for this, I guess, is that the KMX processor treats the Enter key as a 'frame key' and passes the raw key event to the app, which causes a context reset?

@srl295
Copy link
Member

srl295 commented Mar 6, 2024

🙀

@mcdurdin mcdurdin changed the title bug(core): LDML processor handling "Enter" incorrectly for with non-complaint apps (context aware apps) bug(core): LDML processor handling "Enter" incorrectly for with non-compliant apps (context aware apps) Mar 7, 2024
@mcdurdin mcdurdin added this to the B17S4 milestone Mar 7, 2024
@mcdurdin
Copy link
Member

mcdurdin commented Mar 7, 2024

Assigning to you @srl295 in next sprint, as this probably should be addressed before we leave beta

@rc-swag
Copy link
Contributor Author

rc-swag commented Mar 8, 2024

The reason for this, I guess, is that the KMX processor treats the Enter key as a 'frame key' and passes the raw key event to the app, which causes a context reset?

This question made me go look at the logs again because what you said didn't seem correct. I found that the KMX processor resets the context regardless of compliant or not. I have updated the issue to match. The KMX processor makes the decision to invalidate the context so it is reset in the core in the process_event call before the EMIT keystroke to the app has occurred.

@rc-swag rc-swag changed the title bug(core): LDML processor handling "Enter" incorrectly for with non-compliant apps (context aware apps) bug(core): LDML processor handling "Enter" does not reset/invalidate the context Mar 8, 2024
@rc-swag
Copy link
Contributor Author

rc-swag commented Mar 26, 2024

@srl295 I was testing for #10227 and discovered that it is not just Enter that it is not resetting the context. Looking at the history I now see why. We moved to the ldml processor just pushing an action struct to the core, and we lost the invalidated context or the state->actions().push_invalidate_context(); On the OS side, the engine did not need to know about invalidate context but on the core side it does. Well at least in the non-compliant app stage.
I need to think more about the best solution to this. It may also include bringing the VKReset struct back. #10227 and this PR are now very much related.

@rc-swag rc-swag changed the title bug(core): LDML processor handling "Enter" does not reset/invalidate the context bug(core): LDML processor handling "Enter" frame keys etc does not reset/invalidate the context for non-compliant apps Mar 26, 2024
@srl295
Copy link
Member

srl295 commented Mar 27, 2024

So maybe we need a flag in the struct for context reset ?

@mcdurdin
Copy link
Member

I think we need a discussion on this. The decision on what is a frame key is probably OS-dependent. So some of this logic may belong in Engine, some in Core.

@srl295
Copy link
Member

srl295 commented Mar 28, 2024

Just to recap the current state (heh) of the ldml_processor.. when a key is 'not found' in the kmap, on key-down ldml_processor::process_key_down() will call:

void ldml_event_state::emit_passthrough_keystroke() {
  // assert we haven't already requested a keystroke
  assert(actions.emit_keystroke != KM_CORE_TRUE);
  actions.emit_keystroke = KM_CORE_TRUE;
}

The processor definitely doesn't (and, i'd think ideally wouldn't) know whether a VK is a frame key or not. Should the above be sufficient, and engine/core take it from there? Or should there be a hint set which explicitly says, "the processor did not find the requested key"?

Looking at KM_CORE_STATUS_* it doesn't seem like it would be a good fit to return a 'key not processed' status there. Just to rule that out.

@rc-swag
Copy link
Contributor Author

rc-swag commented Mar 28, 2024

Just to recap the current state (heh) of the ldml_processor.. when a key is 'not found' in the kmap, on key-down ...

Yes, this is the spot I was originally thinking you would do a lookup into the VKResetContext data structure at this point unless we can push into the core logic to make the decision. It is almost the equivalent spot in the kmx_processor [ except it has already determined whether it is a character, note and it doesn't map exactly to the old VKResetContext data structure ].

We know the information need for the decision it is:

if actions.emit_keystroke && ((key_pressed is a platform_frame_key || key_pressed == backspace && actions.code_points_to_delete ==0)) {
state->context().clear();
}

This could be a call made in km_core_process_event after the process_event call to the relevant processor
Then we just need the frame keys as an env variable passed through on keyboard creation.
We will have a meeting about this next week.

@mcdurdin mcdurdin modified the milestones: B17S4, B17S5 Mar 30, 2024
@rc-swag
Copy link
Contributor Author

rc-swag commented Apr 3, 2024

rough psudeo code could be small private function.

if actions.emit_keystroke && ((key_pressed is a platform_frame_key || key_pressed == backspace && actions.code_points_to_delete ==0)) {
state->context().clear();
}

where platform_frame_key == the VKResetArray

This could be a call made in km_core_process_event after the process_event call to the relevant processor

For the future we could add support for different frame keys on different OS's
Have the vkey arrays defined for each OS in a header file and then the environment variable would just be used to choose the correct vkey array.
items[4].scope = KM_CORE_OPT_ENVIRONMENT;
items[4].key = KM_CORE_VKEY_ENV_PLATFORM;
items[4].value = WINDOWS_PLATFORM_ENV;

srl295 added a commit that referenced this issue Apr 5, 2024
- move the reset table into its own cpp
- update function signatures per review comments

Fixes: #10955
srl295 added a commit that referenced this issue Apr 5, 2024
srl295 added a commit that referenced this issue Apr 5, 2024
@srl295 srl295 linked a pull request Apr 5, 2024 that will close this issue
srl295 added a commit that referenced this issue Apr 5, 2024
srl295 added a commit that referenced this issue Apr 5, 2024
- updates to debug_api test for rearranged items
- try to rearrange the action queue to match prior behavior

Fixes: #10955
srl295 added a commit that referenced this issue Apr 5, 2024
- reset for ctrl or alt modifiers, but NOT for key-up

Fixes: #10955
srl295 added a commit that referenced this issue Apr 5, 2024
- it was the check for deletion that was unneeded

Fixes: #10955
srl295 added a commit that referenced this issue Apr 8, 2024
- mark event flags as unused for now

Fixes: #10955
@darcywong00 darcywong00 removed this from the B17S5 milestone Apr 12, 2024
@darcywong00 darcywong00 added this to the B17S6 milestone Apr 12, 2024
srl295 added a commit that referenced this issue Apr 17, 2024
- clear the app context as well as the cached context

Fixes: #10955
srl295 added a commit that referenced this issue Apr 18, 2024
- don't invalidate on keyup
- don't check context()->empty()
- clean up structure and comments

Fixes: #10955
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug core/ Keyman Core
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants