Changing Mouse screenX and screenY values on Firefox

After browsing through the Firefox code, I found the dir where the MouseEvent is implemented.
What helped me find the dir was the gamepadAPI patch for Firefox. After Raymond(rhung) told me that Jon(jbuck)  had uploaded the gamepad patch to github, I’ve forked his repo and started looking at the code.
The whole patch had changes in 33 different files. Out of those 33, 14 were newly created files
From the 14 new files

  • 8 were in the content/events/src
  • 4 were in the dom/interfaces/events/
  • 2 were in the dom/system

I listed all the files in the content/events/src dir an saw the implementation for several browser events, such as mouse, scroll, keyboard, touch, etc.

Looking at the file for the mouse event (nsDOMMouseEvent.cpp) I saw a lot of familiar keywords

  • GetScreenX
  • GetScreenY
  • GetClientX
  • GetClientY
  • GetCtrlKey
  • GetShiftKey
  • GetMetaKey

As you can see the MouseEvent object has some properties with the same name as the methods in the nsDOMMouseEvent.cpp

I added some printf’s to the code and changed the value of screenX and screenY to -1


 223 NS_METHOD nsDOMMouseEvent::GetScreenX(PRInt32* aScreenX)  
 224 {  
 226 *aScreenX = -1; //GetScreenPoint().x;  
 227 printf("nnGetScreenXnscreenX: %d", GetScreenPoint().x);  
 228 return NS_OK;  
 229 }  
 232 nsDOMMouseEvent::GetScreenY(PRInt32* aScreenY)  
 233 {  
 235 printf("nnGetScreenYnscreenY: %d", GetScreenPoint().y);  
 236 *aScreenY = -1; //GetScreenPoint().y;  
 237 return NS_OK;  
 238 }

When I ran Firefox, on the terminal would print the correct values for screenX and screenY, but on the browser would always print -1/-1.

A few interesting points:

  • The GetScreenX and GetScreenY are not at the bottom of the stack, since they get the coords from GetScreenPosition(). Next step is to find where GetScreenPosition() is located, and if GetScreenPosition() is at the bottom of the stack
  • The return type for the GetScreenX is NS_METHOD and for the GetScreenY is NS_IMETHODIMP, even though they both return NS_OK
  • Every time the mouse moves, the browser invokes the GetScreenX and GetScreenY methods.
  • The nsDOMMouseEvent.h doesn’t have the methods used in the nsDOMMouseEvent.cpp
  • The type of the mouse event(click,over,move,etc) is just an attribute of a MouseEvent object and not an object itself

One question is: How the browser knows when the mouse is over an element? Lets say a div. How does it know when to fire the mouseover event? Does it stores the x,y coords of that element, and when the mouse x,y cords are in the range of the x,y coords of the element the event is fired? What if the screen is resized?

What’s next?
Reading the W3C Mouse Lock specs, one of the sections I found interesting was 10.6

10.6 Why modify MouseEvent and reuse existing mouse events instead of creating a mouse delta event?

When under mouse lock many mouse events remain relevant, e.g. click, mousedown, etc. These all share the same event data structure MouseEvent. If movement data were reported via a new data structure then a new event would be needed for reporting delta movement. The new data structure would have many parallels to MouseEvent to offer the same conveniences, e.g. button and modifier key states. When handling click, down, and up events would the existing mousedown, mouseup be used? If so, they would provide .clientX/Y and .screenX/Y with no useful data, but would lack the convenience of containing the current movement data. Or, new events would also be required for when the mouse is locked.

Also, movementX/Y are convenient even when the mouse is not locked. This spec requires movement members to always be valid, even when the mouse cursor exists. This reduces code required to track the last cursor state and mouseover/mouseout transitions if applications wish to make use of delta motion of the mouse.

The only negative of adding movementX/Y to MouseEvent appears to be the unused values in clientX/Y and screenX/Y when under mouse lock. This does not seem to be a significant problem.

Therefore the minimal change to add movementX/Y to MouseEvent is selected to reduce API and implementation complexity.

If I understood correctly, to implement the Mouse Lock, two new attributes must be added to the Mouse Event object, movementX/Y.
So I guess all the work will be adding functionality to the MouseEvent and making sure it handles the lock properly.
I’ll keep reading the specs since I don’t fully understand how the lock will work, but it looks like that a good understanding of MouseEvent will be fundamental in the implementation of Mouse Lock.