Skip to content

Commit d47b38d

Browse files
committed
Implement targetX and targetY fields for mouse and touch events, #2751. Bump version to 1.23.4 to rebuild cache since src/struct_info.json changes.
1 parent eff15fb commit d47b38d

File tree

5 files changed

+55
-12
lines changed

5 files changed

+55
-12
lines changed

emscripten-version.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
1.23.3
1+
1.23.4
22

site/source/docs/api_reference/html5.h.rst

+11-1
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,11 @@ Struct
387387
388388
If pointer lock is active, these two extra fields give relative mouse movement since the last event.
389389

390+
.. c:member:: long targetX
391+
long targetY
392+
393+
These fields give the mouse coordinates mapped relative to the coordinate space of the target DOM element receiving the input events (Emscripten-specific extension).
394+
390395

391396
.. c:member:: long canvasX
392397
long canvasY
@@ -1360,10 +1365,15 @@ Struct
13601365
13611366
Specifies whether this touch point is still above the original target on which it was initially pressed.
13621367
1368+
.. c:member:: long targetX
1369+
long targetY
1370+
1371+
These fields give the touch coordinates mapped relative to the coordinate space of the target DOM element receiving the input events (Emscripten-specific extension).
1372+
13631373
.. c:member:: long canvasX
13641374
long canvasY
13651375
1366-
The touch coordinates mapped to the Emscripten canvas client area, in pixels.
1376+
The touch coordinates mapped to the Emscripten canvas client area, in pixels (Emscripten-specific extension).
13671377
13681378
13691379

src/library_html5.js

+35-10
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,11 @@ var LibraryJSEvents = {
197197
JSEvents.registerOrRemoveHandler(eventHandler);
198198
},
199199

200-
fillMouseEventData: function(eventStruct, e) {
200+
// Copies mouse event data from the given JS mouse event 'e' to the specified Emscripten mouse event structure in the HEAP.
201+
// eventStruct: the structure to populate.
202+
// e: The JS mouse event to read data from.
203+
// target: Specifies a target DOM element that will be used as the reference to populate targetX and targetY parameters.
204+
fillMouseEventData: function(eventStruct, e, target) {
201205
{{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenMouseEvent.timestamp, 'JSEvents.tick()', 'double') }}};
202206
{{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenMouseEvent.screenX, 'e.screenX', 'i32') }}};
203207
{{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenMouseEvent.screenY, 'e.screenY', 'i32') }}};
@@ -220,6 +224,14 @@ var LibraryJSEvents = {
220224
{{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenMouseEvent.canvasX, '0', 'i32') }}};
221225
{{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenMouseEvent.canvasY, '0', 'i32') }}};
222226
}
227+
if (target) {
228+
var rect = (target === window) ? { left: 0, top: 0 } : target.getBoundingClientRect();
229+
{{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenMouseEvent.targetX, 'e.clientX - rect.left', 'i32') }}};
230+
{{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenMouseEvent.targetY, 'e.clientY - rect.top', 'i32') }}};
231+
} else { // No specific target passed, return 0.
232+
{{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenMouseEvent.targetX, '0', 'i32') }}};
233+
{{{ makeSetValue('eventStruct', C_STRUCTS.EmscriptenMouseEvent.targetY, '0', 'i32') }}};
234+
}
223235
JSEvents.previousScreenX = e.screenX;
224236
JSEvents.previousScreenY = e.screenY;
225237
},
@@ -228,17 +240,18 @@ var LibraryJSEvents = {
228240
if (!JSEvents.mouseEvent) {
229241
JSEvents.mouseEvent = _malloc( {{{ C_STRUCTS.EmscriptenMouseEvent.__size__ }}} );
230242
}
243+
target = JSEvents.findEventTarget(target);
231244
var handlerFunc = function(event) {
232245
var e = event || window.event;
233-
JSEvents.fillMouseEventData(JSEvents.mouseEvent, e);
246+
JSEvents.fillMouseEventData(JSEvents.mouseEvent, e, target);
234247
var shouldCancel = Runtime.dynCall('iiii', callbackfunc, [eventTypeId, JSEvents.mouseEvent, userData]);
235248
if (shouldCancel) {
236249
e.preventDefault();
237250
}
238251
};
239252

240253
var eventHandler = {
241-
target: JSEvents.findEventTarget(target),
254+
target: target,
242255
allowsDeferredCalls: eventTypeString != 'mousemove', // Mouse move events do not allow fullscreen/pointer lock requests to be handled in them!
243256
eventTypeString: eventTypeString,
244257
callbackfunc: callbackfunc,
@@ -254,10 +267,11 @@ var LibraryJSEvents = {
254267
if (!JSEvents.wheelEvent) {
255268
JSEvents.wheelEvent = _malloc( {{{ C_STRUCTS.EmscriptenWheelEvent.__size__ }}} );
256269
}
270+
target = JSEvents.findEventTarget(target);
257271
// The DOM Level 3 events spec event 'wheel'
258272
var wheelHandlerFunc = function(event) {
259273
var e = event || window.event;
260-
JSEvents.fillMouseEventData(JSEvents.wheelEvent, e);
274+
JSEvents.fillMouseEventData(JSEvents.wheelEvent, e, target);
261275
{{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaX, 'e["deltaX"]', 'double') }}};
262276
{{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaY, 'e["deltaY"]', 'double') }}};
263277
{{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaZ, 'e["deltaZ"]', 'double') }}};
@@ -270,7 +284,7 @@ var LibraryJSEvents = {
270284
// The 'mousewheel' event as implemented in Safari 6.0.5
271285
var mouseWheelHandlerFunc = function(event) {
272286
var e = event || window.event;
273-
JSEvents.fillMouseEventData(JSEvents.wheelEvent, e);
287+
JSEvents.fillMouseEventData(JSEvents.wheelEvent, e, target);
274288
{{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaX, 'e["wheelDeltaX"]', 'double') }}};
275289
{{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaY, '-e["wheelDeltaY"] /* Invert to unify direction with the DOM Level 3 wheel event. */', 'double') }}};
276290
{{{ makeSetValue('JSEvents.wheelEvent', C_STRUCTS.EmscriptenWheelEvent.deltaZ, '0 /* Not available */', 'double') }}};
@@ -282,7 +296,7 @@ var LibraryJSEvents = {
282296
};
283297

284298
var eventHandler = {
285-
target: JSEvents.findEventTarget(target),
299+
target: target,
286300
allowsDeferredCalls: true,
287301
eventTypeString: eventTypeString,
288302
callbackfunc: callbackfunc,
@@ -699,6 +713,8 @@ var LibraryJSEvents = {
699713
JSEvents.touchEvent = _malloc( {{{ C_STRUCTS.EmscriptenTouchEvent.__size__ }}} );
700714
}
701715

716+
target = JSEvents.findEventTarget(target);
717+
702718
var handlerFunc = function(event) {
703719
var e = event || window.event;
704720

@@ -723,7 +739,8 @@ var LibraryJSEvents = {
723739
{{{ makeSetValue('ptr', C_STRUCTS.EmscriptenTouchEvent.altKey, 'e.altKey', 'i32') }}};
724740
{{{ makeSetValue('ptr', C_STRUCTS.EmscriptenTouchEvent.metaKey, 'e.metaKey', 'i32') }}};
725741
ptr += {{{ C_STRUCTS.EmscriptenTouchEvent.touches }}}; // Advance to the start of the touch array.
726-
var rect = Module['canvas'].getBoundingClientRect();
742+
var canvasRect = Module['canvas'] ? Module['canvas'].getBoundingClientRect() : undefined;
743+
var targetRect = (target === window) ? { left: 0, top: 0 } : target.getBoundingClientRect();
727744
var numTouches = 0;
728745
for(var i in touches) {
729746
var t = touches[i];
@@ -736,8 +753,16 @@ var LibraryJSEvents = {
736753
{{{ makeSetValue('ptr', C_STRUCTS.EmscriptenTouchPoint.pageY, 't.pageY', 'i32') }}};
737754
{{{ makeSetValue('ptr', C_STRUCTS.EmscriptenTouchPoint.isChanged, 't.changed', 'i32') }}};
738755
{{{ makeSetValue('ptr', C_STRUCTS.EmscriptenTouchPoint.onTarget, 't.onTarget', 'i32') }}};
739-
{{{ makeSetValue('ptr', C_STRUCTS.EmscriptenTouchPoint.canvasX, 't.clientX - rect.left', 'i32') }}};
740-
{{{ makeSetValue('ptr', C_STRUCTS.EmscriptenTouchPoint.canvasY, 't.clientY - rect.top', 'i32') }}};
756+
if (canvasRect) {
757+
{{{ makeSetValue('ptr', C_STRUCTS.EmscriptenTouchPoint.canvasX, 't.clientX - canvasRect.left', 'i32') }}};
758+
{{{ makeSetValue('ptr', C_STRUCTS.EmscriptenTouchPoint.canvasY, 't.clientY - canvasRect.top', 'i32') }}};
759+
} else {
760+
{{{ makeSetValue('ptr', C_STRUCTS.EmscriptenTouchPoint.canvasX, '0', 'i32') }}};
761+
{{{ makeSetValue('ptr', C_STRUCTS.EmscriptenTouchPoint.canvasY, '0', 'i32') }}};
762+
}
763+
{{{ makeSetValue('ptr', C_STRUCTS.EmscriptenTouchPoint.targetX, 't.clientX - targetRect.left', 'i32') }}};
764+
{{{ makeSetValue('ptr', C_STRUCTS.EmscriptenTouchPoint.targetY, 't.clientY - targetRect.top', 'i32') }}};
765+
741766
ptr += {{{ C_STRUCTS.EmscriptenTouchPoint.__size__ }}};
742767

743768
if (++numTouches >= 32) {
@@ -753,7 +778,7 @@ var LibraryJSEvents = {
753778
};
754779

755780
var eventHandler = {
756-
target: JSEvents.findEventTarget(target),
781+
target: target,
757782
allowsDeferredCalls: false, // XXX Currently disabled, see bug https://bugzilla.mozilla.org/show_bug.cgi?id=966493
758783
// Once the above bug is resolved, enable the following condition if possible:
759784
// allowsDeferredCalls: eventTypeString == 'touchstart',

src/struct_info.json

+4
Original file line numberDiff line numberDiff line change
@@ -1192,6 +1192,8 @@
11921192
"buttons",
11931193
"movementX",
11941194
"movementY",
1195+
"targetX",
1196+
"targetY",
11951197
"canvasX",
11961198
"canvasY"
11971199
],
@@ -1269,6 +1271,8 @@
12691271
"pageY",
12701272
"isChanged",
12711273
"onTarget",
1274+
"targetX",
1275+
"targetY",
12721276
"canvasX",
12731277
"canvasY"
12741278
],

system/include/emscripten/html5.h

+4
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ typedef struct EmscriptenMouseEvent {
109109
unsigned short buttons;
110110
long movementX;
111111
long movementY;
112+
long targetX;
113+
long targetY;
112114
long canvasX;
113115
long canvasY;
114116
long padding;
@@ -281,6 +283,8 @@ typedef struct EmscriptenTouchPoint
281283
long pageY;
282284
EM_BOOL isChanged;
283285
EM_BOOL onTarget;
286+
long targetX;
287+
long targetY;
284288
long canvasX;
285289
long canvasY;
286290
} EmscriptenTouchPoint;

0 commit comments

Comments
 (0)