Handle repeated key events correctly.
- No leaking memory. - Make the viewer side be in charge of handling repeated key events.
This commit is contained in:
parent
70dae7d4f3
commit
0820c08dfc
|
|
@ -18,7 +18,7 @@ function Keyboard(defaults) {
|
||||||
var that = {}, // Public API methods
|
var that = {}, // Public API methods
|
||||||
conf = {}, // Configuration attributes
|
conf = {}, // Configuration attributes
|
||||||
|
|
||||||
keyDownList = []; // List of depressed keys
|
keyDownMap = {}; // List of depressed keys
|
||||||
// (even if they are happy)
|
// (even if they are happy)
|
||||||
|
|
||||||
// Configuration attributes
|
// Configuration attributes
|
||||||
|
|
@ -198,12 +198,15 @@ function getKeysym(evt) {
|
||||||
return keysym;
|
return keysym;
|
||||||
}
|
}
|
||||||
|
|
||||||
function show_keyDownList(kind) {
|
function show_keyDownMap(kind) {
|
||||||
var c;
|
var c = 0;
|
||||||
var msg = "keyDownList (" + kind + "):\n";
|
var keyCode, fevt;
|
||||||
for (c = 0; c < keyDownList.length; c++) {
|
var msg = "keyDownMap (" + kind + "):\n";
|
||||||
msg = msg + " " + c + " - keyCode: " + keyDownList[c].keyCode +
|
for (keyCode in keyDownMap) {
|
||||||
" - which: " + keyDownList[c].which + "\n";
|
fevt = getKeyEvent(keyCode, false);
|
||||||
|
msg = msg + " " + c + " - keyCode: " + fevt.keyCode +
|
||||||
|
" - which: " + fevt.which + "\n";
|
||||||
|
c++;
|
||||||
}
|
}
|
||||||
Util.Debug(msg);
|
Util.Debug(msg);
|
||||||
}
|
}
|
||||||
|
|
@ -221,20 +224,15 @@ function copyKeyEvent(evt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function pushKeyEvent(fevt) {
|
function pushKeyEvent(fevt) {
|
||||||
keyDownList.push(fevt);
|
keyDownMap[fevt.keyCode] = fevt;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getKeyEvent(keyCode, pop) {
|
function getKeyEvent(keyCode, pop) {
|
||||||
var i, fevt = null;
|
var fevt = keyDownMap[keyCode];
|
||||||
for (i = keyDownList.length-1; i >= 0; i--) {
|
if (typeof(fevt) === 'undefined') {
|
||||||
if (keyDownList[i].keyCode === keyCode) {
|
fevt = null;
|
||||||
if ((typeof(pop) !== "undefined") && (pop)) {
|
} else if ((typeof(pop) !== "undefined") && (pop)) {
|
||||||
fevt = keyDownList.splice(i, 1)[0];
|
delete keyDownMap[keyCode];
|
||||||
} else {
|
|
||||||
fevt = keyDownList[i];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return fevt;
|
return fevt;
|
||||||
}
|
}
|
||||||
|
|
@ -318,16 +316,11 @@ function onKeyDown(e) {
|
||||||
" (onKeyDown key: " + evt.keyCode +
|
" (onKeyDown key: " + evt.keyCode +
|
||||||
", which: " + evt.which + ")");
|
", which: " + evt.which + ")");
|
||||||
conf.onKeyPress(keysym, 1, evt);
|
conf.onKeyPress(keysym, 1, evt);
|
||||||
|
pushKeyEvent(fevt);
|
||||||
}
|
}
|
||||||
suppress = true;
|
suppress = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! ignoreKeyEvent(evt)) {
|
|
||||||
// Add it to the list of depressed keys
|
|
||||||
pushKeyEvent(fevt);
|
|
||||||
//show_keyDownList('down');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (suppress) {
|
if (suppress) {
|
||||||
// Suppress bubbling/default actions
|
// Suppress bubbling/default actions
|
||||||
Util.stopEvent(e);
|
Util.stopEvent(e);
|
||||||
|
|
@ -344,7 +337,7 @@ function onKeyPress(e) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
var evt = (e ? e : window.event),
|
var evt = (e ? e : window.event),
|
||||||
kdlen = keyDownList.length, keysym = null;
|
kdlen = keyDownMap.length, keysym = null;
|
||||||
//Util.Debug("onKeyPress kC:" + evt.keyCode + " cC:" + evt.charCode + " w:" + evt.which);
|
//Util.Debug("onKeyPress kC:" + evt.keyCode + " cC:" + evt.charCode + " w:" + evt.which);
|
||||||
|
|
||||||
if (((evt.which !== "undefined") && (evt.which === 0)) ||
|
if (((evt.which !== "undefined") && (evt.which === 0)) ||
|
||||||
|
|
@ -361,23 +354,17 @@ function onKeyPress(e) {
|
||||||
|
|
||||||
keysym = getKeysym(evt);
|
keysym = getKeysym(evt);
|
||||||
|
|
||||||
// Modify the the which attribute in the depressed keys list so
|
//show_keyDownMap('press');
|
||||||
// that the keyUp event will be able to have the character code
|
|
||||||
// translation available.
|
|
||||||
if (kdlen > 0) {
|
|
||||||
keyDownList[kdlen-1].keysym = keysym;
|
|
||||||
} else {
|
|
||||||
Util.Warn("keyDownList empty when keyPress triggered");
|
|
||||||
}
|
|
||||||
|
|
||||||
//show_keyDownList('press');
|
|
||||||
|
|
||||||
// Send the translated keysym
|
// Send the translated keysym
|
||||||
if (conf.onKeyPress && (keysym > 0)) {
|
if (conf.onKeyPress && (keysym > 0)) {
|
||||||
Util.Debug("onKeyPress down, keysym: " + keysym +
|
Util.Debug("onKeyPress down, keysym: " + keysym +
|
||||||
" (onKeyPress key: " + evt.keyCode +
|
" (onKeyPress key: " + evt.keyCode +
|
||||||
", which: " + evt.which + ")");
|
", which: " + evt.which + ")");
|
||||||
conf.onKeyPress(keysym, 1, evt);
|
Util.Debug("onKeyPress up, keysym: " + keysym +
|
||||||
|
" (onKeyPress key: " + evt.keyCode +
|
||||||
|
", which: " + evt.which + ")");
|
||||||
|
conf.onKeyPress(keysym, 2, evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop keypress events just in case
|
// Stop keypress events just in case
|
||||||
|
|
@ -397,12 +384,12 @@ function onKeyUp(e) {
|
||||||
if (fevt) {
|
if (fevt) {
|
||||||
keysym = fevt.keysym;
|
keysym = fevt.keysym;
|
||||||
} else {
|
} else {
|
||||||
Util.Warn("Key event (keyCode = " + evt.keyCode +
|
//Util.Debug("Key event (keyCode = " + evt.keyCode +
|
||||||
") not found on keyDownList");
|
// ") not found on keyDownMap");
|
||||||
keysym = 0;
|
keysym = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//show_keyDownList('up');
|
//show_keyDownMap('up');
|
||||||
|
|
||||||
if (conf.onKeyPress && (keysym > 0)) {
|
if (conf.onKeyPress && (keysym > 0)) {
|
||||||
//Util.Debug("keyPress up, keysym: " + keysym +
|
//Util.Debug("keyPress up, keysym: " + keysym +
|
||||||
|
|
@ -418,12 +405,9 @@ function onKeyUp(e) {
|
||||||
|
|
||||||
function allKeysUp() {
|
function allKeysUp() {
|
||||||
Util.Debug(">> Keyboard.allKeysUp");
|
Util.Debug(">> Keyboard.allKeysUp");
|
||||||
if (keyDownList.length > 0) {
|
var keyCode, keysym, fevt;
|
||||||
Util.Info("Releasing pressed/down keys");
|
for (keyCode in keyDownMap) {
|
||||||
}
|
fevt = getKeyEvent(keyCode, true);
|
||||||
var i, keysym, fevt = null;
|
|
||||||
for (i = keyDownList.length-1; i >= 0; i--) {
|
|
||||||
fevt = keyDownList.splice(i, 1)[0];
|
|
||||||
keysym = fevt.keysym;
|
keysym = fevt.keysym;
|
||||||
if (conf.onKeyPress && (keysym > 0)) {
|
if (conf.onKeyPress && (keysym > 0)) {
|
||||||
Util.Debug("allKeysUp, keysym: " + keysym +
|
Util.Debug("allKeysUp, keysym: " + keysym +
|
||||||
|
|
|
||||||
|
|
@ -601,7 +601,17 @@ keyPress = function(keysym, down) {
|
||||||
|
|
||||||
if (conf.view_only) { return; } // View only, skip keyboard events
|
if (conf.view_only) { return; } // View only, skip keyboard events
|
||||||
|
|
||||||
arr = keyEvent(keysym, down);
|
if (down === 2) {
|
||||||
|
// keypress event
|
||||||
|
// Send a keyup event here to avoid letting the server side generate
|
||||||
|
// repeated-key events. Otherwise, both sides will independently
|
||||||
|
// generate key down and press events against the same key.
|
||||||
|
arr = keyEvent(keysym, 1);
|
||||||
|
arr = arr.concat(keyEvent(keysym, 0));
|
||||||
|
} else {
|
||||||
|
// keydown or keyup event
|
||||||
|
arr = keyEvent(keysym, down);
|
||||||
|
}
|
||||||
arr = arr.concat(fbUpdateRequests());
|
arr = arr.concat(fbUpdateRequests());
|
||||||
ws.send(arr);
|
ws.send(arr);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue