mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-09 02:15:32 +00:00
Fixes #5950. If a user starts a longpress gesture and then flicks up, that immediately brings up the longpress menu, and the timeout for display of the menu should be cancelled -- otherwise the end result is a key that stays 'stuck' on.
73 lines
2.4 KiB
TypeScript
73 lines
2.4 KiB
TypeScript
/// <reference path="subkeyPopup.ts" />
|
|
/// <reference path="../pendingGesture.interface.ts" />
|
|
|
|
namespace com.keyman.osk.browser {
|
|
/**
|
|
* (Conceptually) represents a finite-state-machine that determines
|
|
* whether or not a series of touch events corresponds to a longpress
|
|
* touch input. The `resolve` method may be used to trigger the
|
|
* subkey menu early, as with the upward quick-display shortcut.
|
|
*
|
|
* This is the default implementation of longpress behavior for KMW.
|
|
* Alterate implementations are modeled through the `embedded`
|
|
* namespace's equivalent, which is designed to facilitate custom
|
|
* modeling for such gestures.
|
|
*
|
|
* Once the conditions to recognize a longpress gesture have been
|
|
* fulfilled, this class's `promise` will resolve with a `SubkeyPopup`
|
|
* matching the gesture's 'base' key, which itself provides a
|
|
* `promise` field that will resolve to a `KeyEvent` once the touch
|
|
* sequence is completed.
|
|
*/
|
|
export class PendingLongpress implements PendingGesture {
|
|
public readonly baseKey: KeyElement;
|
|
public readonly promise: Promise<SubkeyPopup>;
|
|
|
|
public readonly subkeyUI: SubkeyPopup;
|
|
|
|
private readonly vkbd: VisualKeyboard;
|
|
private resolver: (subkeyPopup: SubkeyPopup) => void;
|
|
|
|
private timerId: number;
|
|
private popupDelay: number = 500;
|
|
|
|
constructor(vkbd: VisualKeyboard, baseKey: KeyElement) {
|
|
this.vkbd = vkbd;
|
|
this.baseKey = baseKey;
|
|
|
|
let _this = this;
|
|
this.promise = new Promise<SubkeyPopup>(function(resolve, reject) {
|
|
_this.resolver = resolve;
|
|
// After the timeout, it's no longer deferred; it's being fulfilled.
|
|
// Even if the actual subkey itself is still async.
|
|
_this.timerId = window.setTimeout(_this.resolve.bind(_this), _this.popupDelay);
|
|
});
|
|
}
|
|
|
|
public cancel() {
|
|
if(this.timerId) {
|
|
window.clearTimeout(this.timerId);
|
|
this.timerId = null;
|
|
}
|
|
|
|
if(this.resolver) {
|
|
this.resolver(null);
|
|
this.resolver = null;
|
|
}
|
|
}
|
|
|
|
public resolve() {
|
|
// User has flicked up to get to the longpress, before
|
|
// the timeout has expired. We need to cancel the timeout.
|
|
// See #5950
|
|
if(this.timerId) {
|
|
window.clearTimeout(this.timerId);
|
|
this.timerId = null;
|
|
}
|
|
|
|
if(this.resolver) {
|
|
this.resolver(new SubkeyPopup(this.vkbd, this.baseKey));
|
|
}
|
|
}
|
|
}
|
|
}
|