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

Side by Side Diff: third_party/WebKit/Source/core/html/shadow/MediaControls.cpp

Issue 2431583004: Media Controls: don't activate buttons when tapping on hidden controls. (Closed)
Patch Set: review comments Created 4 years, 1 month 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 unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/core/html/shadow/MediaControls.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011, 2012 Apple Inc. All rights reserved. 2 * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
3 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. 3 * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 WTF::bind(&MediaControls::hideAllMenus, wrapWeakPersistent(this)))), 126 WTF::bind(&MediaControls::hideAllMenus, wrapWeakPersistent(this)))),
127 m_hideMediaControlsTimer(this, 127 m_hideMediaControlsTimer(this,
128 &MediaControls::hideMediaControlsTimerFired), 128 &MediaControls::hideMediaControlsTimerFired),
129 m_hideTimerBehaviorFlags(IgnoreNone), 129 m_hideTimerBehaviorFlags(IgnoreNone),
130 m_isMouseOverControls(false), 130 m_isMouseOverControls(false),
131 m_isPausedForScrubbing(false), 131 m_isPausedForScrubbing(false),
132 m_panelWidthChangedTimer(this, 132 m_panelWidthChangedTimer(this,
133 &MediaControls::panelWidthChangedTimerFired), 133 &MediaControls::panelWidthChangedTimerFired),
134 m_panelWidth(0), 134 m_panelWidth(0),
135 m_allowHiddenVolumeControls( 135 m_allowHiddenVolumeControls(
136 RuntimeEnabledFeatures::newMediaPlaybackUiEnabled()) {} 136 RuntimeEnabledFeatures::newMediaPlaybackUiEnabled()),
137 m_keepShowingUntilTimerFires(false) {}
137 138
138 MediaControls* MediaControls::create(HTMLMediaElement& mediaElement) { 139 MediaControls* MediaControls::create(HTMLMediaElement& mediaElement) {
139 MediaControls* controls = new MediaControls(mediaElement); 140 MediaControls* controls = new MediaControls(mediaElement);
140 controls->setShadowPseudoId(AtomicString("-webkit-media-controls")); 141 controls->setShadowPseudoId(AtomicString("-webkit-media-controls"));
141 controls->initializeControls(); 142 controls->initializeControls();
142 return controls; 143 return controls;
143 } 144 }
144 145
145 // The media controls DOM structure looks like: 146 // The media controls DOM structure looks like:
146 // 147 //
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 } 385 }
385 } 386 }
386 387
387 void MediaControls::hide() { 388 void MediaControls::hide() {
388 m_panel->setIsWanted(false); 389 m_panel->setIsWanted(false);
389 m_panel->setIsDisplayed(false); 390 m_panel->setIsDisplayed(false);
390 if (m_overlayPlayButton) 391 if (m_overlayPlayButton)
391 m_overlayPlayButton->setIsWanted(false); 392 m_overlayPlayButton->setIsWanted(false);
392 } 393 }
393 394
395 bool MediaControls::isVisible() const {
396 return m_panel->isOpaque();
397 }
398
394 void MediaControls::makeOpaque() { 399 void MediaControls::makeOpaque() {
395 m_panel->makeOpaque(); 400 m_panel->makeOpaque();
396 } 401 }
397 402
398 void MediaControls::makeTransparent() { 403 void MediaControls::makeTransparent() {
399 m_panel->makeTransparent(); 404 m_panel->makeTransparent();
400 } 405 }
401 406
402 bool MediaControls::shouldHideMediaControls(unsigned behaviorFlags) const { 407 bool MediaControls::shouldHideMediaControls(unsigned behaviorFlags) const {
403 // Never hide for a media element without visual representation. 408 // Never hide for a media element without visual representation.
404 if (!mediaElement().isHTMLVideoElement() || !mediaElement().hasVideo() || 409 if (!mediaElement().isHTMLVideoElement() || !mediaElement().hasVideo() ||
405 mediaElement().isPlayingRemotely()) 410 mediaElement().isPlayingRemotely()) {
406 return false; 411 return false;
412 }
413
414 // Keep the controls visible as long as the timer is running.
415 const bool ignoreWaitForTimer = behaviorFlags & IgnoreWaitForTimer;
416 if (!ignoreWaitForTimer && m_keepShowingUntilTimerFires)
417 return false;
418
407 // Don't hide if the mouse is over the controls. 419 // Don't hide if the mouse is over the controls.
408 const bool ignoreControlsHover = behaviorFlags & IgnoreControlsHover; 420 const bool ignoreControlsHover = behaviorFlags & IgnoreControlsHover;
409 if (!ignoreControlsHover && m_panel->isHovered()) 421 if (!ignoreControlsHover && m_panel->isHovered())
410 return false; 422 return false;
423
411 // Don't hide if the mouse is over the video area. 424 // Don't hide if the mouse is over the video area.
412 const bool ignoreVideoHover = behaviorFlags & IgnoreVideoHover; 425 const bool ignoreVideoHover = behaviorFlags & IgnoreVideoHover;
413 if (!ignoreVideoHover && m_isMouseOverControls) 426 if (!ignoreVideoHover && m_isMouseOverControls)
414 return false; 427 return false;
428
415 // Don't hide if focus is on the HTMLMediaElement or within the 429 // Don't hide if focus is on the HTMLMediaElement or within the
416 // controls/shadow tree. (Perform the checks separately to avoid going 430 // controls/shadow tree. (Perform the checks separately to avoid going
417 // through all the potential ancestor hosts for the focused element.) 431 // through all the potential ancestor hosts for the focused element.)
418 const bool ignoreFocus = behaviorFlags & IgnoreFocus; 432 const bool ignoreFocus = behaviorFlags & IgnoreFocus;
419 if (!ignoreFocus && 433 if (!ignoreFocus &&
420 (mediaElement().isFocused() || contains(document().focusedElement()))) 434 (mediaElement().isFocused() || contains(document().focusedElement()))) {
421 return false; 435 return false;
436 }
437
422 // Don't hide the media controls when a panel is showing. 438 // Don't hide the media controls when a panel is showing.
423 if (m_textTrackList->isWanted() || m_overflowList->isWanted()) 439 if (m_textTrackList->isWanted() || m_overflowList->isWanted())
424 return false; 440 return false;
441
425 return true; 442 return true;
426 } 443 }
427 444
428 void MediaControls::playbackStarted() { 445 void MediaControls::playbackStarted() {
429 BatchedControlUpdate batch(this); 446 BatchedControlUpdate batch(this);
430 447
431 if (!RuntimeEnabledFeatures::newMediaPlaybackUiEnabled()) { 448 if (!RuntimeEnabledFeatures::newMediaPlaybackUiEnabled()) {
432 m_currentTimeDisplay->setIsWanted(true); 449 m_currentTimeDisplay->setIsWanted(true);
433 m_durationDisplay->setIsWanted(false); 450 m_durationDisplay->setIsWanted(false);
434 } 451 }
435 452
436 updatePlayState(); 453 updatePlayState();
437 m_timeline->setPosition(mediaElement().currentTime()); 454 m_timeline->setPosition(mediaElement().currentTime());
438 updateCurrentTimeDisplay(); 455 updateCurrentTimeDisplay();
439 456
440 startHideMediaControlsTimer(); 457 startHideMediaControlsTimer();
441 } 458 }
442 459
443 void MediaControls::playbackProgressed() { 460 void MediaControls::playbackProgressed() {
444 m_timeline->setPosition(mediaElement().currentTime()); 461 m_timeline->setPosition(mediaElement().currentTime());
445 updateCurrentTimeDisplay(); 462 updateCurrentTimeDisplay();
446 463
447 if (shouldHideMediaControls()) 464 if (isVisible() && shouldHideMediaControls())
448 makeTransparent(); 465 makeTransparent();
449 } 466 }
450 467
451 void MediaControls::playbackStopped() { 468 void MediaControls::playbackStopped() {
452 updatePlayState(); 469 updatePlayState();
453 m_timeline->setPosition(mediaElement().currentTime()); 470 m_timeline->setPosition(mediaElement().currentTime());
454 updateCurrentTimeDisplay(); 471 updateCurrentTimeDisplay();
455 makeOpaque(); 472 makeOpaque();
456 473
457 stopHideMediaControlsTimer(); 474 stopHideMediaControlsTimer();
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 m_overlayCastButton->setIsPlayingRemotely(false); 650 m_overlayCastButton->setIsPlayingRemotely(false);
634 } 651 }
635 652
636 void MediaControls::defaultEventHandler(Event* event) { 653 void MediaControls::defaultEventHandler(Event* event) {
637 HTMLDivElement::defaultEventHandler(event); 654 HTMLDivElement::defaultEventHandler(event);
638 655
639 // Add IgnoreControlsHover to m_hideTimerBehaviorFlags when we see a touch 656 // Add IgnoreControlsHover to m_hideTimerBehaviorFlags when we see a touch
640 // event, to allow the hide-timer to do the right thing when it fires. 657 // event, to allow the hide-timer to do the right thing when it fires.
641 // FIXME: Preferably we would only do this when we're actually handling the 658 // FIXME: Preferably we would only do this when we're actually handling the
642 // event here ourselves. 659 // event here ourselves.
643 bool wasLastEventTouch = 660 bool isTouchEvent =
644 event->isTouchEvent() || event->isGestureEvent() || 661 event->isTouchEvent() || event->isGestureEvent() ||
645 (event->isMouseEvent() && toMouseEvent(event)->fromTouch()); 662 (event->isMouseEvent() && toMouseEvent(event)->fromTouch());
646 m_hideTimerBehaviorFlags |= 663 m_hideTimerBehaviorFlags |= isTouchEvent ? IgnoreControlsHover : IgnoreNone;
647 wasLastEventTouch ? IgnoreControlsHover : IgnoreNone; 664
665 // Touch events are treated differently to avoid fake mouse events to trigger
666 // random behavior. The expect behaviour for touch is that a tap will show the
667 // controls and they will hide when the timer to hide fires.
668 if (isTouchEvent) {
669 if (event->type() != EventTypeNames::gesturetap)
670 return;
671
672 if (!containsRelatedTarget(event)) {
673 if (!mediaElement().paused()) {
674 if (!isVisible()) {
675 makeOpaque();
676 // When the panel switches from invisible to visible, we need to mark
677 // the event handled to avoid buttons below the tap to be activated.
678 event->setDefaultHandled();
679 }
680 if (shouldHideMediaControls(IgnoreWaitForTimer)) {
681 m_keepShowingUntilTimerFires = true;
682 startHideMediaControlsTimer();
683 }
684 }
685 }
686
687 return;
688 }
648 689
649 if (event->type() == EventTypeNames::mouseover) { 690 if (event->type() == EventTypeNames::mouseover) {
650 if (!containsRelatedTarget(event)) { 691 if (!containsRelatedTarget(event)) {
651 m_isMouseOverControls = true; 692 m_isMouseOverControls = true;
652 if (!mediaElement().paused()) { 693 if (!mediaElement().paused()) {
653 makeOpaque(); 694 makeOpaque();
654 if (shouldHideMediaControls()) 695 if (shouldHideMediaControls())
655 startHideMediaControlsTimer(); 696 startHideMediaControlsTimer();
656 } 697 }
657 } 698 }
(...skipping 16 matching lines...) Expand all
674 if (shouldHideMediaControls(IgnoreVideoHover)) 715 if (shouldHideMediaControls(IgnoreVideoHover))
675 startHideMediaControlsTimer(); 716 startHideMediaControlsTimer();
676 return; 717 return;
677 } 718 }
678 } 719 }
679 720
680 void MediaControls::hideMediaControlsTimerFired(TimerBase*) { 721 void MediaControls::hideMediaControlsTimerFired(TimerBase*) {
681 unsigned behaviorFlags = 722 unsigned behaviorFlags =
682 m_hideTimerBehaviorFlags | IgnoreFocus | IgnoreVideoHover; 723 m_hideTimerBehaviorFlags | IgnoreFocus | IgnoreVideoHover;
683 m_hideTimerBehaviorFlags = IgnoreNone; 724 m_hideTimerBehaviorFlags = IgnoreNone;
725 m_keepShowingUntilTimerFires = false;
684 726
685 if (mediaElement().paused()) 727 if (mediaElement().paused())
686 return; 728 return;
687 729
688 if (!shouldHideMediaControls(behaviorFlags)) 730 if (!shouldHideMediaControls(behaviorFlags))
689 return; 731 return;
690 732
691 makeTransparent(); 733 makeTransparent();
692 m_overlayCastButton->setIsWanted(false); 734 m_overlayCastButton->setIsWanted(false);
693 } 735 }
694 736
695 void MediaControls::startHideMediaControlsTimer() { 737 void MediaControls::startHideMediaControlsTimer() {
696 m_hideMediaControlsTimer.startOneShot( 738 m_hideMediaControlsTimer.startOneShot(
697 timeWithoutMouseMovementBeforeHidingMediaControls, BLINK_FROM_HERE); 739 timeWithoutMouseMovementBeforeHidingMediaControls, BLINK_FROM_HERE);
698 } 740 }
699 741
700 void MediaControls::stopHideMediaControlsTimer() { 742 void MediaControls::stopHideMediaControlsTimer() {
743 m_keepShowingUntilTimerFires = false;
701 m_hideMediaControlsTimer.stop(); 744 m_hideMediaControlsTimer.stop();
702 } 745 }
703 746
704 void MediaControls::resetHideMediaControlsTimer() { 747 void MediaControls::resetHideMediaControlsTimer() {
705 stopHideMediaControlsTimer(); 748 stopHideMediaControlsTimer();
706 if (!mediaElement().paused()) 749 if (!mediaElement().paused())
707 startHideMediaControlsTimer(); 750 startHideMediaControlsTimer();
708 } 751 }
709 752
710 bool MediaControls::containsRelatedTarget(Event* event) { 753 bool MediaControls::containsRelatedTarget(Event* event) {
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
919 visitor->trace(m_textTrackList); 962 visitor->trace(m_textTrackList);
920 visitor->trace(m_overflowMenu); 963 visitor->trace(m_overflowMenu);
921 visitor->trace(m_overflowList); 964 visitor->trace(m_overflowList);
922 visitor->trace(m_castButton); 965 visitor->trace(m_castButton);
923 visitor->trace(m_overlayCastButton); 966 visitor->trace(m_overlayCastButton);
924 visitor->trace(m_windowEventListener); 967 visitor->trace(m_windowEventListener);
925 HTMLDivElement::trace(visitor); 968 HTMLDivElement::trace(visitor);
926 } 969 }
927 970
928 } // namespace blink 971 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/html/shadow/MediaControls.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698