Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
This repository was archived by the owner on Sep 8, 2021. It is now read-only.

Commit 49808f6

Browse filesBrowse files
Merge pull request livecode#7400 from livecodeian/bugfix-21001_regression
[[ emscripten ]] Use a single hidden input field for all LC windows
2 parents 70380da + 11ca633 commit 49808f6
Copy full SHA for 49808f6

File tree

Expand file treeCollapse file tree

1 file changed

+103
-54
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+103
-54
lines changed

‎engine/src/em-event.js

Copy file name to clipboardExpand all lines: engine/src/em-event.js
+103-54Lines changed: 103 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -30,66 +30,59 @@ mergeInto(LibraryManager.library, {
3030
// text element used to capture input events
3131
_inputelement: null,
3232

33+
// current target of keyboard / input events
34+
_inputtarget: null,
35+
3336
// This function is used to call a function for each event
3437
// type to handler mapping defined for LiveCode on Emscripten.
3538
//
36-
// The <func> must take three arguments: the event type, the
37-
// handler function used to handle that event type, and a
38-
// boolean indicating whether the event handler should be
39-
// attached to the hidden input control.
39+
// The <func> must take two arguments: the event type, and the
40+
// handler function used to handle that event type.
4041
_eventForEach: function(func) {
4142

4243
// Master mapping from event types to handler functions.
4344
var mapping = [
44-
['focus', LiveCodeEvents._handleFocusEvent, false],
45-
['blur', LiveCodeEvents._handleFocusEvent, false],
45+
['focus', LiveCodeEvents._handleFocusEvent],
46+
['blur', LiveCodeEvents._handleFocusEvent],
4647

47-
['mousemove', LiveCodeEvents._handleMouseEvent, false],
48-
['mousedown', LiveCodeEvents._handleMouseEvent, false],
49-
['mouseup', LiveCodeEvents._handleMouseEvent, false],
50-
['mouseenter', LiveCodeEvents._handleMouseEvent, false],
51-
['mouseleave', LiveCodeEvents._handleMouseEvent, false],
48+
['mousemove', LiveCodeEvents._handleMouseEvent],
49+
['mousedown', LiveCodeEvents._handleMouseEvent],
50+
['mouseup', LiveCodeEvents._handleMouseEvent],
51+
['mouseenter', LiveCodeEvents._handleMouseEvent],
52+
['mouseleave', LiveCodeEvents._handleMouseEvent],
5253

53-
['keyup', LiveCodeEvents._handleKeyboardEvent, true],
54-
['keydown', LiveCodeEvents._handleKeyboardEvent, true],
54+
['contextmenu', LiveCodeEvents._handleContextMenu],
55+
];
5556

56-
['input', LiveCodeEvents._handleInput, true],
57-
['beforeinput', LiveCodeEvents._handleInput, true],
57+
var mapLength = mapping.length;
58+
for (var i = 0; i < mapLength; i++) {
59+
func(mapping[i][0], mapping[i][1], mapping[i][2]);
60+
}
61+
},
5862

59-
['compositionstart', LiveCodeEvents._handleComposition, true],
60-
['compositionupdate', LiveCodeEvents._handleComposition, true],
61-
['compositionend', LiveCodeEvents._handleComposition, true],
62-
63-
['contextmenu', LiveCodeEvents._handleContextMenu, false],
63+
_inputEventForEach: function(pFunc) {
64+
var mapping = [
65+
['keyup', LiveCodeEvents._handleKeyboardEvent],
66+
['keydown', LiveCodeEvents._handleKeyboardEvent],
67+
68+
['input', LiveCodeEvents._handleInput],
69+
['beforeinput', LiveCodeEvents._handleInput],
70+
71+
['compositionstart', LiveCodeEvents._handleComposition],
72+
['compositionupdate', LiveCodeEvents._handleComposition],
73+
['compositionend', LiveCodeEvents._handleComposition],
6474
];
6575

6676
var mapLength = mapping.length;
6777
for (var i = 0; i < mapLength; i++) {
68-
func(mapping[i][0], mapping[i][1], mapping[i][2]);
78+
pFunc(mapping[i][0], mapping[i][1]);
6979
}
7080
},
7181

7282
addEventListeners: function(pElement)
7383
{
74-
// Create the hidden input element
75-
var tInput = document.createElement('input');
76-
tInput.type = 'text';
77-
tInput.style.position = 'absolute';
78-
tInput.style.zIndex = 0;
79-
tInput.style.opacity = 0;
80-
81-
LiveCodeEvents._inputelement = tInput;
82-
document.body.appendChild(tInput);
83-
84-
LiveCodeEvents._eventForEach(function(type, handler, addToInputField) {
85-
if (addToInputField)
86-
{
87-
tInput.addEventListener(type, function(e){
88-
handler(e, pElement);
89-
});
90-
}
91-
else
92-
pElement.addEventListener(type, handler, true);
84+
LiveCodeEvents._eventForEach(function(type, handler) {
85+
pElement.addEventListener(type, handler, true);
9386
});
9487

9588
// Make sure the canvas is treated as focusable...
@@ -106,9 +99,6 @@ mergeInto(LibraryManager.library, {
10699
LiveCodeEvents._eventForEach(function (type, handler) {
107100
pElement.removeEventListener(type, handler, true);
108101
});
109-
110-
document.body.removeChild(LiveCodeEvents._inputelement);
111-
LiveCodeEvents._inputelements = null;
112102
},
113103

114104
initialize: function() {
@@ -121,6 +111,20 @@ mergeInto(LibraryManager.library, {
121111
document.addEventListener("mouseup", LiveCodeEvents._handleDocumentMouseEvent);
122112
document.addEventListener("mousemove", LiveCodeEvents._handleDocumentMouseEvent);
123113

114+
// Create the hidden input element
115+
var tInput = document.createElement('input');
116+
tInput.type = 'text';
117+
tInput.style.position = 'absolute';
118+
tInput.style.zIndex = 0;
119+
tInput.style.opacity = 0;
120+
121+
LiveCodeEvents._inputelement = tInput;
122+
document.body.appendChild(tInput);
123+
124+
LiveCodeEvents._inputEventForEach(function(type, handler) {
125+
tInput.addEventListener(type, handler);
126+
});
127+
124128
LiveCodeEvents._initialised = true;
125129
},
126130

@@ -129,6 +133,9 @@ mergeInto(LibraryManager.library, {
129133
return;
130134
}
131135

136+
document.body.removeChild(LiveCodeEvents._inputelement);
137+
LiveCodeEvents._inputelements = null;
138+
132139
LiveCodeEvents._initialised = false;;
133140
},
134141

@@ -167,24 +174,64 @@ mergeInto(LibraryManager.library, {
167174
[stack, owner]);
168175
},
169176

177+
// When a LC canvas acquires focus, mark it as the current key focus target, then pass focus to the hidden input field
178+
_setInputFocus: function(pTarget) {
179+
if (pTarget != LiveCodeEvents._inputtarget)
180+
{
181+
if (LiveCodeEvents._inputtarget != null)
182+
{
183+
var tOldTarget = LiveCodeEvents._inputtarget;
184+
LiveCodeEvents._inputtarget = null;
185+
LiveCodeEvents._postKeyFocus(LiveCodeEvents._getStackForCanvas(tOldTarget), false);
186+
tOldTarget.blur();
187+
}
188+
189+
if (pTarget != null)
190+
{
191+
LiveCodeEvents._inputtarget = pTarget;
192+
LiveCodeEvents._postKeyFocus(LiveCodeEvents._getStackForCanvas(pTarget), true);
193+
}
194+
}
195+
196+
if (LiveCodeEvents._inputelement != null)
197+
LiveCodeEvents._inputelement.focus({"preventScroll": true});
198+
},
199+
170200
_handleFocusEvent: function(e) {
171201
LiveCodeAsync.delay(function() {
172202
var stack = LiveCodeEvents._getStackForCanvas(e.target);
203+
204+
// clear the current focus target when the hidden input field loses focus to a non-LC element.
205+
if (e.target == LiveCodeEvents._inputelement &&
206+
(e.type == 'blur' || e.type == 'focusout') &&
207+
LiveCodeEvents._getStackForCanvas(e.relatedTarget) == null)
208+
{
209+
_setInputFocus(null);
210+
return;
211+
}
212+
173213
// ignore events for non-lc elements
174214
if (!stack)
175215
return;
176216

177217
switch (e.type) {
178218
case 'focus':
179219
case 'focusin':
180-
LiveCodeEvents._postKeyFocus(stack, true);
181-
182-
// direct key events to input element
183-
LiveCodeEvents._inputelement.focus();
220+
LiveCodeEvents._setInputFocus(e.target);
184221
break;
185222
case 'blur':
186223
case 'focusout':
187-
LiveCodeEvents._postKeyFocus(stack, false);
224+
// ignore passing focus to hidden input field
225+
if (e.relatedTarget == LiveCodeEvents._inputelement)
226+
return;
227+
228+
// if losing focus to another LC stack don't remove focus here, as focus will
229+
// be reassigned in the 'focusin' event sent to that stack canvas
230+
var tFocusStack = LiveCodeEvents._getStackForCanvas(e.relatedTarget);
231+
if (tFocusStack != null)
232+
return;
233+
234+
LiveCodeEvents._setInputFocus(null);
188235
break;
189236
default:
190237
console.debug('Unexpected focus event type: ' + e.type);
@@ -531,14 +578,14 @@ mergeInto(LibraryManager.library, {
531578
[stack, modifiers, char_code, key_code, key_state]);
532579
},
533580

534-
_handleKeyboardEvent: function(e, pCanvas) {
581+
_handleKeyboardEvent: function(e) {
535582
LiveCodeAsync.delay(function() {
536583

537584
const kKeyStateDown = 0;
538585
const kKeyStateUp = 1;
539586
const kKeyStatePressed = 2;
540587

541-
var stack = LiveCodeEvents._getStackForCanvas(pCanvas);
588+
var stack = LiveCodeEvents._getStackForCanvas(LiveCodeEvents._inputtarget);
542589
/* TODO - reenable alt key detection
543590
* As there is no direct way to tell the difference between an alt+<key>
544591
* combination that produces a different character, and holding alt down
@@ -603,7 +650,7 @@ mergeInto(LibraryManager.library, {
603650
[stack, enabled, offset, chars, length]);
604651
},
605652

606-
_handleInput: function(inputEvent, pCanvas) {
653+
_handleInput: function(inputEvent) {
607654
console.debug('Input event: ' + inputEvent.type + ' ' + inputEvent.data);
608655
},
609656

@@ -612,15 +659,16 @@ mergeInto(LibraryManager.library, {
612659
return [buffer, string.length];
613660
},
614661

615-
_handleComposition: function(compositionEvent, pCanvas) {
662+
_handleComposition: function(compositionEvent) {
616663
LiveCodeAsync.delay(function() {
617664
// Stack that we're targeting
618-
var stack = LiveCodeEvents._getStackForCanvas(pCanvas);
665+
var stack = LiveCodeEvents._getStackForCanvas(LiveCodeEvents._inputtarget);
619666

620667
// ignore events for non-lc elements
621668
if (!stack)
622669
return;
623670

671+
console.log('composition event: ' + compositionEvent.type + " '" + compositionEvent.data + "'");
624672
var encodedString;
625673
var chars, length;
626674
switch (compositionEvent.type) {
@@ -759,7 +807,8 @@ mergeInto(LibraryManager.library, {
759807
case 'mousedown':
760808
// In the case of mouse down, specifically request
761809
// keyboard focus
762-
e.target.focus();
810+
LiveCodeEvents._setInputFocus(target);
811+
763812
LiveCodeEvents._postMousePosition(stack, e.timeStamp, mods, pos[0], pos[1]);
764813
var state = LiveCodeEvents._encodeMouseState(e.type);
765814
LiveCodeEvents._postMousePress(stack, e.timeStamp, mods,

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.