https://bugs.webkit.org/show_bug.cgi?id=141439
Patch by Jeremy Jones <jeremyj@apple.com> on 2015-03-06
Reviewed by Simon Fraser.
Source/WebCore:
This patch will scroll the element so it is visible when exiting fullscreen,
but only if the element is completely scrolled off screen.
Also update the element screen rect so exit animation goes to the correct location.
* dom/Element.cpp:
(WebCore::Element::scrollIntoViewIfNotVisible): Added.
* dom/Element.h: Add declaration for scrollIntoViewIfNotVisible.
* platform/ios/WebVideoFullscreenControllerAVKit.mm:
(-[WebVideoFullscreenController fullscreenMayReturnToInline]):
* platform/ios/WebVideoFullscreenInterfaceAVKit.h:
* platform/ios/WebVideoFullscreenInterfaceAVKit.mm:
(-[WebAVPlayerController playerViewController:restoreUserInterfaceForOptimizedFullscreenStopWithCompletionHandler:]):
(-[WebAVPlayerController playerViewControllerWillCancelOptimizedFullscree:]):
(WebVideoFullscreenInterfaceAVKit::setupFullscreen):
(WebVideoFullscreenInterfaceAVKit::setupFullscreenInternal):
(WebVideoFullscreenInterfaceAVKit::exitFullscreen):
(WebVideoFullscreenInterfaceAVKit::exitFullscreenInternal):
(WebVideoFullscreenInterfaceAVKit::preparedToReturnToInline):
(WebVideoFullscreenInterfaceAVKit::fullscreenMayReturnToInline):
* rendering/ScrollBehavior.cpp:
* rendering/ScrollBehavior.h:
Source/WebKit2:
This patch will restore interface state when exiting fullscreen.
Adds preparedToReturnToInline to continue exiting once the interface is updated.
* UIProcess/ios/WebVideoFullscreenManagerProxy.h:
* UIProcess/ios/WebVideoFullscreenManagerProxy.messages.in:
* UIProcess/ios/WebVideoFullscreenManagerProxy.mm:
(WebKit::WebVideoFullscreenManagerProxy::setupFullscreenWithID):
(WebKit::WebVideoFullscreenManagerProxy::fullscreenMayReturnToInline):
(WebKit::WebVideoFullscreenManagerProxy::preparedToReturnToInline): added.
* WebProcess/ios/WebVideoFullscreenManager.h:
* WebProcess/ios/WebVideoFullscreenManager.messages.in:
* WebProcess/ios/WebVideoFullscreenManager.mm:
(WebKit::WebVideoFullscreenManager::fullscreenMayReturnToInline):
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@181173
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2015-03-06 Jeremy Jones <jeremyj@apple.com>
+
+ Scroll to make the video element visible when exiting fullscreen.
+ https://bugs.webkit.org/show_bug.cgi?id=141439
+
+ Reviewed by Simon Fraser.
+
+ This patch will scroll the element so it is visible when exiting fullscreen,
+ but only if the element is completely scrolled off screen.
+ Also update the element screen rect so exit animation goes to the correct location.
+
+ * dom/Element.cpp:
+ (WebCore::Element::scrollIntoViewIfNotVisible): Added.
+ * dom/Element.h: Add declaration for scrollIntoViewIfNotVisible.
+ * platform/ios/WebVideoFullscreenControllerAVKit.mm:
+ (-[WebVideoFullscreenController fullscreenMayReturnToInline]):
+ * platform/ios/WebVideoFullscreenInterfaceAVKit.h:
+ * platform/ios/WebVideoFullscreenInterfaceAVKit.mm:
+ (-[WebAVPlayerController playerViewController:restoreUserInterfaceForOptimizedFullscreenStopWithCompletionHandler:]):
+ (-[WebAVPlayerController playerViewControllerWillCancelOptimizedFullscree:]):
+ (WebVideoFullscreenInterfaceAVKit::setupFullscreen):
+ (WebVideoFullscreenInterfaceAVKit::setupFullscreenInternal):
+ (WebVideoFullscreenInterfaceAVKit::exitFullscreen):
+ (WebVideoFullscreenInterfaceAVKit::exitFullscreenInternal):
+ (WebVideoFullscreenInterfaceAVKit::preparedToReturnToInline):
+ (WebVideoFullscreenInterfaceAVKit::fullscreenMayReturnToInline):
+ * rendering/ScrollBehavior.cpp:
+ * rendering/ScrollBehavior.h:
+
2015-03-06 Myles C. Maxfield <mmaxfield@apple.com>
Crash in -[WebCascadeList objectAtIndex:] + 195
renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
}
+void Element::scrollIntoViewIfNotVisible(bool centerIfNotVisible)
+{
+ document().updateLayoutIgnorePendingStylesheets();
+
+ if (!renderer())
+ return;
+
+ LayoutRect bounds = renderer()->anchorRect();
+ if (centerIfNotVisible)
+ renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignCenterIfNotVisible, ScrollAlignment::alignCenterIfNotVisible);
+ else
+ renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNotVisible, ScrollAlignment::alignToEdgeIfNotVisible);
+}
+
void Element::scrollByUnits(int units, ScrollGranularity granularity)
{
document().updateLayoutIgnorePendingStylesheets();
void scrollIntoView(bool alignToTop = true);
void scrollIntoViewIfNeeded(bool centerIfNeeded = true);
+ WEBCORE_EXPORT void scrollIntoViewIfNotVisible(bool centerIfNotVisible = true);
void scrollByLines(int lines);
void scrollByPages(int pages);
- (void)fullscreenMayReturnToInline
{
+ _interface->preparedToReturnToInline(true, _videoElement->clientRect());
}
@end
WEBCORE_EXPORT virtual void setLegibleMediaSelectionOptions(const Vector<WTF::String>& options, uint64_t selectedIndex) override;
WEBCORE_EXPORT virtual void setExternalPlayback(bool enabled, ExternalPlaybackTargetType, WTF::String localizedDeviceName) override;
- WEBCORE_EXPORT virtual void setupFullscreen(PlatformLayer&, IntRect initialRect, UIView *, HTMLMediaElement::VideoFullscreenMode, bool allowOptimizedFullscreen);
+ WEBCORE_EXPORT virtual void setupFullscreen(PlatformLayer&, const IntRect& initialRect, UIView *, HTMLMediaElement::VideoFullscreenMode, bool allowOptimizedFullscreen);
WEBCORE_EXPORT virtual void enterFullscreen();
- WEBCORE_EXPORT virtual void exitFullscreen(IntRect finalRect);
+ WEBCORE_EXPORT virtual void exitFullscreen(const IntRect& finalRect);
WEBCORE_EXPORT virtual void cleanupFullscreen();
WEBCORE_EXPORT virtual void invalidate();
WEBCORE_EXPORT virtual void requestHideAndExitFullscreen();
+ WEBCORE_EXPORT virtual void preparedToReturnToInline(bool visible, const IntRect& inlineRect);
HTMLMediaElement::VideoFullscreenMode mode() const { return m_mode; }
void setIsOptimized(bool);
WEBCORE_EXPORT bool mayAutomaticallyShowVideoOptimized();
- bool fullscreenMayReturnToInline();
+ void fullscreenMayReturnToInline();
protected:
void beginSession();
- void setupFullscreenInternal(PlatformLayer&, IntRect initialRect, UIView *, HTMLMediaElement::VideoFullscreenMode, bool allowOptimizedFullscreen);
+ void setupFullscreenInternal(PlatformLayer&, const IntRect& initialRect, UIView *, HTMLMediaElement::VideoFullscreenMode, bool allowOptimizedFullscreen);
void enterFullscreenOptimized();
void enterFullscreenStandard();
- void exitFullscreenInternal(IntRect finalRect);
+ void exitFullscreenInternal(const IntRect& finalRect);
void cleanupFullscreenInternal();
RetainPtr<WebAVPlayerController> m_playerController;
@property AVPlayerControllerExternalPlaybackType externalPlaybackType;
@property (retain) NSString *externalPlaybackAirPlayDeviceLocalizedName;
+@property (copy) void (^exitOptimizedCallback)(BOOL restored);
+
- (BOOL)playerViewController:(AVPlayerViewController *)playerViewController shouldExitFullScreenWithReason:(AVPlayerViewControllerExitFullScreenReason)reason;
@end
- (void)playerViewController:(AVPlayerViewController *)playerViewController restoreUserInterfaceForOptimizedFullscreenStopWithCompletionHandler:(void (^)(BOOL restored))completionHandler
{
UNUSED_PARAM(playerViewController);
- completionHandler(self.fullscreenInterface->fullscreenMayReturnToInline());
+ self.exitOptimizedCallback = completionHandler;
+ self.fullscreenInterface->fullscreenMayReturnToInline();
}
- (void)playerViewControllerWillCancelOptimizedFullscree:(AVPlayerViewController *)playerViewController
{
UNUSED_PARAM(playerViewController);
- ASSERT(self.delegate);
+ if (!self.delegate)
+ return
self.delegate->requestExitFullscreen();
}
});
}
-void WebVideoFullscreenInterfaceAVKit::setupFullscreen(PlatformLayer& videoLayer, WebCore::IntRect initialRect, UIView* parentView, HTMLMediaElement::VideoFullscreenMode mode, bool allowOptimizedFullscreen)
+void WebVideoFullscreenInterfaceAVKit::setupFullscreen(PlatformLayer& videoLayer, const WebCore::IntRect& initialRect, UIView* parentView, HTMLMediaElement::VideoFullscreenMode mode, bool allowOptimizedFullscreen)
{
RefPtr<WebVideoFullscreenInterfaceAVKit> strongThis(this);
});
}
-void WebVideoFullscreenInterfaceAVKit::setupFullscreenInternal(PlatformLayer& videoLayer, WebCore::IntRect initialRect, UIView* parentView, HTMLMediaElement::VideoFullscreenMode mode, bool allowOptimizedFullscreen)
+void WebVideoFullscreenInterfaceAVKit::setupFullscreenInternal(PlatformLayer& videoLayer, const WebCore::IntRect& initialRect, UIView* parentView, HTMLMediaElement::VideoFullscreenMode mode, bool allowOptimizedFullscreen)
{
UNUSED_PARAM(videoLayer);
UNUSED_PARAM(mode);
}];
}
-void WebVideoFullscreenInterfaceAVKit::exitFullscreen(WebCore::IntRect finalRect)
+void WebVideoFullscreenInterfaceAVKit::exitFullscreen(const WebCore::IntRect& finalRect)
{
RefPtr<WebVideoFullscreenInterfaceAVKit> strongThis(this);
});
}
-void WebVideoFullscreenInterfaceAVKit::exitFullscreenInternal(WebCore::IntRect finalRect)
+void WebVideoFullscreenInterfaceAVKit::exitFullscreenInternal(const WebCore::IntRect& finalRect)
{
[m_playerViewController setShowsPlaybackControls:NO];
if (m_viewController)
m_videoFullscreenModel->requestExitFullscreen();
}
+void WebVideoFullscreenInterfaceAVKit::preparedToReturnToInline(bool visible, const IntRect& inlineRect)
+{
+ RefPtr<WebVideoFullscreenInterfaceAVKit> strongThis(this);
+ dispatch_async(dispatch_get_main_queue(), [strongThis, visible, inlineRect] {
+ if (strongThis->m_playerController.get().exitOptimizedCallback) {
+
+ if (strongThis->m_viewController)
+ [strongThis->m_playerViewController view].frame = [strongThis->m_parentView convertRect:inlineRect toView:nil];
+ else
+ [strongThis->m_playerViewController view].frame = inlineRect;
+
+ strongThis->m_playerController.get().exitOptimizedCallback(visible);
+ }
+ });
+}
+
void WebVideoFullscreenInterfaceAVKit::setIsOptimized(bool active)
{
if (m_mode & HTMLMediaElement::VideoFullscreenModeStandard) {
return [m_playerController isPlaying] && m_mode == HTMLMediaElement::VideoFullscreenModeStandard && wkIsOptimizedFullscreenSupported();
}
-bool WebVideoFullscreenInterfaceAVKit::fullscreenMayReturnToInline()
+void WebVideoFullscreenInterfaceAVKit::fullscreenMayReturnToInline()
{
- m_fullscreenChangeObserver->fullscreenMayReturnToInline();
- return true;
+ if (m_fullscreenChangeObserver)
+ m_fullscreenChangeObserver->fullscreenMayReturnToInline();
}
#endif
namespace WebCore {
+const ScrollAlignment ScrollAlignment::alignCenterIfNotVisible = { noScroll, alignCenter, noScroll };
+const ScrollAlignment ScrollAlignment::alignToEdgeIfNotVisible = { noScroll, alignToClosestEdge, noScroll };
const ScrollAlignment ScrollAlignment::alignCenterIfNeeded = { noScroll, alignCenter, alignToClosestEdge };
WEBCORE_EXPORT const ScrollAlignment ScrollAlignment::alignToEdgeIfNeeded = { noScroll, alignToClosestEdge, alignToClosestEdge };
WEBCORE_EXPORT const ScrollAlignment ScrollAlignment::alignCenterAlways = { alignCenter, alignCenter, alignCenter };
static ScrollBehavior getPartialBehavior(const ScrollAlignment& s) { return s.m_rectPartial; }
static ScrollBehavior getHiddenBehavior(const ScrollAlignment& s) { return s.m_rectHidden; }
+ static const ScrollAlignment alignCenterIfNotVisible;
+ static const ScrollAlignment alignToEdgeIfNotVisible;
static const ScrollAlignment alignCenterIfNeeded;
WEBCORE_EXPORT static const ScrollAlignment alignToEdgeIfNeeded;
WEBCORE_EXPORT static const ScrollAlignment alignCenterAlways;
+2015-03-06 Jeremy Jones <jeremyj@apple.com>
+
+ Scroll to make the video element visible when exiting fullscreen.
+ https://bugs.webkit.org/show_bug.cgi?id=141439
+
+ Reviewed by Simon Fraser.
+
+ This patch will restore interface state when exiting fullscreen.
+ Adds preparedToReturnToInline to continue exiting once the interface is updated.
+
+ * UIProcess/ios/WebVideoFullscreenManagerProxy.h:
+ * UIProcess/ios/WebVideoFullscreenManagerProxy.messages.in:
+ * UIProcess/ios/WebVideoFullscreenManagerProxy.mm:
+ (WebKit::WebVideoFullscreenManagerProxy::setupFullscreenWithID):
+ (WebKit::WebVideoFullscreenManagerProxy::fullscreenMayReturnToInline):
+ (WebKit::WebVideoFullscreenManagerProxy::preparedToReturnToInline): added.
+ * WebProcess/ios/WebVideoFullscreenManager.h:
+ * WebProcess/ios/WebVideoFullscreenManager.messages.in:
+ * WebProcess/ios/WebVideoFullscreenManager.mm:
+ (WebKit::WebVideoFullscreenManager::fullscreenMayReturnToInline):
+
2015-03-06 Antti Koivisto <antti@apple.com>
Rename NetworkCacheStorageCocoa.mm to NetworkCacheStorage.cpp
virtual void didReceiveMessage(IPC::Connection&, IPC::MessageDecoder&) override;
// Translate to FullscreenInterface
- void setupFullscreenWithID(uint32_t, WebCore::IntRect initialRect, float hostingDeviceScaleFactor, WebCore::HTMLMediaElement::VideoFullscreenMode, bool allowOptimizedFullscreen);
+ void setupFullscreenWithID(uint32_t, const WebCore::IntRect& initialRect, float hostingDeviceScaleFactor, WebCore::HTMLMediaElement::VideoFullscreenMode, bool allowOptimizedFullscreen);
void setSeekableRangesVector(const Vector<std::pair<double, double>>&);
void setExternalPlaybackProperties(bool enabled, uint32_t targetType, String localizedDeviceName);
void fullscreenModeChanged(WebCore::HTMLMediaElement::VideoFullscreenMode) override;
-
+ void preparedToReturnToInline(bool visible, const WebCore::IntRect& inlineRect) override;
+
// Fullscreen Observer
virtual void didSetupFullscreen() override;
virtual void didEnterFullscreen() override;
EnterFullscreen()
ExitFullscreen(WebCore::IntRect finalRect)
CleanupFullscreen()
+ PreparedToReturnToInline(bool visible, WebCore::IntRect inlineRect)
}
#endif
m_layerHost.clear();
}
-void WebVideoFullscreenManagerProxy::setupFullscreenWithID(uint32_t videoLayerID, WebCore::IntRect initialRect, float hostingDeviceScaleFactor, HTMLMediaElement::VideoFullscreenMode videoFullscreenMode, bool allowOptimizedFullscreen)
+void WebVideoFullscreenManagerProxy::setupFullscreenWithID(uint32_t videoLayerID, const WebCore::IntRect& initialRect, float hostingDeviceScaleFactor, HTMLMediaElement::VideoFullscreenMode videoFullscreenMode, bool allowOptimizedFullscreen)
{
ASSERT(videoLayerID);
m_layerHost = WKMakeRenderLayer(videoLayerID);
void WebVideoFullscreenManagerProxy::fullscreenMayReturnToInline()
{
+ bool isViewVisible = m_page->isViewVisible();
+ m_page->send(Messages::WebVideoFullscreenManager::FullscreenMayReturnToInline(isViewVisible), m_page->pageID());
+}
+
+void WebVideoFullscreenManagerProxy::preparedToReturnToInline(bool visible, const WebCore::IntRect& inlineRect)
+{
m_page->fullscreenMayReturnToInline();
+ WebVideoFullscreenInterfaceAVKit::preparedToReturnToInline(visible, inlineRect);
}
void WebVideoFullscreenManagerProxy::requestExitFullscreen()
virtual void didExitFullscreen();
virtual void didCleanupFullscreen();
virtual void setVideoLayerGravityEnum(unsigned);
+ virtual void fullscreenMayReturnToInline(bool isPageVisible);
void setVideoLayerFrameFenced(WebCore::FloatRect bounds, IPC::Attachment fencePort);
WebPage* m_page;
SelectAudioMediaOption(uint64_t index)
SelectLegibleMediaOption(uint64_t index)
fullscreenModeChanged(WebCore::HTMLMediaElement::VideoFullscreenMode videoFullscreenMode)
+ FullscreenMayReturnToInline(bool isPageVisible)
}
#endif
setVideoLayerGravity((WebVideoFullscreenModel::VideoGravity)gravity);
}
+void WebVideoFullscreenManager::fullscreenMayReturnToInline(bool isPageVisible)
+{
+ if (!isPageVisible)
+ m_videoElement->scrollIntoViewIfNotVisible(false);
+ m_page->send(Messages::WebVideoFullscreenManagerProxy::PreparedToReturnToInline(true, clientRectForElement(m_videoElement.get())), m_page->pageID());
+}
+
void WebVideoFullscreenManager::setVideoLayerFrameFenced(WebCore::FloatRect bounds, IPC::Attachment fencePort)
{
if (m_layerHostingContext)