Bug 1036606 - Extend mozRequestFullScreen to accept an options dict with a vrDisplay member; r=bz

This commit is contained in:
Vladimir Vukicevic 2014-07-09 12:30:22 -07:00
parent 7a528c00ee
commit 0356575b13
9 changed files with 97 additions and 26 deletions

View File

@ -138,6 +138,7 @@
#include "mozilla/IntegerPrintfMacros.h"
#include "mozilla/dom/WindowBinding.h"
#include "mozilla/dom/ElementBinding.h"
#include "mozilla/dom/VRDevice.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -3073,7 +3074,7 @@ GetFullScreenError(nsIDocument* aDoc)
}
void
Element::MozRequestFullScreen()
Element::MozRequestFullScreen(const RequestFullscreenOptions& aOptions)
{
// Only grant full-screen requests if this is called from inside a trusted
// event handler (i.e. inside an event handler for a user initiated event).
@ -3097,7 +3098,12 @@ Element::MozRequestFullScreen()
return;
}
OwnerDoc()->AsyncRequestFullScreen(this);
FullScreenOptions opts;
if (aOptions.mVrDisplay) {
opts.mVRHMDDevice = aOptions.mVrDisplay->GetHMD();
}
OwnerDoc()->AsyncRequestFullScreen(this, opts);
return;
}

View File

@ -34,6 +34,7 @@
#include "mozilla/EventForwards.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/WindowBinding.h"
#include "mozilla/dom/ElementBinding.h"
#include "Units.h"
class nsIDOMEventListener;
@ -724,7 +725,7 @@ public:
nsIPresShell::SetCapturingContent(nullptr, 0);
}
}
void MozRequestFullScreen();
void MozRequestFullScreen(const RequestFullscreenOptions& aOptions);
void MozRequestPointerLock();
Attr* GetAttributeNode(const nsAString& aName);
already_AddRefed<Attr> SetAttributeNode(Attr& aNewAttr,
@ -1768,7 +1769,7 @@ NS_IMETHOD ReleaseCapture(void) MOZ_FINAL \
} \
NS_IMETHOD MozRequestFullScreen(void) MOZ_FINAL \
{ \
Element::MozRequestFullScreen(); \
Element::MozRequestFullScreen(mozilla::dom::RequestFullscreenOptions()); \
return NS_OK; \
} \
NS_IMETHOD MozRequestPointerLock(void) MOZ_FINAL \

View File

@ -10730,13 +10730,13 @@ nsIDocument::MozCancelFullScreen()
// Element::UnbindFromTree().
class nsSetWindowFullScreen : public nsRunnable {
public:
nsSetWindowFullScreen(nsIDocument* aDoc, bool aValue)
: mDoc(aDoc), mValue(aValue) {}
nsSetWindowFullScreen(nsIDocument* aDoc, bool aValue, gfx::VRHMDInfo* aHMD = nullptr)
: mDoc(aDoc), mValue(aValue), mHMD(aHMD) {}
NS_IMETHOD Run()
{
if (mDoc->GetWindow()) {
mDoc->GetWindow()->SetFullScreenInternal(mValue, false);
mDoc->GetWindow()->SetFullScreenInternal(mValue, false, mHMD);
}
return NS_OK;
}
@ -10744,6 +10744,7 @@ public:
private:
nsCOMPtr<nsIDocument> mDoc;
bool mValue;
nsRefPtr<gfx::VRHMDInfo> mHMD;
};
static nsIDocument*
@ -10763,7 +10764,7 @@ GetFullscreenRootDocument(nsIDocument* aDoc)
}
static void
SetWindowFullScreen(nsIDocument* aDoc, bool aValue)
SetWindowFullScreen(nsIDocument* aDoc, bool aValue, gfx::VRHMDInfo *aVRHMD = nullptr)
{
// Maintain list of fullscreen root documents.
nsCOMPtr<nsIDocument> root = GetFullscreenRootDocument(aDoc);
@ -10773,7 +10774,7 @@ SetWindowFullScreen(nsIDocument* aDoc, bool aValue)
FullscreenRoots::Remove(root);
}
if (!nsContentUtils::IsFullscreenApiContentOnly()) {
nsContentUtils::AddScriptRunner(new nsSetWindowFullScreen(aDoc, aValue));
nsContentUtils::AddScriptRunner(new nsSetWindowFullScreen(aDoc, aValue, aVRHMD));
}
}
@ -11093,12 +11094,13 @@ nsDocument::IsFullScreenDoc()
class nsCallRequestFullScreen : public nsRunnable
{
public:
explicit nsCallRequestFullScreen(Element* aElement)
explicit nsCallRequestFullScreen(Element* aElement, FullScreenOptions& aOptions)
: mElement(aElement),
mDoc(aElement->OwnerDoc()),
mWasCallerChrome(nsContentUtils::IsCallerChrome()),
mHadRequestPending(static_cast<nsDocument*>(mDoc.get())->
mAsyncFullscreenPending)
mAsyncFullscreenPending),
mOptions(aOptions)
{
static_cast<nsDocument*>(mDoc.get())->
mAsyncFullscreenPending = true;
@ -11110,6 +11112,7 @@ public:
mAsyncFullscreenPending = mHadRequestPending;
nsDocument* doc = static_cast<nsDocument*>(mDoc.get());
doc->RequestFullScreen(mElement,
mOptions,
mWasCallerChrome,
/* aNotifyOnOriginChange */ true);
return NS_OK;
@ -11119,10 +11122,12 @@ public:
nsCOMPtr<nsIDocument> mDoc;
bool mWasCallerChrome;
bool mHadRequestPending;
FullScreenOptions mOptions;
};
void
nsDocument::AsyncRequestFullScreen(Element* aElement)
nsDocument::AsyncRequestFullScreen(Element* aElement,
FullScreenOptions& aOptions)
{
NS_ASSERTION(aElement,
"Must pass non-null element to nsDocument::AsyncRequestFullScreen");
@ -11130,7 +11135,7 @@ nsDocument::AsyncRequestFullScreen(Element* aElement)
return;
}
// Request full-screen asynchronously.
nsCOMPtr<nsIRunnable> event(new nsCallRequestFullScreen(aElement));
nsCOMPtr<nsIRunnable> event(new nsCallRequestFullScreen(aElement, aOptions));
NS_DispatchToCurrentThread(event);
}
@ -11198,6 +11203,9 @@ nsDocument::CleanupFullscreenState()
Element* top = FullScreenStackTop();
NS_ASSERTION(top, "Should have a top when full-screen stack isn't empty");
if (top) {
// Remove any VR state properties
top->DeleteProperty(nsGkAtoms::vr_state);
EventStateManager::SetFullScreenState(top, false);
}
mFullScreenStack.Clear();
@ -11234,8 +11242,12 @@ nsDocument::FullScreenStackPop()
return;
}
// Remove styles from existing top element.
Element* top = FullScreenStackTop();
// Remove any VR state properties
top->DeleteProperty(nsGkAtoms::vr_state);
// Remove styles from existing top element.
EventStateManager::SetFullScreenState(top, false);
// Remove top element. Note the remaining top element in the stack
@ -11323,7 +11335,9 @@ nsresult nsDocument::RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement,
// If the frame element is already the fullscreen element in this document,
// this has no effect.
nsCOMPtr<nsIContent> content(do_QueryInterface(aFrameElement));
FullScreenOptions opts;
RequestFullScreen(content->AsElement(),
opts,
/* aWasCallerChrome */ false,
/* aNotifyOnOriginChange */ false);
@ -11349,8 +11363,17 @@ nsresult nsDocument::RemoteFrameFullscreenReverted()
return NS_OK;
}
static void
ReleaseHMDInfoRef(void *, nsIAtom*, void *aPropertyValue, void *)
{
if (aPropertyValue) {
static_cast<gfx::VRHMDInfo*>(aPropertyValue)->Release();
}
}
void
nsDocument::RequestFullScreen(Element* aElement,
FullScreenOptions& aOptions,
bool aWasCallerChrome,
bool aNotifyOnOriginChange)
{
@ -11439,6 +11462,14 @@ nsDocument::RequestFullScreen(Element* aElement,
UnlockPointer();
}
// Process options -- in this case, just HMD
if (aOptions.mVRHMDDevice) {
nsRefPtr<gfx::VRHMDInfo> hmdRef = aOptions.mVRHMDDevice;
aElement->SetProperty(nsGkAtoms::vr_state, hmdRef.forget().take(),
ReleaseHMDInfoRef,
true);
}
// Set the full-screen element. This sets the full-screen style on the
// element, and the full-screen-ancestor styles on ancestors of the element
// in this document.
@ -11543,7 +11574,7 @@ nsDocument::RequestFullScreen(Element* aElement,
// modes. Also note that nsGlobalWindow::SetFullScreen() (which
// SetWindowFullScreen() calls) proxies to the root window in its hierarchy,
// and does not operate on the a per-nsIDOMWindow basis.
SetWindowFullScreen(this, true);
SetWindowFullScreen(this, true, aOptions.mVRHMDDevice);
}
NS_IMETHODIMP

View File

@ -1146,7 +1146,8 @@ public:
virtual Element* FindImageMap(const nsAString& aNormalizedMapName) MOZ_OVERRIDE;
virtual Element* GetFullScreenElement() MOZ_OVERRIDE;
virtual void AsyncRequestFullScreen(Element* aElement) MOZ_OVERRIDE;
virtual void AsyncRequestFullScreen(Element* aElement,
mozilla::dom::FullScreenOptions& aOptions) MOZ_OVERRIDE;
virtual void RestorePreviousFullScreenState() MOZ_OVERRIDE;
virtual bool IsFullscreenLeaf() MOZ_OVERRIDE;
virtual bool IsFullScreenDoc() MOZ_OVERRIDE;
@ -1197,6 +1198,7 @@ public:
// need to send the notification with the origin of the document which
// originally requested fullscreen, not *this* document's origin.
void RequestFullScreen(Element* aElement,
mozilla::dom::FullScreenOptions& aOptions,
bool aWasCallerChrome,
bool aNotifyOnOriginChange);

View File

@ -5930,7 +5930,7 @@ nsGlobalWindow::SetFullScreen(bool aFullScreen)
}
nsresult
nsGlobalWindow::SetFullScreenInternal(bool aFullScreen, bool aRequireTrust)
nsGlobalWindow::SetFullScreenInternal(bool aFullScreen, bool aRequireTrust, gfx::VRHMDInfo* aHMD)
{
MOZ_ASSERT(IsOuterWindow());
@ -5952,7 +5952,7 @@ nsGlobalWindow::SetFullScreenInternal(bool aFullScreen, bool aRequireTrust)
if (!window)
return NS_ERROR_FAILURE;
if (rootItem != mDocShell)
return window->SetFullScreenInternal(aFullScreen, aRequireTrust);
return window->SetFullScreenInternal(aFullScreen, aRequireTrust, aHMD);
// make sure we don't try to set full screen on a non-chrome window,
// which might happen in embedding world
@ -5987,8 +5987,13 @@ nsGlobalWindow::SetFullScreenInternal(bool aFullScreen, bool aRequireTrust)
// want the content to fill the entire client area of the emulator window.
if (!Preferences::GetBool("full-screen-api.ignore-widgets", false)) {
nsCOMPtr<nsIWidget> widget = GetMainWidget();
if (widget)
widget->MakeFullScreen(aFullScreen);
if (widget) {
nsCOMPtr<nsIScreen> screen;
if (aHMD) {
screen = aHMD->GetScreen();
}
widget->MakeFullScreen(aFullScreen, screen);
}
}
if (!mFullScreen) {

View File

@ -468,7 +468,8 @@ public:
virtual void RefreshCompartmentPrincipal();
// Outer windows only.
virtual nsresult SetFullScreenInternal(bool aIsFullScreen, bool aRequireTrust);
virtual nsresult SetFullScreenInternal(bool aIsFullScreen, bool aRequireTrust,
mozilla::gfx::VRHMDInfo *aHMD = nullptr);
bool FullScreen() const;
// Inner windows only.

View File

@ -27,6 +27,7 @@
#include "nsExpirationTracker.h"
#include "nsClassHashtable.h"
#include "prclist.h"
#include "gfxVR.h"
class imgIRequest;
class nsAString;
@ -135,6 +136,12 @@ template<typename> class Sequence;
template<typename, typename> class CallbackObjectHolder;
typedef CallbackObjectHolder<NodeFilter, nsIDOMNodeFilter> NodeFilterHolder;
struct FullScreenOptions {
FullScreenOptions() { }
nsRefPtr<gfx::VRHMDInfo> mVRHMDDevice;
};
} // namespace dom
} // namespace mozilla
@ -164,6 +171,7 @@ already_AddRefed<nsContentList>
NS_GetContentList(nsINode* aRootNode,
int32_t aMatchNameSpaceId,
const nsAString& aTagname);
//----------------------------------------------------------------------
// Document interface. This is implemented by all document objects in
@ -1064,7 +1072,8 @@ public:
* the <iframe> or <browser> that contains this document is also mode
* fullscreen. This happens recursively in all ancestor documents.
*/
virtual void AsyncRequestFullScreen(Element* aElement) = 0;
virtual void AsyncRequestFullScreen(Element* aElement,
mozilla::dom::FullScreenOptions& aOptions) = 0;
/**
* Called when a frame in a child process has entered fullscreen or when a

View File

@ -38,6 +38,9 @@ namespace dom {
class AudioContext;
class Element;
}
namespace gfx {
class VRHMDInfo;
}
}
// Popup control state enum. The values in this enum must go from most
@ -60,8 +63,8 @@ enum UIStateChangeType
};
#define NS_PIDOMWINDOW_IID \
{ 0x71412748, 0x6368, 0x4332, \
{ 0x82, 0x66, 0xff, 0xaa, 0x19, 0xda, 0x09, 0x7c } }
{ 0x19fb3019, 0x7b5d, 0x4235, \
{ 0xa9, 0x59, 0xa2, 0x31, 0xa2, 0xe7, 0x94, 0x79 } }
class nsPIDOMWindow : public nsIDOMWindowInternal
{
@ -460,9 +463,13 @@ public:
* otherwise exits fullscreen. If aRequireTrust is true, this method only
* changes window state in a context trusted for write.
*
* If aHMD is not null, the window is made full screen on the given VR HMD
* device instead of its currrent display.
*
* Outer windows only.
*/
virtual nsresult SetFullScreenInternal(bool aIsFullScreen, bool aRequireTrust) = 0;
virtual nsresult SetFullScreenInternal(bool aIsFullScreen, bool aRequireTrust,
mozilla::gfx::VRHMDInfo *aHMD = nullptr) = 0;
/**
* Call this to check whether some node (this window, its document,

View File

@ -124,9 +124,11 @@ interface Element : Node {
* Requests that this element be made the full-screen element, as per the DOM
* full-screen api.
*
* The fsOptions parameter is non-standard.
*
* @see <https://wiki.mozilla.org/index.php?title=Gecko:FullScreenAPI>
*/
void mozRequestFullScreen();
void mozRequestFullScreen(optional RequestFullscreenOptions fsOptions);
/**
* Requests that this element be made the pointer-locked element, as per the DOM
@ -235,3 +237,10 @@ Element implements NonDocumentTypeChildNode;
Element implements ParentNode;
Element implements Animatable;
Element implements GeometryUtils;
// non-standard: allows passing options to Element.requestFullScreen
dictionary RequestFullscreenOptions {
// Which HMDVRDevice to go full screen on; also enables VR rendering.
// If null, normal fullscreen is entered.
HMDVRDevice? vrDisplay = null;
};