diff --git a/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/gestureSequence.ts b/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/gestureSequence.ts index 6838647cb9..538bf7d2bb 100644 --- a/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/gestureSequence.ts +++ b/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/gestureSequence.ts @@ -130,7 +130,9 @@ export class GestureSequence extends EventEmitter> { } public get allSourceIds(): string[] { - return this.stageReports[this.stageReports.length - 1]?.allSourceIds; + // Note: there is a brief window of time - between construction & the deferred first + // 'stage' event - during which this array may be of length 0. + return this.stageReports[this.stageReports.length - 1]?.allSourceIds ?? []; } private get baseGestureSetId(): string { diff --git a/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/matcherSelector.ts b/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/matcherSelector.ts index 15d346f23b..e4572a4d45 100644 --- a/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/matcherSelector.ts +++ b/common/web/gesture-recognizer/src/engine/headless/gestures/matchers/matcherSelector.ts @@ -221,7 +221,10 @@ export class MatcherSelector extends EventEmitter> { matcher: null, result: { matched: false, - action: null + action: { + type: 'complete', + item: null + } } }); } diff --git a/web/src/engine/osk/src/keyboard-layout/oskLayerGroup.ts b/web/src/engine/osk/src/keyboard-layout/oskLayerGroup.ts index 4237c5fe2d..16a126a6e4 100644 --- a/web/src/engine/osk/src/keyboard-layout/oskLayerGroup.ts +++ b/web/src/engine/osk/src/keyboard-layout/oskLayerGroup.ts @@ -104,28 +104,17 @@ export default class OSKLayerGroup { private nearestKey(coord: Omit, 'item'>, layer: OSKLayer): KeyElement { const baseRect = this.element.getBoundingClientRect(); - /** - * Transforms the client rect of child elements to use a coordinate system where the top-left - * of the layer group's bounding rectangle serves as the origin - the same coordinate - * system output by the gesture engine. - * @param childRect - * @returns - */ - const translation = (childRect: DOMRect) => { - return new DOMRect(childRect.x - baseRect.x, childRect.y - baseRect.y, childRect.width, childRect.height); - } - let row: OSKRow = null; let bestMatchDistance = Number.MAX_VALUE; // Find the row that the touch-coordinate lies within. for(const r of layer.rows) { - const rowRect = translation(r.element.getBoundingClientRect()); - if(rowRect.top <= coord.targetY && coord.targetY < rowRect.bottom) { + const rowRect = r.element.getBoundingClientRect(); + if(rowRect.top <= coord.clientY && coord.clientY < rowRect.bottom) { row = r; break; } else { - const distance = rowRect.top > coord.targetY ? rowRect.top - coord.targetY : coord.targetY - rowRect.bottom; + const distance = rowRect.top > coord.clientY ? rowRect.top - coord.clientY : coord.clientY - rowRect.bottom; if(distance < bestMatchDistance) { bestMatchDistance = distance; @@ -144,12 +133,12 @@ export default class OSKLayerGroup { let dxMax = 24; let dxMin = 100000; - const x = coord.targetX; + const x = coord.clientX; for (let k = 0; k < row.keys.length; k++) { // Second-biggest, though documentation suggests this is probably right. const keySquare = row.keys[k].square as HTMLElement; // gets the .kmw-key-square containing a key - const squareRect = translation(keySquare.getBoundingClientRect()); + const squareRect = keySquare.getBoundingClientRect(); // Find the actual key element. let childNode = keySquare.firstChild ? keySquare.firstChild as HTMLElement : keySquare; @@ -179,7 +168,7 @@ export default class OSKLayerGroup { if (dxMin < 100000) { const t = row.keys[closestKeyIndex].square; - const squareRect = translation(t.getBoundingClientRect()); + const squareRect = t.getBoundingClientRect(); const x1 = squareRect.left; const x2 = squareRect.right; diff --git a/web/src/tools/testing/recorder/browserDriver.ts b/web/src/tools/testing/recorder/browserDriver.ts index 53b16ab53d..7b2626b584 100644 --- a/web/src/tools/testing/recorder/browserDriver.ts +++ b/web/src/tools/testing/recorder/browserDriver.ts @@ -52,6 +52,11 @@ export class BrowserDriver { simulateOSKEvent(eventSpec: OSKInputEventSpec) { let target = this.target; let oskKeyElement = document.getElementById(eventSpec.keyID); + const boundingBox = oskKeyElement.getBoundingClientRect(); + const center = { + clientX: boundingBox.left + boundingBox.width/2, + clientY: boundingBox.top + boundingBox.height/2 + } if(!oskKeyElement) { console.error('Could not find OSK key "' + eventSpec.keyID + '"!'); @@ -65,14 +70,18 @@ export class BrowserDriver { if(keyman.config.hostDevice.touchable) { downEvent = new Event(BrowserDriver.oskDownTouchType); upEvent = new Event(BrowserDriver.oskUpTouchType); - downEvent['touches'] = [{"target": oskKeyElement}]; - upEvent['touches'] = [{"target": oskKeyElement}]; - downEvent['changedTouches'] = [{"target": oskKeyElement}]; - upEvent['changedTouches'] = [{"target": oskKeyElement}]; + downEvent['touches'] = [{"target": oskKeyElement, ...center}]; + upEvent['touches'] = [{"target": oskKeyElement, ...center}]; + downEvent['changedTouches'] = [{"target": oskKeyElement, ...center}]; + upEvent['changedTouches'] = [{"target": oskKeyElement, ...center}]; } else { downEvent = new Event(BrowserDriver.oskDownMouseType); upEvent = new Event(BrowserDriver.oskUpMouseType); + downEvent.clientX = center.clientX; + downEvent.clientY = center.clientY; downEvent['relatedTarget'] = target; + upEvent.clientX = center.clientX; + upEvent.clientY = center.clientY; upEvent['relatedTarget'] = target; // Mouse-click driven OSK use involves use of at least one mouse button. downEvent['button'] = upEvent['button'] = 0;