[Laszlo-checkins] r14129 - in openlaszlo/trunk: . WEB-INF/lps/lfc/kernel/dhtml WEB-INF/lps/lfc/kernel/swf WEB-INF/lps/lfc/kernel/swf9 WEB-INF/lps/lfc/services lps/includes/source
ptw@openlaszlo.org
ptw at openlaszlo.org
Fri Jun 12 14:58:04 PDT 2009
Author: ptw
Date: 2009-06-12 14:58:00 -0700 (Fri, 12 Jun 2009)
New Revision: 14129
Modified:
openlaszlo/trunk/
openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzKeyboardKernel.js
openlaszlo/trunk/WEB-INF/lps/lfc/kernel/swf/LzKeyboardKernel.as
openlaszlo/trunk/WEB-INF/lps/lfc/kernel/swf9/LzKeyboardKernel.as
openlaszlo/trunk/WEB-INF/lps/lfc/services/LzKeys.lzs
openlaszlo/trunk/lps/includes/source/embednew.js
Log:
Merged revisions 14112 via svnmerge from
http://svn.openlaszlo.org/openlaszlo/branches/4.2
.......
r14112 | ptw | 2009-06-10 17:01:41 -0400 (Wed, 10 Jun 2009) | 30 lines
Change 20090609-ptw-V by ptw at dueling-banjos.local on 2009-06-09 16:28:34 EDT
in /Users/ptw/OpenLaszlo/4.2
for http://svn.openlaszlo.org/openlaszlo/branches/4.2
Summary: Clear stuck keys on browser focus
Bugs Fixed: LPP-8056 Alt tab issue when switching tasks (partial)
Technical Reviewer: max (Message-ID: <4A300705.4070400 at laszlosystems.com>)
QA Reviewer: aalappat at laszlosystems.com (pending)
Details:
This fixes the bug in all browsers _except_ IE, where it only
reduces the bug somewhat. I'm putting in this partial fix just so
the work is not lost.
LzKeyboardKernel.*: Add an __allKeysUp call that will simulate
key up events for any keys that the kernel believes to (still) be
down.
LzKeys: __allKeysUp exported so it can be called from lz.embed
embednew: When the browser regains focus, invoke
lz.Keys.__allKeysUp to clear any keys that may appear to still be
down because the browser lost focus due to keyboard input.
Tests:
Test case from the bug report
.......
Property changes on: openlaszlo/trunk
___________________________________________________________________
Name: svnmerge-integrated
- /openlaszlo/branches/4.1:1-10153 /openlaszlo/branches/4.2:1-12154,12181,13205,13778 /openlaszlo/branches/4.4:1-13936,14007 /openlaszlo/branches/devildog:1-8432 /openlaszlo/branches/pagan-deities:1-7955,8825,10756-10920,10922-10928,10930-10935,11151,11207,11554,13476,13629 /openlaszlo/branches/paperpie:1-6504,6506-6574,6576-7135,7137-7235 /openlaszlo/branches/wafflecone:1-5746,5818-6068,6070-6205,6207-6213,6216-6265,6267-6368,6370-6431,6433-6450,6497,6509,6661,7097,7872 /openlaszlo/trunk:1-3892,3894-3952,3954-4393,4395-4461,4463-4467,4469-4471,4473-5085,5087-5171,5173-5203,5205-5209,5211-5331,5333-5334
+ /openlaszlo/branches/4.1:1-10153 /openlaszlo/branches/4.2:1-12154,12181,13205,13778,14112 /openlaszlo/branches/4.4:1-13936,14007 /openlaszlo/branches/devildog:1-8432 /openlaszlo/branches/pagan-deities:1-7955,8825,10756-10920,10922-10928,10930-10935,11151,11207,11554,13476,13629 /openlaszlo/branches/paperpie:1-6504,6506-6574,6576-7135,7137-7235 /openlaszlo/branches/wafflecone:1-5746,5818-6068,6070-6205,6207-6213,6216-6265,6267-6368,6370-6431,6433-6450,6497,6509,6661,7097,7872 /openlaszlo/trunk:1-3892,3894-3952,3954-4393,4395-4461,4463-4467,4469-4471,4473-5085,5087-5171,5173-5203,5205-5209,5211-5331,5333-5334
Modified: openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzKeyboardKernel.js
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzKeyboardKernel.js 2009-06-12 19:35:15 UTC (rev 14128)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzKeyboardKernel.js 2009-06-12 21:58:00 UTC (rev 14129)
@@ -11,8 +11,8 @@
// Receives keyboard events from the runtime
var LzKeyboardKernel = {
- __downKeysHash: {alt: false, control: false, shift: false, meta: false}
- ,__keyCodes: {}
+ // Key is the character (or a name for shift keys), value is the keycode
+ __downKeysHash: {}
,__keyboardEvent: function ( e ){
if (!e) e = window.event;
var delta = {};
@@ -25,19 +25,18 @@
if (k >= 0 && k != 16 && k != 17 && k != 18 && k != 224) {
// TODO: add mapping to flash character codes?
var s = String.fromCharCode(k).toLowerCase();
- LzKeyboardKernel.__keyCodes[s] = k;
if (t == 'keyup') {
- if (dh[s] != false) {
+ if (dh[s] != null) {
delta[s] = false;
dirty = true;
}
- dh[s] = false;
+ dh[s] = null;
} else if (t == 'keydown') {
- if (dh[s] != true) {
+ if (dh[s] == null) {
delta[s] = true;
dirty = true;
}
- dh[s] = true;
+ dh[s] = k;
}
}
@@ -59,7 +58,8 @@
//Debug.write('canceling tab');
e.cancelBubble = true;
return false;
- } else if (LzKeyboardKernel.__cancelKeys && (k == 13 || k == 0 || k == 37 || k == 38 || k == 39 || k == 40) ) {
+ } else if (LzKeyboardKernel.__cancelKeys &&
+ (k == 13 || k == 0 || k == 37 || k == 38 || k == 39 || k == 40) ) {
//Debug.write('canceling key', k, t);
// cancel event bubbling for enter, space(scroll) and arrow keys
e.cancelBubble = true;
@@ -80,68 +80,84 @@
var send = true;
}
var alt = e['altKey'];
- if (dh['alt'] != alt) {
+ if ((dh['alt'] != null) != alt) {
+ dh['alt'] = alt?18:null;
delta['alt'] = alt;
- dirty = true;
+ dirty = send;
if (quirks['alt_key_sends_control']) {
delta['control'] = delta['alt'];
}
}
+
var ctrl = e['ctrlKey'];
- if (dh['control'] != ctrl) {
+ if ((dh['control'] != null) != ctrl) {
+ dh['control'] = ctrl?17:null;
delta['control'] = ctrl;
- dirty = true;
+ dirty = send;
}
+
var shift = e['shiftKey'];
- if (dh['shift'] != shift) {
+ if ((dh['shift'] != null) != shift) {
+ dh['shift'] = shift?16:null;
delta['shift'] = shift;
- dirty = true;
+ dirty = send;
}
- var stuck;
+
var meta = e['metaKey'];
- if (quirks['detectstuckkeys']) {
- // see LPP-8210
- if (dh['meta'] != meta) {
- // look for stuck keys
- delta['control'] = meta;
- dirty = true;
+ if ((dh['meta'] != null) != meta) {
+ dh['meta'] = meta?224:null;
+ delta['meta'] = meta;
+ dirty = send;
+ // Is this a quirk?
+ delta['control'] = meta;
+ // look for stuck keys (see LPP-8210)
+ if (quirks['detectstuckkeys']) {
if (! meta) {
- for (var key in dh) {
- if (key == 'control' || key == 'shift' || key == 'alt' || key == 'meta') continue;
- stuck = key;
- delete dh[key];
- }
+ // If meta goes up, clear all the other keys
+ LzKeyboardKernel.__allKeysUp();
+ dirty = false;
}
- }
+ }
}
- dh['alt'] = alt;
- dh['control'] = ctrl;
- dh['shift'] = shift;
- dh['meta'] = meta;
-
- if (dirty && (send || stuck)) {
+ if (dirty) {
var scope = LzKeyboardKernel.__scope;
var callback = LzKeyboardKernel.__callback;
if (scope && scope[callback]) {
- //console.log(t, s, k, delta, e.metaKey, e.ctrlKey, dh);
- if (stuck) {
- // console.log('stuck key', key, keycode);
- var keycode = LzKeyboardKernel.__keyCodes[stuck];
- var fakedelta = {};
- // FIXME: [20090602 anba] 'key' seems to be a typo, should it be 'stuck'?
- fakedelta[key] = false;
- scope[callback](fakedelta, keycode, 'onkeyup');
- }
-
- if (send) {
- scope[callback](delta, 0, 'on' + e.type);
- }
+ scope[callback](delta, 0, 'on' + e.type);
}
}
return dirty;
}
+ // Called by lz.embed when the browser window regains focus
+ ,__allKeysUp: function () {
+ var delta = {};
+ var stuck = false;
+ var keys;
+ var dh = LzKeyboardKernel.__downKeysHash;
+ for (var key in dh) {
+ if (dh[key] != null) {
+ stuck = true;
+ delta[key] = false;
+ if (key.length == 1) {
+ if (! keys) { keys = []; }
+ keys.push(dh[key]);
+ }
+ }
+ }
+// Debug.info("[%6.2f] All keys up: %w, %w", (new Date).getTime() % 1000000, delta, keys);
+ var scope = LzKeyboardKernel.__scope;
+ var callback = LzKeyboardKernel.__callback;
+ if (stuck && scope && scope[callback]) {
+ if (!keys) {
+ scope[callback](delta, 0, 'onkeyup');
+ } else for (var i = 0, l = keys.length; i < l; i++) {
+ scope[callback](delta, keys[i], 'onkeyup');
+ }
+ }
+ LzKeyboardKernel.__downKeysHash = {};
+ }
,__callback: null
,__scope: null
,__cancelKeys: true
Modified: openlaszlo/trunk/WEB-INF/lps/lfc/kernel/swf/LzKeyboardKernel.as
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/kernel/swf/LzKeyboardKernel.as 2009-06-12 19:35:15 UTC (rev 14128)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/kernel/swf/LzKeyboardKernel.as 2009-06-12 21:58:00 UTC (rev 14129)
@@ -37,17 +37,17 @@
//Debug.info("__keyboardEvent k=%w s=%w %w ctrl=%w, delta=%w", k,s,t, ctrl,delta);
if (t == 'onkeyup') {
- if (dh[s] != false) {
+ if (dh[s] != null) {
delta[s] = false;
dirty = true;
}
- dh[s] = false;
+ dh[s] = null;
} else if (t == 'onkeydown') {
- if (dh[s] != true) {
+ if (dh[s] == null) {
delta[s] = true;
dirty = true;
}
- dh[s] = true;
+ dh[s] = k;
}
//Debug.write('downKeysHash', t, k, dh, delta);
@@ -55,13 +55,41 @@
LzKeyboardKernel.__scope[LzKeyboardKernel.__callback](delta, k, t, ctrl);
}
}
- ,__codes: {16: 'shift', 17: 'control'}
+ ,__codes: {16: 'shift', 17: 'control', 18: 'alt'}
,__callback: null
,__scope: null
,setCallback: function (scope, funcname) {
this.__scope = scope;
this.__callback = funcname;
}
+ // Called by lz.embed when the browser window regains focus
+ ,__allKeysUp: function () {
+ var delta = {};
+ var stuck = false;
+ var keys;
+ var dh = LzKeyboardKernel.__downKeysHash;
+ for (var key in dh) {
+ if (dh[key] != null) {
+ stuck = true;
+ delta[key] = false;
+ if (key.length == 1) {
+ if (! keys) { keys = []; }
+ keys.push(dh[key]);
+ }
+ }
+ }
+// Debug.info("[%6.2f] All keys up: %w, %w", (new Date).getTime() % 1000000, delta, keys);
+ var scope = LzKeyboardKernel.__scope;
+ var callback = LzKeyboardKernel.__callback;
+ if (stuck && scope && scope[callback]) {
+ if (!keys) {
+ scope[callback](delta, 0, 'onkeyup');
+ } else for (var i = 0, l = keys.length; i < l; i++) {
+ scope[callback](delta, keys[i], 'onkeyup');
+ }
+ }
+ LzKeyboardKernel.__downKeysHash = {};
+ }
// Called by lz.Keys when the last focusable element was reached.
,gotLastFocus: function () {
}
Modified: openlaszlo/trunk/WEB-INF/lps/lfc/kernel/swf9/LzKeyboardKernel.as
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/kernel/swf9/LzKeyboardKernel.as 2009-06-12 19:35:15 UTC (rev 14128)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/kernel/swf9/LzKeyboardKernel.as 2009-06-12 21:58:00 UTC (rev 14129)
@@ -23,8 +23,8 @@
// prevent duplicate onkeydown events - see LPP-7432
- if (__keyState[k] == keyisdown) return;
- __keyState[k] = keyisdown;
+ if ((__keyState[k] != null) == keyisdown) return;
+ __keyState[k] = keyisdown?k:null;
delta[s] = keyisdown;
var ctrl:Boolean = e.ctrlKey;
@@ -49,6 +49,30 @@
}
}
+ // Called by lz.embed when the browser window regains focus
+ static function __allKeysUp () {
+ var delta = {};
+ var stuck = false;
+ var keys;
+ for (var key in __keyState) {
+ if (__keyState[key] != null) {
+ stuck = true;
+ delta[key] = false;
+ if (! keys) { keys = []; }
+ keys.push(__keyState[key]);
+ }
+ }
+// Debug.info("[%6.2f] All keys up: %w", (new Date).getTime() % 1000000, delta);
+ if (stuck && __scope && __scope[__callback]) {
+ if (!keys) {
+ __scope[__callback](delta, 0, 'onkeyup');
+ } else for (var i = 0, l = keys.length; i < l; i++) {
+ __scope[__callback](delta, keys[i], 'onkeyup');
+ }
+ }
+ __keyState = {};
+ }
+
// Called by lz.Keys when the last focusable element was reached.
static function gotLastFocus() :void {
}
Modified: openlaszlo/trunk/WEB-INF/lps/lfc/services/LzKeys.lzs
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/services/LzKeys.lzs 2009-06-12 19:35:15 UTC (rev 14128)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/services/LzKeys.lzs 2009-06-12 21:58:00 UTC (rev 14129)
@@ -51,11 +51,14 @@
/** @access private */
function LzKeysService() {
- super();
// if (LzKeysService.LzKeys) {
// throw new Error("There can be only one LzKeys");
// }
+ super();
+
if ($as3) {
+ // NOTE: [2009-06-04 ptw] Apparently handled in
+ // LFCApplication, I don't know why...
} else {
LzKeyboardKernel.setCallback(this, '__keyEvent');
}
@@ -143,6 +146,14 @@
}
/**
+ * Trampoline so we can call from lz.embed
+ * @access private
+ */
+ function __allKeysUp ():void {
+ LzKeyboardKernel.__allKeysUp();
+ }
+
+ /**
* Called whenever a key is pressed with the Flash keycode corresponding to
* the down key.
*
Modified: openlaszlo/trunk/lps/includes/source/embednew.js
===================================================================
--- openlaszlo/trunk/lps/includes/source/embednew.js 2009-06-12 19:35:15 UTC (rev 14128)
+++ openlaszlo/trunk/lps/includes/source/embednew.js 2009-06-12 21:58:00 UTC (rev 14129)
@@ -136,6 +136,7 @@
,_getSWFDiv: lz.embed._getSWFDiv
,loaded: false
,_sendMouseWheel: lz.embed._sendMouseWheel
+ ,_sendAllKeysUp: lz.embed._sendAllKeysUpSWF
,_setCanvasAttributeDequeue: lz.embed._setCanvasAttributeDequeue
,_sendPercLoad: lz.embed._sendPercLoad
}
@@ -254,6 +255,7 @@
,loaded: false
,setCanvasAttribute: lz.embed._setCanvasAttributeDHTML
,getCanvasAttribute: lz.embed._getCanvasAttributeDHTML
+ ,_sendAllKeysUp: lz.embed._sendAllKeysUpDHTML
}
// listen for history unless properties.history == false
if (properties.history == false) {
@@ -682,6 +684,21 @@
if (d != null) this.callMethod("lz.Keys.__mousewheelEvent(" + d + ")");
}
,/** @access private */
+ _gotFocus: function() {
+ lz.embed._broadcastMethod('_sendAllKeysUp');
+ }
+ ,/** @access private */
+ _sendAllKeysUpSWF: function () {
+ this.callMethod("lz.Keys.__allKeysUp()");
+ }
+ ,/** @access private */
+ _sendAllKeysUpDHTML: function () {
+ // How to deal with multiple DHTML apps on a page?
+ if (LzKeyboardKernel && LzKeyboardKernel['__allKeysUp']) {
+ LzKeyboardKernel.__allKeysUp();
+ }
+ }
+ ,/** @access private */
_sendPercLoad: function(p) {
//alert('onpercload' + p);
if (this.onloadstatus && typeof this.onloadstatus == 'function') {
@@ -855,6 +872,12 @@
// Clean up global handlers
lz.embed.attachEventHandler(window, 'beforeunload', lz.embed, '_cleanupHandlers');
+// Notice that you got focus
+lz.embed.attachEventHandler(window, 'focus', lz.embed, '_gotFocus');
+if (lz.embed.browser.isIE) {
+ lz.embed.attachEventHandler(window, 'activate', lz.embed, '_gotFocus');
+}
+
// for backward compatibility
#pragma "passThrough=true"
try {
More information about the Laszlo-checkins
mailing list