MouseLockLost Event

Since we began hacking firefox, I was curious to find out how the events were handled internally.
I saw the mouselocklost event as an opportunity to hack around the event chain in firefox and see how all the differents events worked.
First I started tracking the hierarchy of the nsDOMMouseEvent, that led me to nsDOMUIEvent and nsDOMevent. On the nsDOMEvent.h file, there was an enum with the name of all firefox events. Next I looked at the nsDOMEvent.cpp, I saw that there was an array, again, with the names of all firefox events, still in the nsDOMEvent.cpp there was a method called GetEventName that used a switch statement to find which event was fired in the browser and return its name.

   
 switch(aEventType) {  
 1118 case NS_MOUSE_BUTTON_DOWN:  
 1119 return sEventNames[eDOMEvents_mousedown];  
 1120 case NS_MOUSE_BUTTON_UP:  
 1121 return sEventNames[eDOMEvents_mouseup];  
 …….  
 ………  
 …………..  

and the list just kept getting bigger and bigger, I think in total, there were 134 different events.
An interesting point:

  • For some reason, every time I clicked on the browser, the NS_MOUSE_BUTTON_UP event got fired, but the NS_MOUSE_BUTTON_DOWN, and NS_MOUSE_CLICK didn’t.

So my next move was to search on mxr for the macros name to see where they were declared.
All the macros were declared in the nsGUIEvent.h file.
I wasn’t sure where to declare, and which value to give to the NS_MOUSELOCKLOST macro, so I just placed together with all the other mouse event macros and incremented by one the value of the last mousemacro:

  
 #define NS_MOUSE_MESSAGE_START 300  
 #define NS_MOUSE_MOVE (NS_MOUSE_MESSAGE_START)  
 #define NS_MOUSE_BUTTON_UP (NS_MOUSE_MESSAGE_START + 1)  
 #define NS_MOUSE_BUTTON_DOWN (NS_MOUSE_MESSAGE_START + 2)  
 #define NS_MOUSE_ENTER (NS_MOUSE_MESSAGE_START + 22)  
 #define NS_MOUSE_EXIT (NS_MOUSE_MESSAGE_START + 23)  
 #define NS_MOUSE_DOUBLECLICK (NS_MOUSE_MESSAGE_START + 24)  
 #define NS_MOUSE_CLICK (NS_MOUSE_MESSAGE_START + 27)  
 #define NS_MOUSE_ACTIVATE (NS_MOUSE_MESSAGE_START + 30)  
 #define NS_MOUSE_ENTER_SYNTH (NS_MOUSE_MESSAGE_START + 31)  
 #define NS_MOUSE_EXIT_SYNTH (NS_MOUSE_MESSAGE_START + 32)  
 #define NS_MOUSE_MOZHITTEST (NS_MOUSE_MESSAGE_START + 33)  
 #define NS_MOUSEENTER (NS_MOUSE_MESSAGE_START + 34)  
 #define NS_MOUSELEAVE (NS_MOUSE_MESSAGE_START + 35)  
 #define NS_MOUSELOCKLOST (NS_MOUSE_MESSAGE_START + 36)  

After declaring the mouselocklost macro, I kept searching on mxr for any other occurrences of the event macros in the source code, I found that they were also used in the nsEventNameList.h. I wasn’t sure which event name type I should use, so I added EventNameType_All, since it was used by most other mouse events.

   
 EVENT(mouseup,  
 NS_MOUSE_BUTTON_UP,  
 EventNameType_All,  
 NS_MOUSE_EVENT)  
 EVENT(mozfullscreenchange,  
 NS_FULLSCREENCHANGE,  
 EventNameType_HTML,  
 NS_EVENT_NULL)  
 EVENT(mozfullscreenerror,  
 NS_FULLSCREENERROR,  
 EventNameType_HTML,  
 NS_EVENT_NULL)  
 EVENT(mouselocklost,  
 NS_MOUSELOCKLOST,  
 EventNameType_All,  
 NS_EVENT_NULL)  

I then decided it was time to build to see if the mouselocklost event was being registered. However, I got some compile errors:

In file included from /home/diogogmt/mozilla-central/dom/base/nsGlobalWindow.cpp:10733:
../../dist/include/nsEventNameList.h:278: error: no ‘nsresult nsGlobalWindow::GetOnmouselocklost(JSContext, jsval)’ member function declared in class ‘nsGlobalWindow’
In file included from /home/diogogmt/mozilla-central/dom/base/nsGlobalWindow.cpp:10733:
../../dist/include/nsEventNameList.h:278: error: no ‘nsresult nsGlobalWindow::SetOnmouselocklost(JSContext*, const jsval&)’ member function declared in class ‘nsGlobalWindow’

Those errors were familiar, they meant that the getter and setter for the event didn’t exist, and I remembered from the GetScreenX and GetScreenY example that the Get and Set were added just for the c++ code, and that in javascript would be the just the method name, without Get and Set. I thought about adding those methods in the nsGlobalWindow cpp, but I looked at the file and didn’t find any getter/setter for the other events, so I knew I was missing something.
I went back searching on mxr, but this time without success. My next move was go  to IRC. I followed David Humphrey suggestion and asked first on the #seneca channel, then I went to the #introduction channel, and there they told me it would be best if I asked the question on the #developers channel. That’s what I did, and in less than 5 min I got an answer, I’m amazed about the speed and quality of the answers on IRC, I think that’s one of the reasons for the huge success of Mozilla, having a very strong community of developers.

So the answer I got on the channel, was that I was missing adding the mouselocklost event to two files, nsGkAtomList.h and nsIInlineEventHandlers.idl

They also recommended that I look at this patch.

I made the necessary changes on the code, and this time it worked :)
I’ve commited the changes to here and here

I’m not even sure that if that is how the mouselocklost event should be implemented, but I remembered the quote from today’s class:

The perfect is the enemy of the good

and instead of trying to write the perfect line of code, I just kept hammering around lots of files, and in the end, even though it was not a final solution, is was start.

What’s my next plan?

  • Find how to dispatch an event
  • Callback functions