| Index: third_party/WebKit/Source/core/html/shadow/MediaControls.cpp
|
| diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp b/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp
|
| index 9652b7e9ef2c5f24ffaaa634bc31ec9b6efccb3d..03888b381a5f79c0c97ffb80287c42173679dd0d 100644
|
| --- a/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp
|
| +++ b/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp
|
| @@ -133,7 +133,8 @@ MediaControls::MediaControls(HTMLMediaElement& mediaElement)
|
| &MediaControls::panelWidthChangedTimerFired),
|
| m_panelWidth(0),
|
| m_allowHiddenVolumeControls(
|
| - RuntimeEnabledFeatures::newMediaPlaybackUiEnabled()) {}
|
| + RuntimeEnabledFeatures::newMediaPlaybackUiEnabled()),
|
| + m_keepShowingUntilTimerFires(false) {}
|
|
|
| MediaControls* MediaControls::create(HTMLMediaElement& mediaElement) {
|
| MediaControls* controls = new MediaControls(mediaElement);
|
| @@ -391,6 +392,10 @@ void MediaControls::hide() {
|
| m_overlayPlayButton->setIsWanted(false);
|
| }
|
|
|
| +bool MediaControls::isVisible() const {
|
| + return m_panel->isOpaque();
|
| +}
|
| +
|
| void MediaControls::makeOpaque() {
|
| m_panel->makeOpaque();
|
| }
|
| @@ -402,26 +407,38 @@ void MediaControls::makeTransparent() {
|
| bool MediaControls::shouldHideMediaControls(unsigned behaviorFlags) const {
|
| // Never hide for a media element without visual representation.
|
| if (!mediaElement().isHTMLVideoElement() || !mediaElement().hasVideo() ||
|
| - mediaElement().isPlayingRemotely())
|
| + mediaElement().isPlayingRemotely()) {
|
| + return false;
|
| + }
|
| +
|
| + // Keep the controls visible as long as the timer is running.
|
| + const bool ignoreWaitForTimer = behaviorFlags & IgnoreWaitForTimer;
|
| + if (!ignoreWaitForTimer && m_keepShowingUntilTimerFires)
|
| return false;
|
| +
|
| // Don't hide if the mouse is over the controls.
|
| const bool ignoreControlsHover = behaviorFlags & IgnoreControlsHover;
|
| if (!ignoreControlsHover && m_panel->isHovered())
|
| return false;
|
| +
|
| // Don't hide if the mouse is over the video area.
|
| const bool ignoreVideoHover = behaviorFlags & IgnoreVideoHover;
|
| if (!ignoreVideoHover && m_isMouseOverControls)
|
| return false;
|
| +
|
| // Don't hide if focus is on the HTMLMediaElement or within the
|
| // controls/shadow tree. (Perform the checks separately to avoid going
|
| // through all the potential ancestor hosts for the focused element.)
|
| const bool ignoreFocus = behaviorFlags & IgnoreFocus;
|
| if (!ignoreFocus &&
|
| - (mediaElement().isFocused() || contains(document().focusedElement())))
|
| + (mediaElement().isFocused() || contains(document().focusedElement()))) {
|
| return false;
|
| + }
|
| +
|
| // Don't hide the media controls when a panel is showing.
|
| if (m_textTrackList->isWanted() || m_overflowList->isWanted())
|
| return false;
|
| +
|
| return true;
|
| }
|
|
|
| @@ -444,7 +461,7 @@ void MediaControls::playbackProgressed() {
|
| m_timeline->setPosition(mediaElement().currentTime());
|
| updateCurrentTimeDisplay();
|
|
|
| - if (shouldHideMediaControls())
|
| + if (isVisible() && shouldHideMediaControls())
|
| makeTransparent();
|
| }
|
|
|
| @@ -640,11 +657,35 @@ void MediaControls::defaultEventHandler(Event* event) {
|
| // event, to allow the hide-timer to do the right thing when it fires.
|
| // FIXME: Preferably we would only do this when we're actually handling the
|
| // event here ourselves.
|
| - bool wasLastEventTouch =
|
| + bool isTouchEvent =
|
| event->isTouchEvent() || event->isGestureEvent() ||
|
| (event->isMouseEvent() && toMouseEvent(event)->fromTouch());
|
| - m_hideTimerBehaviorFlags |=
|
| - wasLastEventTouch ? IgnoreControlsHover : IgnoreNone;
|
| + m_hideTimerBehaviorFlags |= isTouchEvent ? IgnoreControlsHover : IgnoreNone;
|
| +
|
| + // Touch events are treated differently to avoid fake mouse events to trigger
|
| + // random behavior. The expect behaviour for touch is that a tap will show the
|
| + // controls and they will hide when the timer to hide fires.
|
| + if (isTouchEvent) {
|
| + if (event->type() != EventTypeNames::gesturetap)
|
| + return;
|
| +
|
| + if (!containsRelatedTarget(event)) {
|
| + if (!mediaElement().paused()) {
|
| + if (!isVisible()) {
|
| + makeOpaque();
|
| + // When the panel switches from invisible to visible, we need to mark
|
| + // the event handled to avoid buttons below the tap to be activated.
|
| + event->setDefaultHandled();
|
| + }
|
| + if (shouldHideMediaControls(IgnoreWaitForTimer)) {
|
| + m_keepShowingUntilTimerFires = true;
|
| + startHideMediaControlsTimer();
|
| + }
|
| + }
|
| + }
|
| +
|
| + return;
|
| + }
|
|
|
| if (event->type() == EventTypeNames::mouseover) {
|
| if (!containsRelatedTarget(event)) {
|
| @@ -681,6 +722,7 @@ void MediaControls::hideMediaControlsTimerFired(TimerBase*) {
|
| unsigned behaviorFlags =
|
| m_hideTimerBehaviorFlags | IgnoreFocus | IgnoreVideoHover;
|
| m_hideTimerBehaviorFlags = IgnoreNone;
|
| + m_keepShowingUntilTimerFires = false;
|
|
|
| if (mediaElement().paused())
|
| return;
|
| @@ -698,6 +740,7 @@ void MediaControls::startHideMediaControlsTimer() {
|
| }
|
|
|
| void MediaControls::stopHideMediaControlsTimer() {
|
| + m_keepShowingUntilTimerFires = false;
|
| m_hideMediaControlsTimer.stop();
|
| }
|
|
|
|
|