Diff
Modified: trunk/Source/WebCore/ChangeLog (199021 => 199022)
--- trunk/Source/WebCore/ChangeLog 2016-04-04 21:09:35 UTC (rev 199021)
+++ trunk/Source/WebCore/ChangeLog 2016-04-04 21:18:57 UTC (rev 199022)
@@ -1,3 +1,51 @@
+2016-04-04 Beth Dakin <[email protected]>
+
+ Add some logic to decide when a video can control the videoControlsManager
+ https://bugs.webkit.org/show_bug.cgi?id=156089
+ -and corresponding-
+ rdar://problem/23833752
+
+ Reviewed by Eric Carlson and Tim Horton.
+
+ With this patch, a video can take over the videoControlsManager if all of
+ these conditions are met:
+ -Playback is permitted
+ -The video has a renderer
+ -The video is 400x300 or larger
+ AND
+ -The video has both audio and video
+
+ If those criteria are not met the video will still be allowed to take over
+ the videoControlsManager if:
+ -Playback is permitted
+ -The video has a renderer
+ -The video started playing because of a user gesture.
+
+ If multiple videos meet this criteria, then the video that most recently
+ started playing will take over the videoControlsManager.
+
+ We might consider more restrictions in the future, but this seems like a good
+ place to start.
+
+ Move all decisions about the videoControlsManager to updatePlayState()
+ instead of playInternal().
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::playInternal):
+
+ If the video will play after updatePlayState, then invoke
+ setUpVideoControlsManager() if canControlControlsManager() is true. If the
+ video will not be playing after updatePlayState, then check to see if
+ endedPlayback() is true. If it is, then invoke clearVideoControlsManager().
+ (WebCore::HTMLMediaElement::updatePlayState):
+
+ The logic for the heuristic is here:
+ * html/MediaElementSession.cpp:
+ (WebCore::MediaElementSession::canControlControlsManager):
+ * html/MediaElementSession.h:
+
+ New ChromeClient function clearVideoControlsManager().
+ * page/ChromeClient.h:
+
2016-04-03 Sam Weinig <[email protected]>
Add SPI to allow install script message handlers in isolated worlds
Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (199021 => 199022)
--- trunk/Source/WebCore/html/HTMLMediaElement.cpp 2016-04-04 21:09:35 UTC (rev 199021)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp 2016-04-04 21:18:57 UTC (rev 199022)
@@ -2992,14 +2992,6 @@
return;
}
- // FIXME: rdar://problem/23833752 We need to be more strategic about when we set up the video controls manager.
- // It's really something that should be handled by the PlatformMediaSessionManager since we only want a controls
- // manager for the currentSession.
- if (document().page() && is<HTMLVideoElement>(*this)) {
- HTMLVideoElement& asVideo = downcast<HTMLVideoElement>(*this);
- document().page()->chrome().client().setUpVideoControlsManager(asVideo);
- }
-
// 4.8.10.9. Playing the media resource
if (!m_player || m_networkState == NETWORK_EMPTY)
scheduleDelayedAction(LoadMediaResource);
@@ -4816,6 +4808,11 @@
LOG(Media, "HTMLMediaElement::updatePlayState(%p) - shouldBePlaying = %s, playerPaused = %s", this, boolString(shouldBePlaying), boolString(playerPaused));
if (shouldBePlaying) {
+ if (document().page() && m_mediaSession->canControlControlsManager(*this)) {
+ HTMLVideoElement& asVideo = downcast<HTMLVideoElement>(*this);
+ document().page()->chrome().client().setUpVideoControlsManager(asVideo);
+ }
+
setDisplayMode(Video);
invalidateCachedTime();
@@ -4848,6 +4845,9 @@
startPlaybackProgressTimer();
setPlaying(true);
} else {
+ if (endedPlayback() && document().page() && is<HTMLVideoElement>(*this))
+ document().page()->chrome().client().clearVideoControlsManager();
+
if (!playerPaused)
m_player->pause();
refreshCachedTime();
Modified: trunk/Source/WebCore/html/MediaElementSession.cpp (199021 => 199022)
--- trunk/Source/WebCore/html/MediaElementSession.cpp 2016-04-04 21:09:35 UTC (rev 199021)
+++ trunk/Source/WebCore/html/MediaElementSession.cpp 2016-04-04 21:18:57 UTC (rev 199022)
@@ -213,6 +213,31 @@
return true;
}
+bool MediaElementSession::canControlControlsManager(const HTMLMediaElement& element) const
+{
+ // FIXME: rdar://problem/25537071 Audio elements should be able to have a controls manager as well.
+ // Audio elements should probably only have a controls manager if they started playing via a user gesture.
+ if (!element.isVideo())
+ return false;
+
+ if (!playbackPermitted(element))
+ return false;
+
+ RenderBox* renderer = downcast<RenderBox>(element.renderer());
+ if (!renderer)
+ return false;
+
+ if (renderer->clientWidth() >= elementMainContentMinimumWidth && renderer->clientHeight() >= elementMainContentMinimumHeight) {
+ if (element.hasAudio() && element.hasVideo())
+ return true;
+ }
+
+ if (ScriptController::processingUserGestureForMedia())
+ return true;
+
+ return false;
+}
+
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
void MediaElementSession::showPlaybackTargetPicker(const HTMLMediaElement& element)
{
Modified: trunk/Source/WebCore/html/MediaElementSession.h (199021 => 199022)
--- trunk/Source/WebCore/html/MediaElementSession.h 2016-04-04 21:09:35 UTC (rev 199021)
+++ trunk/Source/WebCore/html/MediaElementSession.h 2016-04-04 21:18:57 UTC (rev 199022)
@@ -53,6 +53,8 @@
bool pageAllowsDataLoading(const HTMLMediaElement&) const;
bool pageAllowsPlaybackAfterResuming(const HTMLMediaElement&) const;
+ bool canControlControlsManager(const HTMLMediaElement&) const;
+
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
void showPlaybackTargetPicker(const HTMLMediaElement&);
bool hasWirelessPlaybackTargets(const HTMLMediaElement&) const;
Modified: trunk/Source/WebCore/page/ChromeClient.h (199021 => 199022)
--- trunk/Source/WebCore/page/ChromeClient.h 2016-04-04 21:09:35 UTC (rev 199021)
+++ trunk/Source/WebCore/page/ChromeClient.h 2016-04-04 21:18:57 UTC (rev 199022)
@@ -342,6 +342,7 @@
#if ENABLE(VIDEO)
virtual void enterVideoFullscreenForVideoElement(HTMLVideoElement&, HTMLMediaElementEnums::VideoFullscreenMode) { }
virtual void setUpVideoControlsManager(HTMLVideoElement&) { }
+ virtual void clearVideoControlsManager() { }
#endif
virtual void exitVideoFullscreenForVideoElement(WebCore::HTMLVideoElement&) { }
virtual void exitVideoFullscreenToModeWithoutAnimation(WebCore::HTMLVideoElement&, HTMLMediaElementEnums::VideoFullscreenMode /*targetMode*/) { }
Modified: trunk/Source/WebKit2/ChangeLog (199021 => 199022)
--- trunk/Source/WebKit2/ChangeLog 2016-04-04 21:09:35 UTC (rev 199021)
+++ trunk/Source/WebKit2/ChangeLog 2016-04-04 21:18:57 UTC (rev 199022)
@@ -1,3 +1,57 @@
+2016-04-04 Beth Dakin <[email protected]>
+
+ Add some logic to decide when a video can control the videoControlsManager
+ https://bugs.webkit.org/show_bug.cgi?id=156089
+ -and corresponding-
+ rdar://problem/23833752
+
+ Reviewed by Eric Carlson and Tim Horton.
+
+ The biggest change in WebKit2 is to push all of the logic for the
+ videoControlsManager into WebCore. With this change, WebCore will invoke
+ setUpVideoControlsManager() when there is a video to control the manager, and
+ it will call clearVideoControlsManager() when there is not.
+
+ Add clearVideoControlsManager().
+ * UIProcess/Cocoa/WebVideoFullscreenManagerProxy.h:
+ * UIProcess/Cocoa/WebVideoFullscreenManagerProxy.messages.in:
+ * UIProcess/Cocoa/WebVideoFullscreenManagerProxy.mm:
+ (WebKit::WebVideoFullscreenManagerProxy::clearVideoControlsManager):
+
+ Re-name isPlayingMediaDidChange() to videoControlsManagerDidChange(). This
+ ties the logic to the lifetime of the videoControlsManager instead of
+ figuring it out in the UIProcess based on the media state.
+ * UIProcess/Cocoa/WebViewImpl.h:
+ * UIProcess/Cocoa/WebViewImpl.mm:
+ (WebKit::WebViewImpl::videoControlsManagerDidChange):
+ (WebKit::WebViewImpl::isPlayingMediaDidChange): Deleted.
+ * UIProcess/PageClient.h:
+
+ Also change isPlayingVideoWithAudio() into hasActiveVideoForControlsManager()
+ Again, this ties the logic to the lifetime of the videoControlsManager
+ instead of figuring it out in the UIProcess based on the media state.
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::isPlayingMediaDidChange):
+ (WebKit::WebPageProxy::videoControlsManagerDidChange):
+ (WebKit::WebPageProxy::hasActiveVideoForControlsManager):
+ (WebKit::WebPageProxy::isPlayingVideoWithAudio): Deleted.
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/mac/PageClientImpl.h:
+ * UIProcess/mac/PageClientImpl.mm:
+ (WebKit::PageClientImpl::videoControlsManagerDidChange):
+ (WebKit::PageClientImpl::isPlayingMediaDidChange): Deleted.
+
+ New WebChromeClient function clearVideoControlsManager().
+ * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+ (WebKit::WebChromeClient::clearVideoControlsManager):
+ * WebProcess/WebCoreSupport/WebChromeClient.h:
+
+ Do the work to clear the videoControlsManager.
+ * WebProcess/cocoa/WebVideoFullscreenManager.h:
+ * WebProcess/cocoa/WebVideoFullscreenManager.mm:
+ (WebKit::WebVideoFullscreenManager::clearVideoControlsManager):
+ (WebKit::WebVideoFullscreenManager::exitVideoFullscreenToModeWithoutAnimation):
+
2016-04-04 Brent Fulgham <[email protected]>
REGRESSION(r198955): com.apple.WebKit.Networking.Development crashed in WebKit::NetworkLoad::setPendingDownloadID + 11
Modified: trunk/Source/WebKit2/UIProcess/Cocoa/WebVideoFullscreenManagerProxy.h (199021 => 199022)
--- trunk/Source/WebKit2/UIProcess/Cocoa/WebVideoFullscreenManagerProxy.h 2016-04-04 21:09:35 UTC (rev 199021)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/WebVideoFullscreenManagerProxy.h 2016-04-04 21:18:57 UTC (rev 199022)
@@ -138,6 +138,7 @@
// Messages from WebVideoFullscreenManager
void setupFullscreenWithID(uint64_t contextId, uint32_t videoLayerID, const WebCore::IntRect& initialRect, float hostingScaleFactor, WebCore::HTMLMediaElementEnums::VideoFullscreenMode, bool allowsPictureInPicture);
void setUpVideoControlsManagerWithID(uint64_t contextId);
+ void clearVideoControlsManager();
void resetMediaState(uint64_t contextId);
void setCurrentTime(uint64_t contextId, double currentTime, double hostTime);
void setBufferedTime(uint64_t contextId, double bufferedTime);
Modified: trunk/Source/WebKit2/UIProcess/Cocoa/WebVideoFullscreenManagerProxy.messages.in (199021 => 199022)
--- trunk/Source/WebKit2/UIProcess/Cocoa/WebVideoFullscreenManagerProxy.messages.in 2016-04-04 21:09:35 UTC (rev 199021)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/WebVideoFullscreenManagerProxy.messages.in 2016-04-04 21:18:57 UTC (rev 199022)
@@ -40,6 +40,7 @@
CleanupFullscreen(uint64_t contextId)
PreparedToReturnToInline(uint64_t contextId, bool visible, WebCore::IntRect inlineRect)
SetUpVideoControlsManagerWithID(uint64_t contextId)
+ ClearVideoControlsManager()
#if PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE)
ExitFullscreenWithoutAnimationToMode(uint64_t contextId, WebCore::HTMLMediaElementEnums::VideoFullscreenMode videoFullscreenMode)
#endif
Modified: trunk/Source/WebKit2/UIProcess/Cocoa/WebVideoFullscreenManagerProxy.mm (199021 => 199022)
--- trunk/Source/WebKit2/UIProcess/Cocoa/WebVideoFullscreenManagerProxy.mm 2016-04-04 21:09:35 UTC (rev 199021)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/WebVideoFullscreenManagerProxy.mm 2016-04-04 21:18:57 UTC (rev 199022)
@@ -412,11 +412,25 @@
m_controlsManagerContextId = contextId;
ensureInterface(m_controlsManagerContextId).ensureControlsManager();
addClientForContext(m_controlsManagerContextId);
+
+ m_page->videoControlsManagerDidChange();
#else
UNUSED_PARAM(contextId);
#endif
}
+void WebVideoFullscreenManagerProxy::clearVideoControlsManager()
+{
+#if PLATFORM(MAC)
+ if (!m_controlsManagerContextId)
+ return;
+
+ removeClientForContext(m_controlsManagerContextId);
+ m_controlsManagerContextId = 0;
+ m_page->videoControlsManagerDidChange();
+#endif
+}
+
void WebVideoFullscreenManagerProxy::resetMediaState(uint64_t contextId)
{
ensureInterface(contextId).resetMediaState();
Modified: trunk/Source/WebKit2/UIProcess/Cocoa/WebViewImpl.h (199021 => 199022)
--- trunk/Source/WebKit2/UIProcess/Cocoa/WebViewImpl.h 2016-04-04 21:09:35 UTC (rev 199021)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/WebViewImpl.h 2016-04-04 21:18:57 UTC (rev 199022)
@@ -324,7 +324,7 @@
void completeImmediateActionAnimation();
void didChangeContentSize(CGSize);
void didHandleAcceptedCandidate();
- void isPlayingMediaDidChange();
+ void videoControlsManagerDidChange();
void setIgnoresNonWheelEvents(bool);
bool ignoresNonWheelEvents() const { return m_ignoresNonWheelEvents; }
Modified: trunk/Source/WebKit2/UIProcess/Cocoa/WebViewImpl.mm (199021 => 199022)
--- trunk/Source/WebKit2/UIProcess/Cocoa/WebViewImpl.mm 2016-04-04 21:09:35 UTC (rev 199021)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/WebViewImpl.mm 2016-04-04 21:18:57 UTC (rev 199022)
@@ -2389,7 +2389,7 @@
m_isHandlingAcceptedCandidate = false;
}
-void WebViewImpl::isPlayingMediaDidChange()
+void WebViewImpl::videoControlsManagerDidChange()
{
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
updateWebViewImplAdditions();
Modified: trunk/Source/WebKit2/UIProcess/PageClient.h (199021 => 199022)
--- trunk/Source/WebKit2/UIProcess/PageClient.h 2016-04-04 21:09:35 UTC (rev 199021)
+++ trunk/Source/WebKit2/UIProcess/PageClient.h 2016-04-04 21:18:57 UTC (rev 199022)
@@ -346,7 +346,7 @@
virtual void didHandleAcceptedCandidate() = 0;
- virtual void isPlayingMediaDidChange() = 0;
+ virtual void videoControlsManagerDidChange() = 0;
#endif
#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (199021 => 199022)
--- trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp 2016-04-04 21:09:35 UTC (rev 199021)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp 2016-04-04 21:18:57 UTC (rev 199022)
@@ -6025,21 +6025,27 @@
MediaProducer::MediaStateFlags oldState = m_mediaState;
m_mediaState = state;
-#if PLATFORM(MAC)
- if ((oldState & playingMediaMask) != (m_mediaState & playingMediaMask))
- m_pageClient.isPlayingMediaDidChange();
-#endif
-
playingMediaMask |= MediaProducer::HasActiveMediaCaptureDevice;
if ((oldState & playingMediaMask) != (m_mediaState & playingMediaMask))
m_uiClient->isPlayingAudioDidChange(*this);
}
-bool WebPageProxy::isPlayingVideoWithAudio() const
+#if PLATFORM(MAC)
+void WebPageProxy::videoControlsManagerDidChange()
{
- return m_mediaState & MediaProducer::IsPlayingAudio && m_mediaState & MediaProducer::IsPlayingVideo;
+ m_pageClient.videoControlsManagerDidChange();
}
+bool WebPageProxy::hasActiveVideoForControlsManager() const
+{
+#if ENABLE(VIDEO_PRESENTATION_MODE)
+ return m_videoFullscreenManager && m_videoFullscreenManager->controlsManagerInterface() && m_mediaState & MediaProducer::HasAudioOrVideo;
+#else
+ return false;
+#endif
+}
+#endif
+
#if ENABLE(MEDIA_SESSION)
void WebPageProxy::hasMediaSessionWithActiveMediaElementsDidChange(bool state)
{
Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (199021 => 199022)
--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h 2016-04-04 21:09:35 UTC (rev 199021)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h 2016-04-04 21:18:57 UTC (rev 199022)
@@ -1020,7 +1020,10 @@
void isPlayingMediaDidChange(WebCore::MediaProducer::MediaStateFlags, uint64_t);
WebCore::MediaProducer::MediaStateFlags mediaStateFlags() const { return m_mediaState; }
- bool isPlayingVideoWithAudio() const;
+#if PLATFORM(MAC)
+ void videoControlsManagerDidChange();
+ bool hasActiveVideoForControlsManager() const;
+#endif
#if ENABLE(MEDIA_SESSION)
void hasMediaSessionWithActiveMediaElementsDidChange(bool);
Modified: trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h (199021 => 199022)
--- trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h 2016-04-04 21:09:35 UTC (rev 199021)
+++ trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h 2016-04-04 21:18:57 UTC (rev 199022)
@@ -211,7 +211,7 @@
void didHandleAcceptedCandidate() override;
- void isPlayingMediaDidChange() override;
+ void videoControlsManagerDidChange() override;
void showPlatformContextMenu(NSMenu *, WebCore::IntPoint) override;
Modified: trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm (199021 => 199022)
--- trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm 2016-04-04 21:09:35 UTC (rev 199021)
+++ trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm 2016-04-04 21:18:57 UTC (rev 199022)
@@ -779,9 +779,9 @@
m_impl->didHandleAcceptedCandidate();
}
-void PageClientImpl::isPlayingMediaDidChange()
+void PageClientImpl::videoControlsManagerDidChange()
{
- m_impl->isPlayingMediaDidChange();
+ m_impl->videoControlsManagerDidChange();
}
void PageClientImpl::showPlatformContextMenu(NSMenu *menu, IntPoint location)
Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp (199021 => 199022)
--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp 2016-04-04 21:09:35 UTC (rev 199021)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp 2016-04-04 21:18:57 UTC (rev 199022)
@@ -861,6 +861,11 @@
m_page->videoFullscreenManager()->setUpVideoControlsManager(videoElement);
}
+void WebChromeClient::clearVideoControlsManager()
+{
+ m_page->videoFullscreenManager()->clearVideoControlsManager();
+}
+
void WebChromeClient::enterVideoFullscreenForVideoElement(WebCore::HTMLVideoElement& videoElement, WebCore::HTMLMediaElementEnums::VideoFullscreenMode mode)
{
ASSERT(mode != HTMLMediaElementEnums::VideoFullscreenModeNone);
Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h (199021 => 199022)
--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h 2016-04-04 21:09:35 UTC (rev 199021)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h 2016-04-04 21:18:57 UTC (rev 199022)
@@ -245,6 +245,7 @@
#if PLATFORM(IOS) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
bool supportsVideoFullscreen(WebCore::HTMLMediaElementEnums::VideoFullscreenMode) override;
void setUpVideoControlsManager(WebCore::HTMLVideoElement&) override;
+ void clearVideoControlsManager() override;
void enterVideoFullscreenForVideoElement(WebCore::HTMLVideoElement&, WebCore::HTMLMediaElementEnums::VideoFullscreenMode) override;
void exitVideoFullscreenForVideoElement(WebCore::HTMLVideoElement&) override;
#if PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE)
Modified: trunk/Source/WebKit2/WebProcess/cocoa/WebVideoFullscreenManager.h (199021 => 199022)
--- trunk/Source/WebKit2/WebProcess/cocoa/WebVideoFullscreenManager.h 2016-04-04 21:09:35 UTC (rev 199021)
+++ trunk/Source/WebKit2/WebProcess/cocoa/WebVideoFullscreenManager.h 2016-04-04 21:18:57 UTC (rev 199022)
@@ -118,6 +118,7 @@
void exitVideoFullscreenForVideoElement(WebCore::HTMLVideoElement&);
void exitVideoFullscreenToModeWithoutAnimation(WebCore::HTMLVideoElement&, WebCore::HTMLMediaElementEnums::VideoFullscreenMode);
void setUpVideoControlsManager(WebCore::HTMLVideoElement&);
+ void clearVideoControlsManager();
protected:
friend class WebVideoFullscreenInterfaceContext;
Modified: trunk/Source/WebKit2/WebProcess/cocoa/WebVideoFullscreenManager.mm (199021 => 199022)
--- trunk/Source/WebKit2/WebProcess/cocoa/WebVideoFullscreenManager.mm 2016-04-04 21:09:35 UTC (rev 199021)
+++ trunk/Source/WebKit2/WebProcess/cocoa/WebVideoFullscreenManager.mm 2016-04-04 21:18:57 UTC (rev 199022)
@@ -344,6 +344,18 @@
#endif
}
+void WebVideoFullscreenManager::clearVideoControlsManager()
+{
+#if PLATFORM(MAC)
+ if (!m_controlsManagerContextId)
+ return;
+
+ removeClientForContext(m_controlsManagerContextId);
+ m_controlsManagerContextId = 0;
+ m_page->send(Messages::WebVideoFullscreenManagerProxy::ClearVideoControlsManager(), m_page->pageID());
+#endif
+}
+
void WebVideoFullscreenManager::exitVideoFullscreenToModeWithoutAnimation(WebCore::HTMLVideoElement& videoElement, WebCore::HTMLMediaElementEnums::VideoFullscreenMode targetMode)
{
#if PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE)