Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1271)

Unified Diff: third_party/WebKit/Source/web/FullscreenController.cpp

Issue 2550703002: Move pending state from FullscreenController to Fullscreen (Closed)
Patch Set: tests and documentation Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/web/FullscreenController.cpp
diff --git a/third_party/WebKit/Source/web/FullscreenController.cpp b/third_party/WebKit/Source/web/FullscreenController.cpp
index 63c52024dcb6051ff2078f3daaf0e7ee7a2d0b7b..c139da43cda4d5410e0653d25ccd86930ec70feb 100644
--- a/third_party/WebKit/Source/web/FullscreenController.cpp
+++ b/third_party/WebKit/Source/web/FullscreenController.cpp
@@ -37,132 +37,145 @@
#include "core/frame/PageScaleConstraintsSet.h"
#include "core/html/HTMLVideoElement.h"
#include "core/layout/LayoutFullScreen.h"
-#include "platform/RuntimeEnabledFeatures.h"
#include "public/platform/WebLayerTreeView.h"
#include "public/web/WebFrameClient.h"
#include "web/WebLocalFrameImpl.h"
-#include "web/WebSettingsImpl.h"
#include "web/WebViewImpl.h"
namespace blink {
-FullscreenController* FullscreenController::create(WebViewImpl* webViewImpl) {
- return new FullscreenController(webViewImpl);
+namespace {
+
+WebFrameClient& webFrameClient(LocalFrame& frame) {
+ WebLocalFrameImpl* webFrame = WebLocalFrameImpl::fromFrame(frame);
+ DCHECK(webFrame);
+ DCHECK(webFrame->client());
+ return *webFrame->client();
}
-FullscreenController::FullscreenController(WebViewImpl* webViewImpl)
- : m_webViewImpl(webViewImpl),
- m_haveEnteredFullscreen(false),
- m_exitFullscreenPageScaleFactor(0),
- m_needsScrollAndScaleRestore(false),
- m_isCancelingFullscreen(false) {}
+} // anonymous namespace
-void FullscreenController::didEnterFullscreen() {
- if (!m_provisionalFullscreenElement)
- return;
+std::unique_ptr<FullscreenController> FullscreenController::create(
+ WebViewImpl* webViewImpl) {
+ return wrapUnique(new FullscreenController(webViewImpl));
+}
- Element* element = m_provisionalFullscreenElement.release();
- Document& document = element->document();
- m_fullscreenFrame = document.frame();
+FullscreenController::FullscreenController(WebViewImpl* webViewImpl)
+ : m_webViewImpl(webViewImpl) {}
- if (!m_fullscreenFrame)
+void FullscreenController::didEnterFullscreen() {
+ // |Browser::EnterFullscreenModeForTab()| can enter fullscreen without going
+ // through |Fullscreen::requestFullscreen()|, in which case there will be no
+ // fullscreen element. Do nothing.
+ if (m_state != State::EnteringFullscreen)
return;
- if (!m_haveEnteredFullscreen) {
- updatePageScaleConstraints(false);
- m_webViewImpl->setPageScaleFactor(1.0f);
- if (m_webViewImpl->mainFrame()->isWebLocalFrame())
- m_webViewImpl->mainFrame()->setScrollOffset(WebSize());
- m_webViewImpl->setVisualViewportOffset(FloatPoint());
- m_haveEnteredFullscreen = true;
+ updatePageScaleConstraints(false);
+ m_webViewImpl->setPageScaleFactor(1.0f);
+ if (m_webViewImpl->mainFrame()->isWebLocalFrame())
+ m_webViewImpl->mainFrame()->setScrollOffset(WebSize());
+ m_webViewImpl->setVisualViewportOffset(FloatPoint());
+
+ m_state = State::Fullscreen;
+
+ // Notify all local frames that we have entered fullscreen.
+ for (Frame* frame = m_webViewImpl->page()->mainFrame(); frame;
+ frame = frame->tree().traverseNext()) {
+ if (!frame->isLocalFrame())
+ continue;
+ if (Document* document = toLocalFrame(frame)->document()) {
+ if (Fullscreen* fullscreen = Fullscreen::fromIfExists(*document))
+ fullscreen->didEnterFullscreen();
+ }
}
-
- Fullscreen::from(document).didEnterFullscreenForElement(element);
- DCHECK_EQ(Fullscreen::currentFullScreenElementFrom(document), element);
}
void FullscreenController::didExitFullscreen() {
- if (!m_fullscreenFrame)
+ // The browser process can exit fullscreen at any time, e.g. if the user
+ // presses Esc. After |Browser::EnterFullscreenModeForTab()|,
+ // |Browser::ExitFullscreenModeForTab()| will make it seem like we exit when
+ // not even in fullscreen. Do nothing.
+ if (m_state == State::Initial)
return;
- if (m_haveEnteredFullscreen)
- updatePageScaleConstraints(true);
-
- if (Document* document = m_fullscreenFrame->document()) {
- if (Fullscreen* fullscreen = Fullscreen::fromIfExists(*document)) {
- Element* element = fullscreen->currentFullScreenElement();
- if (element) {
- // When the client exits from full screen we have to call
- // fullyExitFullscreen to notify the document. While doing that,
- // suppress notifications back to the client.
- m_isCancelingFullscreen = true;
- Fullscreen::fullyExitFullscreen(*document);
- m_isCancelingFullscreen = false;
-
- // We need to wait until style and layout are updated in order
- // to propertly restore scroll offsets since content may not be
- // overflowing in the same way until they do.
- if (m_haveEnteredFullscreen)
- m_needsScrollAndScaleRestore = true;
-
+ updatePageScaleConstraints(true);
+
+ // Set |m_state| so that any |exitFullscreen()| calls from within
+ // |Fullscreen::didExitFullscreen()| do not call
+ // |WebFrameClient::exitFullscreen()| again.
+ // TODO(foolip): Remove this when state changes and events are synchronized
+ // with animation frames. https://crbug.com/402376
+ m_state = State::ExitingFullscreen;
+
+ // Notify all local frames that we have exited fullscreen.
+ // TODO(foolip): This should only need to notify the topmost local roots. That
+ // doesn't currently work because |Fullscreen::m_currentFullScreenElement|
+ // isn't set for the topmost document when an iframe goes fullscreen, but can
+ // be done once |m_currentFullScreenElement| is gone and all state is in the
+ // fullscreen element stack. https://crbug.com/402421
+ for (Frame* frame = m_webViewImpl->page()->mainFrame(); frame;
+ frame = frame->tree().traverseNext()) {
+ if (!frame->isLocalFrame())
+ continue;
+ if (Document* document = toLocalFrame(frame)->document()) {
+ if (Fullscreen* fullscreen = Fullscreen::fromIfExists(*document))
fullscreen->didExitFullscreen();
- }
}
}
- m_haveEnteredFullscreen = false;
- m_fullscreenFrame.clear();
+ // We need to wait until style and layout are updated in order to properly
+ // restore scroll offsets since content may not be overflowing in the same way
+ // until they are.
+ m_state = State::NeedsScrollAndScaleRestore;
}
-void FullscreenController::enterFullscreenForElement(Element* element) {
- // We are already transitioning to fullscreen for a different element.
- if (m_provisionalFullscreenElement) {
- m_provisionalFullscreenElement = element;
- return;
- }
-
- // We are already in fullscreen mode.
- if (m_fullscreenFrame) {
- m_provisionalFullscreenElement = element;
+void FullscreenController::enterFullscreen(LocalFrame& frame) {
+ // If already fullscreen or exiting fullscreen, synchronously call
+ // |didEnterFullscreen()|. When exiting, the coming |didExitFullscren()| call
+ // will again notify all frames.
+ if (m_state == State::Fullscreen || m_state == State::ExitingFullscreen) {
+ State oldState = m_state;
+ m_state = State::EnteringFullscreen;
didEnterFullscreen();
+ m_state = oldState;
return;
}
- // We need to store these values here rather than didEnterFullscreen since
- // by the time the latter is called, a Resize has already occured, clamping
- // the scroll offset. Don't save values if we're still waiting to restore
- // a previous set. This can happen if we exit and quickly reenter fullscreen
- // without performing a layout.
- if (!m_haveEnteredFullscreen && !m_needsScrollAndScaleRestore) {
- m_exitFullscreenPageScaleFactor = m_webViewImpl->pageScaleFactor();
- m_exitFullscreenScrollOffset =
- m_webViewImpl->mainFrame()->isWebLocalFrame()
- ? m_webViewImpl->mainFrame()->getScrollOffset()
- : WebSize();
- m_exitFullscreenVisualViewportOffset =
- m_webViewImpl->visualViewportOffset();
+ // We need to store these values here rather than in |didEnterFullscreen()|
+ // since by the time the latter is called, a Resize has already occured,
+ // clamping the scroll offset. Don't save values if we're still waiting to
+ // restore a previous set. This can happen if we exit and quickly reenter
+ // fullscreen without performing a layout.
+ if (m_state == State::Initial) {
+ m_initialPageScaleFactor = m_webViewImpl->pageScaleFactor();
+ m_initialScrollOffset = m_webViewImpl->mainFrame()->isWebLocalFrame()
+ ? m_webViewImpl->mainFrame()->getScrollOffset()
+ : WebSize();
+ m_initialVisualViewportOffset = m_webViewImpl->visualViewportOffset();
}
- // We need to transition to fullscreen mode.
- WebLocalFrameImpl* frame =
- WebLocalFrameImpl::fromFrame(element->document().frame());
- if (frame && frame->client()) {
- if (!Fullscreen::from(element->document()).forCrossProcessDescendant())
- frame->client()->enterFullscreen();
- m_provisionalFullscreenElement = element;
- }
-}
+ // If already entering fullscreen, just wait.
+ if (m_state == State::EnteringFullscreen)
+ return;
+
+ DCHECK(m_state == State::Initial ||
+ m_state == State::NeedsScrollAndScaleRestore);
+ webFrameClient(frame).enterFullscreen();
-void FullscreenController::exitFullscreen(LocalFrame* frame) {
- DCHECK(frame);
+ m_state = State::EnteringFullscreen;
+}
- // The client is exiting full screen, so don't send a notification.
- if (m_isCancelingFullscreen)
+void FullscreenController::exitFullscreen(LocalFrame& frame) {
+ // If not in fullscreen, ignore any attempt to exit. In particular, when
+ // entering fullscreen, allow the transition into fullscreen to complete. Note
+ // that the browser process is ultimately in control and can still exit
+ // fullscreen at any time.
+ if (m_state != State::Fullscreen)
return;
- WebLocalFrameImpl* webFrame = WebLocalFrameImpl::fromFrame(frame);
- if (webFrame && webFrame->client())
- webFrame->client()->exitFullscreen();
+ webFrameClient(frame).exitFullscreen();
+
+ m_state = State::ExitingFullscreen;
}
void FullscreenController::fullscreenElementChanged(Element* fromElement,
@@ -202,32 +215,38 @@ void FullscreenController::fullscreenElementChanged(Element* fromElement,
}
void FullscreenController::updateSize() {
- if (!isFullscreen())
+ DCHECK(m_webViewImpl->page());
+
+ if (m_state != State::Fullscreen)
return;
updatePageScaleConstraints(false);
- LayoutFullScreen* layoutObject =
- Fullscreen::from(*m_fullscreenFrame->document()).fullScreenLayoutObject();
- if (layoutObject)
- layoutObject->updateStyle();
+ // Traverse all local frames and notify the LayoutFullScreen object, if any.
+ for (Frame* frame = m_webViewImpl->page()->mainFrame(); frame;
+ frame = frame->tree().traverseNext()) {
+ if (!frame->isLocalFrame())
+ continue;
+ if (Document* document = toLocalFrame(frame)->document()) {
+ if (Fullscreen* fullscreen = Fullscreen::fromIfExists(*document)) {
+ if (LayoutFullScreen* layoutObject =
+ fullscreen->fullScreenLayoutObject())
+ layoutObject->updateStyle();
+ }
+ }
+ }
}
void FullscreenController::didUpdateLayout() {
- if (!m_needsScrollAndScaleRestore)
- return;
-
- // If we re-entered fullscreen before we could restore the scroll and scale
- // don't try restoring them yet.
- if (isFullscreen())
+ if (m_state != State::NeedsScrollAndScaleRestore)
return;
- m_webViewImpl->setPageScaleFactor(m_exitFullscreenPageScaleFactor);
+ m_webViewImpl->setPageScaleFactor(m_initialPageScaleFactor);
if (m_webViewImpl->mainFrame()->isWebLocalFrame())
- m_webViewImpl->mainFrame()->setScrollOffset(
- WebSize(m_exitFullscreenScrollOffset));
- m_webViewImpl->setVisualViewportOffset(m_exitFullscreenVisualViewportOffset);
- m_needsScrollAndScaleRestore = false;
+ m_webViewImpl->mainFrame()->setScrollOffset(WebSize(m_initialScrollOffset));
+ m_webViewImpl->setVisualViewportOffset(m_initialVisualViewportOffset);
+
+ m_state = State::Initial;
}
void FullscreenController::updatePageScaleConstraints(bool removeConstraints) {
@@ -240,13 +259,12 @@ void FullscreenController::updatePageScaleConstraints(bool removeConstraints) {
fullscreenConstraints);
m_webViewImpl->pageScaleConstraintsSet().computeFinalConstraints();
- // Although we called computedFinalConstraints() above, the "final"
+ // Although we called |computedFinalConstraints()| above, the "final"
// constraints are not actually final. They are still subject to scale factor
- // clamping by contents size. Normally they should be dirtied due to
- // contents size mutation after layout, however the contents size is not
- // guaranteed to mutate, and the scale factor may remain unclamped. Just
- // fire the event again to ensure the final constraints pick up the latest
- // contents size.
+ // clamping by contents size. Normally they should be dirtied due to contents
+ // size mutation after layout, however the contents size is not guaranteed to
+ // mutate, and the scale factor may remain unclamped. Just fire the event
+ // again to ensure the final constraints pick up the latest contents size.
m_webViewImpl->didChangeContentsSize();
if (m_webViewImpl->mainFrameImpl() &&
m_webViewImpl->mainFrameImpl()->frameView())
@@ -255,9 +273,4 @@ void FullscreenController::updatePageScaleConstraints(bool removeConstraints) {
m_webViewImpl->updateMainFrameLayoutSize();
}
-DEFINE_TRACE(FullscreenController) {
- visitor->trace(m_provisionalFullscreenElement);
- visitor->trace(m_fullscreenFrame);
-}
-
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698