浏览代码

LibWeb+UI: Add tooltip overriding and use it for <video> tags

This call is used to inform the chrome that it should display a tooltip
now and avoid any hovering timers. This is used by <video> tags to
display the volume percentage when it is changed.
circl 1 年之前
父节点
当前提交
ceb9c3b797

+ 16 - 0
Ladybird/AppKit/UI/LadybirdWebView.mm

@@ -532,6 +532,22 @@ static void copy_data_to_clipboard(StringView data, NSPasteboardType pasteboard_
         [self reload];
     };
 
+    m_web_view_bridge->on_request_tooltip_override = [weak_self](auto, auto const& tooltip) {
+        LadybirdWebView* self = weak_self;
+        if (self == nil) {
+            return;
+        }
+        self.toolTip = Ladybird::string_to_ns_string(tooltip);
+    };
+
+    m_web_view_bridge->on_stop_tooltip_override = [weak_self]() {
+        LadybirdWebView* self = weak_self;
+        if (self == nil) {
+            return;
+        }
+        self.toolTip = nil;
+    };
+
     m_web_view_bridge->on_enter_tooltip_area = [weak_self](auto const& tooltip) {
         LadybirdWebView* self = weak_self;
         if (self == nil) {

+ 23 - 3
Ladybird/Qt/WebContentView.cpp

@@ -99,6 +99,24 @@ WebContentView::WebContentView(QWidget* window, WebContentOptions const& web_con
         update_cursor(cursor);
     };
 
+    on_request_tooltip_override = [this](auto position, auto const& tooltip) {
+        m_tooltip_override = true;
+        if (m_tooltip_hover_timer.isActive())
+            m_tooltip_hover_timer.stop();
+
+        auto tooltip_without_carriage_return = tooltip.contains("\r"sv)
+            ? tooltip.replace("\r\n"sv, "\n"sv, ReplaceMode::All).replace("\r"sv, "\n"sv, ReplaceMode::All)
+            : tooltip;
+        QToolTip::showText(
+            mapToGlobal(QPoint(position.x(), position.y())),
+            qstring_from_ak_string(tooltip_without_carriage_return),
+            this);
+    };
+
+    on_stop_tooltip_override = [this]() {
+        m_tooltip_override = false;
+    };
+
     on_enter_tooltip_area = [this](auto const& tooltip) {
         m_tooltip_text = tooltip.contains("\r"sv)
             ? tooltip.replace("\r\n"sv, "\n"sv, ReplaceMode::All).replace("\r"sv, "\n"sv, ReplaceMode::All)
@@ -332,9 +350,11 @@ void WebContentView::keyReleaseEvent(QKeyEvent* event)
 
 void WebContentView::mouseMoveEvent(QMouseEvent* event)
 {
-    if (QToolTip::isVisible())
-        QToolTip::hideText();
-    m_tooltip_hover_timer.start(600);
+    if (!m_tooltip_override) {
+        if (QToolTip::isVisible())
+            QToolTip::hideText();
+        m_tooltip_hover_timer.start(600);
+    }
 
     enqueue_native_event(Web::MouseEvent::Type::MouseMove, *event);
 }

+ 1 - 0
Ladybird/Qt/WebContentView.h

@@ -104,6 +104,7 @@ private:
     void finish_handling_key_event(Web::KeyEvent const&);
     void update_screen_rects();
 
+    bool m_tooltip_override { false };
     Optional<ByteString> m_tooltip_text;
     QTimer m_tooltip_hover_timer;
 

+ 2 - 0
Userland/Libraries/LibWeb/Page/Page.h

@@ -328,6 +328,8 @@ public:
     virtual void page_did_request_image_context_menu(CSSPixelPoint, URL::URL const&, [[maybe_unused]] ByteString const& target, [[maybe_unused]] unsigned modifiers, Gfx::Bitmap const*) { }
     virtual void page_did_request_media_context_menu(CSSPixelPoint, [[maybe_unused]] ByteString const& target, [[maybe_unused]] unsigned modifiers, Page::MediaContextMenu) { }
     virtual void page_did_middle_click_link(URL::URL const&, [[maybe_unused]] ByteString const& target, [[maybe_unused]] unsigned modifiers) { }
+    virtual void page_did_request_tooltip_override(CSSPixelPoint, ByteString const&) { }
+    virtual void page_did_stop_tooltip_override() { }
     virtual void page_did_enter_tooltip_area(ByteString const&) { }
     virtual void page_did_leave_tooltip_area() { }
     virtual void page_did_hover_link(URL::URL const&) { }

+ 2 - 2
Userland/Libraries/LibWeb/Painting/MediaPaintable.cpp

@@ -302,7 +302,7 @@ MediaPaintable::DispatchEventOfSameName MediaPaintable::handle_mouseup(Badge<Eve
             break;
 
         case HTML::HTMLMediaElement::MouseTrackingComponent::Volume:
-            browsing_context().page().client().page_did_leave_tooltip_area();
+            browsing_context().page().client().page_did_stop_tooltip_override();
             break;
         }
 
@@ -351,7 +351,7 @@ MediaPaintable::DispatchEventOfSameName MediaPaintable::handle_mousemove(Badge<E
                 set_volume(media_element, *cached_layout_boxes.volume_scrub_rect, position);
 
                 auto volume = static_cast<u8>(media_element.volume() * 100.0);
-                browsing_context().page().client().page_did_enter_tooltip_area(ByteString::formatted("{}%", volume));
+                browsing_context().page().client().page_did_request_tooltip_override({ position.x(), cached_layout_boxes.volume_scrub_rect->y() }, ByteString::formatted("{}%", volume));
             }
 
             break;

+ 2 - 0
Userland/Libraries/LibWebView/ViewImplementation.h

@@ -163,6 +163,8 @@ public:
     Function<void()> on_refresh;
     Function<void(Gfx::Bitmap const&)> on_favicon_change;
     Function<void(Gfx::StandardCursor)> on_cursor_change;
+    Function<void(Gfx::IntPoint, ByteString const&)> on_request_tooltip_override;
+    Function<void()> on_stop_tooltip_override;
     Function<void(ByteString const&)> on_enter_tooltip_area;
     Function<void()> on_leave_tooltip_area;
     Function<void(String const& message)> on_request_alert;

+ 16 - 0
Userland/Libraries/LibWebView/WebContentClient.cpp

@@ -170,6 +170,22 @@ void WebContentClient::did_change_url(u64 page_id, URL::URL const& url)
     }
 }
 
+void WebContentClient::did_request_tooltip_override(u64 page_id, Gfx::IntPoint position, ByteString const& title)
+{
+    if (auto view = view_for_page_id(page_id); view.has_value()) {
+        if (view->on_request_tooltip_override)
+            view->on_request_tooltip_override(view->to_widget_position(position), title);
+    }
+}
+
+void WebContentClient::did_stop_tooltip_override(u64 page_id)
+{
+    if (auto view = view_for_page_id(page_id); view.has_value()) {
+        if (view->on_stop_tooltip_override)
+            view->on_stop_tooltip_override();
+    }
+}
+
 void WebContentClient::did_enter_tooltip_area(u64 page_id, ByteString const& title)
 {
     if (auto view = view_for_page_id(page_id); view.has_value()) {

+ 2 - 0
Userland/Libraries/LibWebView/WebContentClient.h

@@ -55,6 +55,8 @@ private:
     virtual void did_layout(u64 page_id, Gfx::IntSize) override;
     virtual void did_change_title(u64 page_id, ByteString const&) override;
     virtual void did_change_url(u64 page_id, URL::URL const&) override;
+    virtual void did_request_tooltip_override(u64 page_id, Gfx::IntPoint, ByteString const&) override;
+    virtual void did_stop_tooltip_override(u64 page_id) override;
     virtual void did_enter_tooltip_area(u64 page_id, ByteString const&) override;
     virtual void did_leave_tooltip_area(u64 page_id) override;
     virtual void did_hover_link(u64 page_id, URL::URL const&) override;

+ 11 - 0
Userland/Services/WebContent/PageClient.cpp

@@ -318,6 +318,17 @@ Gfx::IntRect PageClient::page_did_request_fullscreen_window()
     return client().did_request_fullscreen_window(m_id);
 }
 
+void PageClient::page_did_request_tooltip_override(Web::CSSPixelPoint position, ByteString const& title)
+{
+    auto device_position = page().css_to_device_point(position);
+    client().async_did_request_tooltip_override(m_id, { device_position.x(), device_position.y() }, title);
+}
+
+void PageClient::page_did_stop_tooltip_override()
+{
+    client().async_did_leave_tooltip_area(m_id);
+}
+
 void PageClient::page_did_enter_tooltip_area(ByteString const& title)
 {
     client().async_did_enter_tooltip_area(m_id, title);

+ 2 - 0
Userland/Services/WebContent/PageClient.h

@@ -119,6 +119,8 @@ private:
     virtual Gfx::IntRect page_did_request_maximize_window() override;
     virtual Gfx::IntRect page_did_request_minimize_window() override;
     virtual Gfx::IntRect page_did_request_fullscreen_window() override;
+    virtual void page_did_request_tooltip_override(Web::CSSPixelPoint, ByteString const&) override;
+    virtual void page_did_stop_tooltip_override() override;
     virtual void page_did_enter_tooltip_area(ByteString const&) override;
     virtual void page_did_leave_tooltip_area() override;
     virtual void page_did_hover_link(URL::URL const&) override;

+ 2 - 0
Userland/Services/WebContent/WebContentClient.ipc

@@ -27,6 +27,8 @@ endpoint WebContentClient
     did_layout(u64 page_id, Gfx::IntSize content_size) =|
     did_change_title(u64 page_id, ByteString title) =|
     did_change_url(u64 page_id, URL::URL url) =|
+    did_request_tooltip_override(u64 page_id, Gfx::IntPoint position, ByteString title) =|
+    did_stop_tooltip_override(u64 page_id) =|
     did_enter_tooltip_area(u64 page_id, ByteString title) =|
     did_leave_tooltip_area(u64 page_id) =|
     did_hover_link(u64 page_id, URL::URL url) =|