Skip to content

Commit

Permalink
Merge pull request #11232 from keymanapp/fix/web/no-selection-clear-o…
Browse files Browse the repository at this point in the history
…n-caps-multitap
  • Loading branch information
jahorton authored Apr 17, 2024
2 parents eaff3a3 + fb127e7 commit 5005339
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 2 deletions.
16 changes: 14 additions & 2 deletions common/web/input-processor/src/text/inputProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,20 @@ export default class InputProcessor {
if(keyEvent.baseTranscriptionToken) {
const transcription = this.contextCache.get(keyEvent.baseTranscriptionToken);
if(transcription) {
// Restores full context, including deadkeys in their exact pre-keystroke state.
outputTarget.restoreTo(transcription.preInput);
// Has there been a context change at any point during the multitap? If so, we need
// to revert it. If not, we assume it's a layer-change multitap, in which case
// no such reset is needed.
if(!isEmptyTransform(transcription.transform) || !transcription.preInput.isEqual(Mock.from(outputTarget))) {
// Restores full context, including deadkeys in their exact pre-keystroke state.
outputTarget.restoreTo(transcription.preInput);
}
/*
else:
1. We don't need to restore the original context, as it's already
in-place.
2. Restoring anyway would obliterate any selected text, which is bad
if this is a purely-layer-switching multitap. (#11230)
*/
} else {
console.warn('The base context for the multitap could not be found');
}
Expand Down
22 changes: 22 additions & 0 deletions common/web/keyboard-processor/src/text/deadkeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ export class Deadkey {
return dk;
}

equal(other: Deadkey) {
return this.d == other.d && this.p == other.d && this.o == other.o;
}

/**
* Sorts the deadkeys in reverse order.
*/
Expand Down Expand Up @@ -151,6 +155,24 @@ export class DeadkeyTracker {
}
}

equal(other: DeadkeyTracker) {
if(this.dks.length != other.dks.length) {
return false;
}

const otherDks = other.dks;
const matchedDks: Deadkey[] = [];

for(let dk of this.dks) {
const match = otherDks.find((otherDk) => dk.equal(otherDk));
if(!match) {
return false;
}
}

return matchedDks.length == otherDks.length;
}

count(): number {
return this.dks.length;
}
Expand Down
12 changes: 12 additions & 0 deletions common/web/keyboard-processor/src/text/outputTarget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,18 @@ export class Mock extends OutputTarget {
this.text = this.getTextBeforeCaret() + s;
}

/**
* Indicates if this Mock represents an identical context to that of another Mock.
* @param other
* @returns
*/
isEqual(other: Mock) {
return this.text == other.text
&& this.selStart == other.selStart
&& this.selEnd == other.selEnd
&& this.deadkeys().equal(other.deadkeys());
}

doInputEvent() {
// Mock isn't backed by an element, so it won't have any event listeners.
}
Expand Down

0 comments on commit 5005339

Please sign in to comment.