feat: support for entering text indirectly (#577)
* feat: support for entering text indirectly * fix: restore text area value after composition input * update guacamole keyboard. --------- Co-authored-by: fezhang <fezhang@tencent.com> Co-authored-by: Miroslav Šedivý <sedivy.miro@gmail.com>
This commit is contained in:
parent
5b9225f401
commit
b194e91b1a
2 changed files with 88 additions and 7 deletions
|
|
@ -26,6 +26,8 @@
|
||||||
@touchmove.stop.prevent="onTouchHandler"
|
@touchmove.stop.prevent="onTouchHandler"
|
||||||
@touchstart.stop.prevent="onTouchHandler"
|
@touchstart.stop.prevent="onTouchHandler"
|
||||||
@touchend.stop.prevent="onTouchHandler"
|
@touchend.stop.prevent="onTouchHandler"
|
||||||
|
@compositionstart="onCompositionStartHandler"
|
||||||
|
@compositionend="onCompositionEndHandler"
|
||||||
/>
|
/>
|
||||||
<div v-if="!playing && playable" class="player-overlay" @click.stop.prevent="playAndUnmute">
|
<div v-if="!playing && playable" class="player-overlay" @click.stop.prevent="playAndUnmute">
|
||||||
<i class="fas fa-play-circle" />
|
<i class="fas fa-play-circle" />
|
||||||
|
|
@ -250,6 +252,7 @@
|
||||||
private focused = false
|
private focused = false
|
||||||
private fullscreen = false
|
private fullscreen = false
|
||||||
private mutedOverlay = true
|
private mutedOverlay = true
|
||||||
|
private lastTextAreaValue = ''
|
||||||
|
|
||||||
get admin() {
|
get admin() {
|
||||||
return this.$accessor.user.admin
|
return this.$accessor.user.admin
|
||||||
|
|
@ -756,6 +759,14 @@
|
||||||
first.target.dispatchEvent(simulatedEvent)
|
first.target.dispatchEvent(simulatedEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onCompositionStartHandler() {
|
||||||
|
this.lastTextAreaValue = this._overlay.value
|
||||||
|
}
|
||||||
|
|
||||||
|
onCompositionEndHandler() {
|
||||||
|
this._overlay.value = this.lastTextAreaValue
|
||||||
|
}
|
||||||
|
|
||||||
isMouseDown = false
|
isMouseDown = false
|
||||||
|
|
||||||
onMouseDown(e: MouseEvent) {
|
onMouseDown(e: MouseEvent) {
|
||||||
|
|
|
||||||
|
|
@ -297,6 +297,10 @@ Guacamole.Keyboard = function Keyboard(element) {
|
||||||
// Determine whether default action for Alt+combinations must be prevented
|
// Determine whether default action for Alt+combinations must be prevented
|
||||||
var prevent_alt = !this.modifiers.ctrl && !quirks.altIsTypableOnly;
|
var prevent_alt = !this.modifiers.ctrl && !quirks.altIsTypableOnly;
|
||||||
|
|
||||||
|
// If alt is typeable only, and this is actually an alt key event, treat as AltGr instead
|
||||||
|
if (quirks.altIsTypableOnly && (this.keysym === 0xFFE9 || this.keysym === 0xFFEA))
|
||||||
|
this.keysym = 0xFE03;
|
||||||
|
|
||||||
// Determine whether default action for Ctrl+combinations must be prevented
|
// Determine whether default action for Ctrl+combinations must be prevented
|
||||||
var prevent_ctrl = !this.modifiers.alt;
|
var prevent_ctrl = !this.modifiers.alt;
|
||||||
|
|
||||||
|
|
@ -397,7 +401,7 @@ Guacamole.Keyboard = function Keyboard(element) {
|
||||||
13: [0xFF0D], // enter
|
13: [0xFF0D], // enter
|
||||||
16: [0xFFE1, 0xFFE1, 0xFFE2], // shift
|
16: [0xFFE1, 0xFFE1, 0xFFE2], // shift
|
||||||
17: [0xFFE3, 0xFFE3, 0xFFE4], // ctrl
|
17: [0xFFE3, 0xFFE3, 0xFFE4], // ctrl
|
||||||
18: [0xFFE9, 0xFFE9, 0xFE03], // alt
|
18: [0xFFE9, 0xFFE9, 0xFFEA], // alt
|
||||||
19: [0xFF13], // pause/break
|
19: [0xFF13], // pause/break
|
||||||
20: [0xFFE5], // caps lock
|
20: [0xFFE5], // caps lock
|
||||||
27: [0xFF1B], // escape
|
27: [0xFF1B], // escape
|
||||||
|
|
@ -458,7 +462,7 @@ Guacamole.Keyboard = function Keyboard(element) {
|
||||||
"Again": [0xFF66],
|
"Again": [0xFF66],
|
||||||
"AllCandidates": [0xFF3D],
|
"AllCandidates": [0xFF3D],
|
||||||
"Alphanumeric": [0xFF30],
|
"Alphanumeric": [0xFF30],
|
||||||
"Alt": [0xFFE9, 0xFFE9, 0xFE03],
|
"Alt": [0xFFE9, 0xFFE9, 0xFFEA],
|
||||||
"Attn": [0xFD0E],
|
"Attn": [0xFD0E],
|
||||||
"AltGraph": [0xFE03],
|
"AltGraph": [0xFE03],
|
||||||
"ArrowDown": [0xFF54],
|
"ArrowDown": [0xFF54],
|
||||||
|
|
@ -469,7 +473,7 @@ Guacamole.Keyboard = function Keyboard(element) {
|
||||||
"CapsLock": [0xFFE5],
|
"CapsLock": [0xFFE5],
|
||||||
"Cancel": [0xFF69],
|
"Cancel": [0xFF69],
|
||||||
"Clear": [0xFF0B],
|
"Clear": [0xFF0B],
|
||||||
"Convert": [0xFF21],
|
"Convert": [0xFF23],
|
||||||
"Copy": [0xFD15],
|
"Copy": [0xFD15],
|
||||||
"Crsel": [0xFD1C],
|
"Crsel": [0xFD1C],
|
||||||
"CrSel": [0xFD1C],
|
"CrSel": [0xFD1C],
|
||||||
|
|
@ -536,6 +540,7 @@ Guacamole.Keyboard = function Keyboard(element) {
|
||||||
"Left": [0xFF51],
|
"Left": [0xFF51],
|
||||||
"Meta": [0xFFE7, 0xFFE7, 0xFFE8],
|
"Meta": [0xFFE7, 0xFFE7, 0xFFE8],
|
||||||
"ModeChange": [0xFF7E],
|
"ModeChange": [0xFF7E],
|
||||||
|
"NonConvert": [0xFF22],
|
||||||
"NumLock": [0xFF7F],
|
"NumLock": [0xFF7F],
|
||||||
"PageDown": [0xFF56],
|
"PageDown": [0xFF56],
|
||||||
"PageUp": [0xFF55],
|
"PageUp": [0xFF55],
|
||||||
|
|
@ -545,6 +550,7 @@ Guacamole.Keyboard = function Keyboard(element) {
|
||||||
"PrintScreen": [0xFF61],
|
"PrintScreen": [0xFF61],
|
||||||
"Redo": [0xFF66],
|
"Redo": [0xFF66],
|
||||||
"Right": [0xFF53],
|
"Right": [0xFF53],
|
||||||
|
"Romaji": [0xFF24],
|
||||||
"RomanCharacters": null,
|
"RomanCharacters": null,
|
||||||
"Scroll": [0xFF14],
|
"Scroll": [0xFF14],
|
||||||
"Select": [0xFF60],
|
"Select": [0xFF60],
|
||||||
|
|
@ -1316,9 +1322,10 @@ Guacamole.Keyboard = function Keyboard(element) {
|
||||||
|
|
||||||
var keydownEvent = new KeydownEvent(e);
|
var keydownEvent = new KeydownEvent(e);
|
||||||
|
|
||||||
// Ignore (but do not prevent) the "composition" keycode sent by some
|
// Ignore (but do not prevent) the event if explicitly marked as composing,
|
||||||
// browsers when an IME is in use (see: http://lists.w3.org/Archives/Public/www-dom/2010JulSep/att-0182/keyCode-spec.html)
|
// or when the "composition" keycode sent by some browsers when an IME is in use
|
||||||
if (keydownEvent.keyCode === 229)
|
// (see: http://lists.w3.org/Archives/Public/www-dom/2010JulSep/att-0182/keyCode-spec.html)
|
||||||
|
if (e.isComposing || keydownEvent.keyCode === 229)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Log event
|
// Log event
|
||||||
|
|
@ -1365,7 +1372,70 @@ Guacamole.Keyboard = function Keyboard(element) {
|
||||||
|
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
// NEKO: Do not automatically type text entered into the wrapped field
|
/**
|
||||||
|
* Handles the given "input" event, typing the data within the input text.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {!InputEvent} e
|
||||||
|
* The "input" event to handle.
|
||||||
|
*/
|
||||||
|
var handleInput = function handleInput(e) {
|
||||||
|
|
||||||
|
// Only intercept if handler set
|
||||||
|
if (!guac_keyboard.onkeydown && !guac_keyboard.onkeyup) return;
|
||||||
|
|
||||||
|
// Ignore events which have already been handled
|
||||||
|
if (!markEvent(e)) return;
|
||||||
|
|
||||||
|
// Type all content written
|
||||||
|
if (e.data && !e.isComposing)
|
||||||
|
guac_keyboard.type(e.data);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the given "compositionstart" event, automatically removing
|
||||||
|
* the "input" event handler, as "input" events should only be handled
|
||||||
|
* if composition events are not provided by the browser.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {!CompositionEvent} e
|
||||||
|
* The "compositionstart" event to handle.
|
||||||
|
*/
|
||||||
|
var handleCompositionStart = function handleCompositionStart(e) {
|
||||||
|
|
||||||
|
// Remove the "input" event handler now that the browser is known
|
||||||
|
// to send composition events
|
||||||
|
element.removeEventListener("input", handleInput, false);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the given "compositionend" event, typing the data within the
|
||||||
|
* composed text.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {!CompositionEvent} e
|
||||||
|
* The "compositionend" event to handle.
|
||||||
|
*/
|
||||||
|
var handleCompositionEnd = function handleCompositionEnd(e) {
|
||||||
|
|
||||||
|
// Only intercept if handler set
|
||||||
|
if (!guac_keyboard.onkeydown && !guac_keyboard.onkeyup) return;
|
||||||
|
|
||||||
|
// Ignore events which have already been handled
|
||||||
|
if (!markEvent(e)) return;
|
||||||
|
|
||||||
|
// Type all content written
|
||||||
|
if (e.data)
|
||||||
|
guac_keyboard.type(e.data);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// Automatically type text entered into the wrapped field
|
||||||
|
element.addEventListener("input", handleInput, false);
|
||||||
|
element.addEventListener("compositionend", handleCompositionEnd, false);
|
||||||
|
element.addEventListener("compositionstart", handleCompositionStart, false);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue