From 55b61724a0fef51ce463620a5e204313a3ec15e1 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Wed, 14 Jun 2023 15:35:20 -0400 Subject: [PATCH] LibWeb: Handle media elements being painted before their duration is set It can take some time to download / decode a media resource. During this time, its duration is set to NaN. The media control box would then have some odd rendering glitches as it tried to treat NaN as an actual time. Once we do have a duration, we also must ensure the media control box is updated. --- Userland/Libraries/LibWeb/HTML/HTMLMediaElement.cpp | 3 +++ Userland/Libraries/LibWeb/Painting/MediaPaintable.cpp | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.cpp index b8168dc04f..3f464e8e38 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.cpp @@ -303,6 +303,9 @@ void HTMLMediaElement::set_duration(double duration) } m_duration = duration; + + if (auto* layout_node = this->layout_node()) + layout_node->set_needs_display(); } WebIDL::ExceptionOr> HTMLMediaElement::play() diff --git a/Userland/Libraries/LibWeb/Painting/MediaPaintable.cpp b/Userland/Libraries/LibWeb/Painting/MediaPaintable.cpp index 73cc0ca95c..a3c99133c8 100644 --- a/Userland/Libraries/LibWeb/Painting/MediaPaintable.cpp +++ b/Userland/Libraries/LibWeb/Painting/MediaPaintable.cpp @@ -132,7 +132,7 @@ DevicePixelRect MediaPaintable::paint_control_bar_timeline(PaintContext& context timeline_rect.set_width(min(control_box_rect.width() * 6 / 10, timeline_rect.width())); media_element.cached_layout_boxes({}).timeline_rect = context.scale_to_css_rect(timeline_rect); - auto playback_percentage = media_element.current_time() / media_element.duration(); + auto playback_percentage = isnan(media_element.duration()) ? 0.0 : media_element.current_time() / media_element.duration(); auto playback_position = static_cast(static_cast(timeline_rect.width())) * playback_percentage; auto timeline_button_size = min(maximum_timeline_button_size, timeline_rect.height() / 2); @@ -166,7 +166,8 @@ DevicePixelRect MediaPaintable::paint_control_bar_timeline(PaintContext& context DevicePixelRect MediaPaintable::paint_control_bar_timestamp(PaintContext& context, HTML::HTMLMediaElement const& media_element, DevicePixelRect control_box_rect) const { auto current_time = human_readable_digital_time(round(media_element.current_time())); - auto duration = human_readable_digital_time(round(media_element.duration())); + auto duration = human_readable_digital_time(isnan(media_element.duration()) ? 0 : round(media_element.duration())); + auto timestamp = String::formatted("{} / {}", current_time, duration).release_value_but_fixme_should_propagate_errors(); auto const& scaled_font = layout_node().scaled_font(context);