Skip to content

Commit

Permalink
Merge pull request #5479 from keymanapp/fix/common/core/web/empty-alt…
Browse files Browse the repository at this point in the history
…ernates

fix(common/core/web): error from early fat-finger termination due to OS interruptions
  • Loading branch information
jahorton authored Jul 27, 2021
2 parents 0eae52f + 9d35b26 commit fc1251b
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 2 deletions.
11 changes: 10 additions & 1 deletion common/core/web/input-processor/src/text/inputProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,11 @@ namespace com.keyman.text {
if(pair.p < KEYSTROKE_EPSILON) {
break;
} else if(timer && timer() >= TIMEOUT_THRESHOLD) {
// Note: it's always possible that the thread _executing_ our JS
// got paused by the OS, even if JS itself is single-threaded.
//
// The case where `alternates` is initialized (line 167) but empty
// (because of net-zero loop iterations) MUST be handled.
break;
}

Expand All @@ -187,6 +192,8 @@ namespace com.keyman.text {

// If alternateBehavior.beep == true, ignore it. It's a disallowed key sequence,
// so we expect users to never intend their use.
//
// Also possible that this set of conditions fail for all evaluated alternates.
if(alternateBehavior && !alternateBehavior.beep && pair.p > 0) {
let transform: Transform = alternateBehavior.transcription.transform;

Expand Down Expand Up @@ -215,7 +222,9 @@ namespace com.keyman.text {
// -- All keystroke (and 'alternate') processing is now complete. Time to finalize everything! --

// Notify the ModelManager of new input - it's predictive text time!
ruleBehavior.transcription.alternates = alternates;
if(alternates && alternates.length > 0) {
ruleBehavior.transcription.alternates = alternates;
}
// Yes, even for ruleBehavior.triggersDefaultCommand. Those tend to change the context.
ruleBehavior.predictionPromise = this.languageProcessor.predict(ruleBehavior.transcription);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -323,8 +323,16 @@ namespace com.keyman.text.prediction {
this.lmEngine.resetContext(context);
}

let alternates = transcription.alternates;
if(!alternates || alternates.length == 0) {
alternates = [{
sample: transcription.transform,
p: 1.0
}];
}

let transform = transcription.transform;
var promise = this.currentPromise = this.lmEngine.predict(transcription.alternates || transcription.transform, context);
var promise = this.currentPromise = this.lmEngine.predict(alternates, context);

let lp = this;
return promise.then(function(suggestions: Suggestion[]) {
Expand Down
19 changes: 19 additions & 0 deletions common/predictive-text/worker/model-compositor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,25 @@ class ModelCompositor {

if(!(transformDistribution instanceof Array)) {
transformDistribution = [ {sample: transformDistribution, p: 1.0} ];
} else if(transformDistribution.length == 0) {
/*
Robust stop-gap: if our other filters somehow fail, this fixes the
zero-length array by making it match the form of the array that
would result if it were instead called with the other legal
parameter type - a single Transform.
Unfortunately, the method will lack all data about even
the original keystroke that resulted in the call... but this way,
we can at least get some predictions rather than shortcutting
and producing none whatsoever.
*/
transformDistribution.push({
sample: {
insert: '',
deleteLeft: 0
},
p: 1.0
})
}

let inputTransform = transformDistribution.sort(function(a, b) {
Expand Down

0 comments on commit fc1251b

Please sign in to comment.