Just before the mouselock patch was submitted to review, some new changes landed on the mozFullScreen implementation, and that affected some of the mouselock behaviour, since a great part of its functionality relies on the fullscreen code. However, David Humphrey was able to make the necessary changes to adapt the new fullScreen implementation to handle mouselock, and the patch was successfully submited.

After the patch was submitted, I was curious to see what were the changes to the fullscreen implementation, plus we needed some new mochitests to test this new patch, so I went to mxr and started inspecting some code.

From what I understood, the functionality added to fullscreen was to cascade fullscreen between nested elements, for example:

[sourcecode language=”html”]




[/sourcecode]

So if parent gets fullscreen, and then child gets fullscreen, parent would still be in fullscreen mode, and if child loses fullscreen, parent would regain it.

The Problem

What happened was that if the parent element had the mouse locked, and the child received fullscreen, the mozfullscreenchange event was never dispatched, since the parent didn’t actually lose fullscreen, so it would still have the mouse locked to it, even though the child would be in fullscreen mode.

Solution

When nsDocument::RequestFullScreen is called, it checks if there is already an element in fullscreen mode, if it does, it unlocks the mouse before setting the new element to fullscreen.
code

Bellow, I created a simple class diagram with some of the classes/methods that handle fullscreen requests.

Here are some printf’s that helped me understand the flow of the fullscreen.
The first two stacks are from a parent and a child element receiving fullscreen
The last two are from exiting fullscreen by calling document.mozCancelFullScreen and pressing ESC

Fullscreen Parent Element

nsDocument::AsyncRequest
nsCallRequestFullScreen::nsCallRequestFullScreen
nsCallRequestFullScreen::Run
nsDocument::RequestFullScreen
sFullScreenDoc? FALSE
nsDocument::FullScreenStackPush
calling nsEventStateManager::SetFullScreenState(aElement, true)
returning from nsDocument::FullScreenStackPush
while ((parent = child->GetParentDocument()))
nsDocument::FullScreenStackPush
calling nsEventStateManager::SetFullScreenState(aElement, true)
returning from nsDocument::FullScreenStackPush
if (static_cast(parent)->FullScreenStackPush(element))
static DispatchFullScreenChange
static DispatchFullScreenChange
static SetWIndowFullScreen
nsSetWindowFullScreen::nsSetWindowFullScreen
nsSetWindowFullScreen::Run
nsGlobalWindow::SetFullScreen
setting fullscreen to: TRUE
nsGlobalWindow::SetFullScreen
setting fullscreen to: TRUE

Fullscreen Child Element

nsDocument::AsyncRequest
nsCallRequestFullScreen::nsCallRequestFullScreen
nsCallRequestFullScreen::Run
nsDocument::RequestFullScreen
sFullScreenDoc? TRUE
nsDocument::FullScreenStackPush
top exists, calling nsEventStateManager::SetFullScreenState(top, false)
calling nsEventStateManager::SetFullScreenState(aElement, true)
returning from nsDocument::FullScreenStackPush
static DispatchFullScreenChange
static SetWindowFullScreen
nsSetWindowFullScreen::nsSetWindowFullScreen
nsSetWindowFullScreen::Run
nsGlobalWindow::SetFullScreen
setting fullscreen to: TRUE
nsGlobalWindow::SetFullScreen
setting fullscreen to: TRUE

Exit FullScreen By Calling document.mozCancelFullScreen()

nsDocument::MozCancelFullScreen
nsDocument::RestorePreviousFullScreenState
nsDocument::MaybeUnlockMouse
nsDOMMouseLockable::Unlock
static DispatchFullScreenChange
nsDocument::MaybeUnlockMouse
nsDOMMouseLockable::Unlock
static DispatchFullScreenChange
static SetWindowFullScreen
nsSetWindowFullScreen::nsSetWindowFullScreen
nsSetWindowFullScreen::Run
nsGlobalWindow::SetFullScreen
setting fullscreen to: FALSE
nsGlobalWindow::SetFullScreen
setting fullscreen to: FALSE
nsIDocument::ExitFullScreen
nsDocument::ExitFullScreen

Exit FullScreen By Pressing ESC

nsIDocument::ExitFullScreen
nsCallExitFullScreen::Run
nsDocument::ExitFullScreen
nsDocument::MaybeUnlockMouse
nsDOMMouseLockable::Unlock
static ResetFullScreen
nsDocument::ClearFullScreenStack
static ResetFullScreen
static ResetFullScreen
nsDocument::ClearFullScreenStack
static ResetFullScreen
static ResetFullScreen
static ResetFullScreen
static DispatchFullScreenChange
static DispatchFullScreenChange
static static SetWindowFullScreen
nsSetWIndowFullScreen::nsSetWindowFullScreen
nsSetWindowFullScreen::Run
nsGlobalWindow::SetFullScreen
setting fullscreen to: FALSE
nsIDocument::ExitFullScreen
nsDocument::ExitFullScreen