Error on listening to mouse events using emscripten 's HTML5 C API ?

1,001 views
Skip to first unread message

nagappan nachiappan

unread,
Jul 11, 2014, 2:39:49 AM7/11/14
to emscripte...@googlegroups.com

I am using the HTML5 C Api in the Emscripten project to listen to DOM events  ( A big thanks to Jukka ! ) :



I subscribed to keyboard and mouse events in the following way :

    #include <emscripten.h>
    #include <emscripten/html5.h>
    #include <stdio.h>
    
    EM_BOOL key_callback(int eventType, const EmscriptenKeyboardEvent *e, void *userData)
    {
      printf("You pressed key %lu\n", e->which);
      return 1;
    }
    
    EM_BOOL click_callback(int eventType, const EmscriptenMouseEvent *e, void *userData)
    {
      printf("You just clicked\n");
      return 1;
    }
    
    int main()
    {
      emscripten_set_keypress_callback(0, 0, 1, key_callback);
      emscripten_set_click_callback( "#document" ,  0, 1, click_callback);
    
      EM_ASM(Module['noExitRuntime'] = true);
      return 0;
    }

I included the a.out.js in my HTML and the callbacks for keyboard gets called without any issues. But I see some issues when a mouse event is triggered. Sample Log  ( 1st line for keyboard input and 2nd for mouse )

You pressed key 116
Uncaught TypeError: Cannot read property 'getBoundingClientRect' of undefined

And this is where the exception happens in code :
(a.out.js)
fillMouseEventData:function (eventStruct, e) {
        var rect = Module['canvas'].getBoundingClientRect();
        HEAPF64[((eventStruct)>>3)]=JSEvents.tick();

The Module['canvas'] object is not defined. 
I think this Module['canvas'] is applicable only when we are listening to events on a canvas generated from C/C++.

But in my case, I want to listen to the entire document. I do specify that in the C API  ( in the above C code ):
 emscripten_set_click_callback("#document", 0, 1, click_callback);

Also, it is being set properly when the event is regitered in JS glue function and that's why it work as expected for Keyboard input:
(a.out.js)
var eventHandler = {
          target: JSEvents.findEventTarget(target),
          allowsDeferredCalls: JSEvents.isInternetExplorer() ? false : true, // MSIE doesn't allow fullscreen and pointerlock requests from key handlers, others do.
          eventTypeString: eventTypeString,
          callbackfunc: callbackfunc,
          handlerFunc: handlerFunc,
          useCapture: useCapture
        };

It is just that in the case of Mouse events , there is an access to a non-existent Module['canvas'] object in my context.
3 questions :
Is this a bug ?
How do I get around this ?
Am I missing out something here ?

-Nagappan

jj

unread,
Jul 11, 2014, 4:47:56 AM7/11/14
to emscripte...@googlegroups.com
Thanks!

The default shell.html should populate the Module['canvas'] object for you. See https://github.com/kripken/emscripten/blob/master/src/shell.html#L1248 where it gets defined. If that is null for you, then either your page no longer has a canvas element, or the shell.html you are using doesn't contain that code.

In either case, the HTML5 API should of course work when/if there is no Module['canvas'] object defined in the page. I pushed in a fix to the incoming branch at https://github.com/kripken/emscripten/commit/40675ca6b9c839cedd357f3bd161abeda4dd58b5 . Let me know how that works out for you?

   Jukka

nagappan nachiappan

unread,
Jul 11, 2014, 6:16:39 AM7/11/14
to emscripte...@googlegroups.com
Hey Jukka,

That was quick.
I am sure this will fix my problem. I will wait for the build.
I didn't use the shell.html .

Anyway, do you think this fix will also satisfy the case when the user defines his own Canvas element in the HTML and subscribes to events on that canvas.
Module['canvas'] may not be defined , but there is still a canvas and the getBoundingClientRect(); should be called on the user-defined canvas element.
I noticed that the mouse event contains info of the target element . 
Maybe that can be used :

fillMouseEventData: function(eventStruct, e) {
if( e.currentTarget.getBoundingClientRect)  
var rect = e.currentTarget.getBoundingClientRect();
... 



-Nagappan

Jukka Jylänki

unread,
Jul 11, 2014, 6:26:34 AM7/11/14
to emscripte...@googlegroups.com
Yeah, I considered changing the format of the code to that, but then hesitated, since the existing documentation states the fields are specifically for Module['canvas'], and if I changed the code to above form, .canvasX and .canvasY would switch to reporting coordinates relative to the document origin by default when user specifies the default target = 0. Passing results relative to e.currentTarget is doable, but it would be better to create separate fields to the mouse event struct for that, e.g. .targetX and .targetY in order to no break code for existing users.

If you do have your own custom canvas element, you can give it an id='canvas' or manually assign it to Module.canvas = myCanvas; in JS to make the existing code find your canvas element. There is no need to separate "the user's own Canvas element" and "the Emscripten canvas element", but you can just have your own and make sure Module.canvas points to that. Is there some reason why you cannot set the canvas to Module.canvas?

Please raise a github issue item for a feature request on .targetX and .targetY if you cannot solve it otherwise,
   Jukka


--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

nagappan nachiappan

unread,
Sep 2, 2014, 10:06:42 AM9/2/14
to emscripte...@googlegroups.com
Well, in my case I have multiple canvases. I want to listen to mouse events on each one of them and handle them differently. 
Assigning Module.canvas to those canvases would be an overkill. I will raise an issue on this on github.Thanks.

-Nagappan
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-discuss+unsub...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages