From a3f4fd40a123767add35160b93046e358d4f9c64 Mon Sep 17 00:00:00 2001 From: Theodore Abshire Date: Mon, 23 Feb 2026 03:00:08 -0800 Subject: [PATCH] fix(UI): Prevent hidden seek button from interfering with double-tap (#9748) The hidden seek button has custom behavior that causes it to attempt to "delay" touch events on it, to wait to see if they are a double-tap or not. This interacted with the double click to fullscreen behavior unfortunately; a single touch was registered, then it was registered again 500ms later, causing it to be detected as a double-tap by the controls container. This PR changes the hidden seek button to ignore `touchend` events that happen while the controls are transparent, and changes the initial `touchend` event on the hidden seek button to not propagate down, thus preventing the doubling behavior without introducing any lag on the controls appearing. Fixes #9705 --- ui/controls.js | 8 ++++---- ui/hidden_seek_button.js | 11 ++++++++++- ui/overflow_menu.js | 7 ------- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/ui/controls.js b/ui/controls.js index 03bf6d1cd..f1377ea08 100644 --- a/ui/controls.js +++ b/ui/controls.js @@ -11,6 +11,7 @@ goog.provide('shaka.ui.ControlsPanel'); goog.require('goog.asserts'); goog.require('shaka.ads.Utils'); goog.require('shaka.cast.CastProxy'); +goog.require('shaka.Deprecate'); goog.require('shaka.device.DeviceFactory'); goog.require('shaka.device.IDevice'); goog.require('shaka.log'); @@ -881,10 +882,9 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget { * @export */ setLastTouchEventTime(time, container) { - this.lastTouchEventTime_ = time; - if (container) { - this.lastContainerTouchEventTime_ = time; - } + shaka.Deprecate.deprecateFeature(6, + 'setLastTouchEventTime', + 'This method is no longer used.'); } /** diff --git a/ui/hidden_seek_button.js b/ui/hidden_seek_button.js index c350f3010..ac89600a3 100644 --- a/ui/hidden_seek_button.js +++ b/ui/hidden_seek_button.js @@ -93,7 +93,6 @@ shaka.ui.HiddenSeekButton = class extends shaka.ui.Element { this.eventManager.listen(this.seekContainer, 'touchend', (e) => { const event = /** @type {!TouchEvent} */(e); this.onTouchEnd_(event); - this.controls.setLastTouchEventTime(Date.now(), /* container= */ true); }); } @@ -139,6 +138,14 @@ shaka.ui.HiddenSeekButton = class extends shaka.ui.Element { * @private */ onTouchEnd_(event) { + // Ignore this event if the controls are transparent. + // Double-tapping the hidden seek button when the controls are hidden + // should cause the player to go fullscreen, not cause it to + // rewind/fast-forward. + if (!this.controls.isOpaque()) { + return; + } + // If user scrolled, don't handle as a tap. if (this.hasMoved_) { return; @@ -148,6 +155,7 @@ shaka.ui.HiddenSeekButton = class extends shaka.ui.Element { // play/seek. if (this.controls.anySettingsMenusAreOpen()) { event.preventDefault(); + event.stopPropagation(); this.controls.hideSettingsMenus(); return; } @@ -156,6 +164,7 @@ shaka.ui.HiddenSeekButton = class extends shaka.ui.Element { if (this.controls.getConfig().tapSeekDistance > 0 && (!this.ad || !this.ad.isLinear())) { event.preventDefault(); + event.stopPropagation(); this.onSeekButtonClick_(); } } diff --git a/ui/overflow_menu.js b/ui/overflow_menu.js index 2407fcf0d..e8cfe8dce 100644 --- a/ui/overflow_menu.js +++ b/ui/overflow_menu.js @@ -75,13 +75,6 @@ shaka.ui.OverflowMenu = class extends shaka.ui.Element { shaka.ui.Utils.setDisplay(this.overflowMenuButton_, true); }); - this.eventManager.listen( - this.overflowMenu_, 'touchstart', (event) => { - this.controls.setLastTouchEventTime( - Date.now(), /* container= */ false); - event.stopPropagation(); - }); - this.eventManager.listen(this.overflowMenuButton_, 'click', () => { if (!this.controls.isOpaque()) { return;