From 0f7623dd8322f0fd5ef6ee0e27e1295e11f276e6 Mon Sep 17 00:00:00 2001 From: circl Date: Tue, 2 Jul 2024 14:16:24 +0200 Subject: [PATCH] LibWeb+UI/Qt: Display 'title' tooltips only when the mouse stops moving Now instead of sending the position in which the user entered the tooltip area, send just the text, and let the chrome figure out how to display it. In the case of Qt, wait for 600 milliseconds of no mouse movement, then display it under the mouse cursor. --- Ladybird/AppKit/UI/LadybirdWebView.mm | 2 +- Ladybird/Qt/WebContentView.cpp | 26 +++++++++++++------ Ladybird/Qt/WebContentView.h | 4 +++ .../Libraries/LibWeb/Page/EventHandler.cpp | 2 +- Userland/Libraries/LibWeb/Page/Page.h | 2 +- .../LibWeb/Painting/MediaPaintable.cpp | 2 +- .../Libraries/LibWebView/ViewImplementation.h | 2 +- .../Libraries/LibWebView/WebContentClient.cpp | 4 +-- .../Libraries/LibWebView/WebContentClient.h | 2 +- Userland/Services/WebContent/PageClient.cpp | 5 ++-- Userland/Services/WebContent/PageClient.h | 2 +- .../Services/WebContent/WebContentClient.ipc | 2 +- 12 files changed, 34 insertions(+), 21 deletions(-) diff --git a/Ladybird/AppKit/UI/LadybirdWebView.mm b/Ladybird/AppKit/UI/LadybirdWebView.mm index 538230c95f..1f69875976 100644 --- a/Ladybird/AppKit/UI/LadybirdWebView.mm +++ b/Ladybird/AppKit/UI/LadybirdWebView.mm @@ -532,7 +532,7 @@ static void copy_data_to_clipboard(StringView data, NSPasteboardType pasteboard_ [self reload]; }; - m_web_view_bridge->on_enter_tooltip_area = [weak_self](auto, auto const& tooltip) { + m_web_view_bridge->on_enter_tooltip_area = [weak_self](auto const& tooltip) { LadybirdWebView* self = weak_self; if (self == nil) { return; diff --git a/Ladybird/Qt/WebContentView.cpp b/Ladybird/Qt/WebContentView.cpp index 739f445005..17b22c4338 100644 --- a/Ladybird/Qt/WebContentView.cpp +++ b/Ladybird/Qt/WebContentView.cpp @@ -79,6 +79,16 @@ WebContentView::WebContentView(QWidget* window, WebContentOptions const& web_con update_screen_rects(); }); + m_tooltip_hover_timer.setSingleShot(true); + + QObject::connect(&m_tooltip_hover_timer, &QTimer::timeout, [this] { + if (m_tooltip_text.has_value()) + QToolTip::showText( + QCursor::pos(), + qstring_from_ak_string(m_tooltip_text.value()), + this); + }); + initialize_client((parent_client == nullptr) ? CreateNewClient::Yes : CreateNewClient::No); on_ready_to_paint = [this]() { @@ -89,18 +99,14 @@ WebContentView::WebContentView(QWidget* window, WebContentOptions const& web_con update_cursor(cursor); }; - on_enter_tooltip_area = [this](auto position, auto const& tooltip) { - auto tooltip_without_carriage_return = tooltip.contains("\r"sv) + 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) : tooltip; - QToolTip::showText( - mapToGlobal(QPoint(position.x(), position.y())), - qstring_from_ak_string(tooltip_without_carriage_return), - this); }; - on_leave_tooltip_area = []() { - QToolTip::hideText(); + on_leave_tooltip_area = [this]() { + m_tooltip_text.clear(); }; on_finish_handling_key_event = [this](auto const& event) { @@ -326,6 +332,10 @@ void WebContentView::keyReleaseEvent(QKeyEvent* event) void WebContentView::mouseMoveEvent(QMouseEvent* event) { + if (QToolTip::isVisible()) + QToolTip::hideText(); + m_tooltip_hover_timer.start(600); + enqueue_native_event(Web::MouseEvent::Type::MouseMove, *event); } diff --git a/Ladybird/Qt/WebContentView.h b/Ladybird/Qt/WebContentView.h index cca4732f5d..29757fdf8a 100644 --- a/Ladybird/Qt/WebContentView.h +++ b/Ladybird/Qt/WebContentView.h @@ -23,6 +23,7 @@ #include #include #include +#include #include class QKeyEvent; @@ -103,6 +104,9 @@ private: void finish_handling_key_event(Web::KeyEvent const&); void update_screen_rects(); + Optional m_tooltip_text; + QTimer m_tooltip_hover_timer; + bool m_should_show_line_box_borders { false }; Gfx::IntSize m_viewport_size; diff --git a/Userland/Libraries/LibWeb/Page/EventHandler.cpp b/Userland/Libraries/LibWeb/Page/EventHandler.cpp index 1c342163ba..cad5ecdaff 100644 --- a/Userland/Libraries/LibWeb/Page/EventHandler.cpp +++ b/Userland/Libraries/LibWeb/Page/EventHandler.cpp @@ -567,7 +567,7 @@ bool EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSPixelPoi if (hovered_node_changed) { JS::GCPtr hovered_html_element = document.hovered_node() ? document.hovered_node()->enclosing_html_element_with_attribute(HTML::AttributeNames::title) : nullptr; if (hovered_html_element && hovered_html_element->title().has_value()) { - page.client().page_did_enter_tooltip_area(viewport_position, hovered_html_element->title()->to_byte_string()); + page.client().page_did_enter_tooltip_area(hovered_html_element->title()->to_byte_string()); } else { page.client().page_did_leave_tooltip_area(); } diff --git a/Userland/Libraries/LibWeb/Page/Page.h b/Userland/Libraries/LibWeb/Page/Page.h index ff5d98ac04..89b61bb0c2 100644 --- a/Userland/Libraries/LibWeb/Page/Page.h +++ b/Userland/Libraries/LibWeb/Page/Page.h @@ -328,7 +328,7 @@ 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_enter_tooltip_area(CSSPixelPoint, ByteString const&) { } + 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&) { } virtual void page_did_unhover_link() { } diff --git a/Userland/Libraries/LibWeb/Painting/MediaPaintable.cpp b/Userland/Libraries/LibWeb/Painting/MediaPaintable.cpp index 422bb0d7d6..d40168326a 100644 --- a/Userland/Libraries/LibWeb/Painting/MediaPaintable.cpp +++ b/Userland/Libraries/LibWeb/Painting/MediaPaintable.cpp @@ -351,7 +351,7 @@ MediaPaintable::DispatchEventOfSameName MediaPaintable::handle_mousemove(Badge(media_element.volume() * 100.0); - browsing_context().page().client().page_did_enter_tooltip_area(position, ByteString::formatted("{}%", volume)); + browsing_context().page().client().page_did_enter_tooltip_area(ByteString::formatted("{}%", volume)); } break; diff --git a/Userland/Libraries/LibWebView/ViewImplementation.h b/Userland/Libraries/LibWebView/ViewImplementation.h index aa1fe6367b..cf733a5497 100644 --- a/Userland/Libraries/LibWebView/ViewImplementation.h +++ b/Userland/Libraries/LibWebView/ViewImplementation.h @@ -163,7 +163,7 @@ public: Function on_refresh; Function on_favicon_change; Function on_cursor_change; - Function on_enter_tooltip_area; + Function on_enter_tooltip_area; Function on_leave_tooltip_area; Function on_request_alert; Function on_request_confirm; diff --git a/Userland/Libraries/LibWebView/WebContentClient.cpp b/Userland/Libraries/LibWebView/WebContentClient.cpp index fc11d0c5f0..dc9251911f 100644 --- a/Userland/Libraries/LibWebView/WebContentClient.cpp +++ b/Userland/Libraries/LibWebView/WebContentClient.cpp @@ -170,11 +170,11 @@ void WebContentClient::did_change_url(u64 page_id, URL::URL const& url) } } -void WebContentClient::did_enter_tooltip_area(u64 page_id, Gfx::IntPoint content_position, ByteString const& title) +void WebContentClient::did_enter_tooltip_area(u64 page_id, ByteString const& title) { if (auto view = view_for_page_id(page_id); view.has_value()) { if (view->on_enter_tooltip_area) - view->on_enter_tooltip_area(view->to_widget_position(content_position), title); + view->on_enter_tooltip_area(title); } } diff --git a/Userland/Libraries/LibWebView/WebContentClient.h b/Userland/Libraries/LibWebView/WebContentClient.h index 3a21c5b75a..fa204d4cb2 100644 --- a/Userland/Libraries/LibWebView/WebContentClient.h +++ b/Userland/Libraries/LibWebView/WebContentClient.h @@ -55,7 +55,7 @@ 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_enter_tooltip_area(u64 page_id, Gfx::IntPoint, ByteString const&) 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; virtual void did_unhover_link(u64 page_id) override; diff --git a/Userland/Services/WebContent/PageClient.cpp b/Userland/Services/WebContent/PageClient.cpp index a171f8cdc8..6bb2b4e42c 100644 --- a/Userland/Services/WebContent/PageClient.cpp +++ b/Userland/Services/WebContent/PageClient.cpp @@ -318,10 +318,9 @@ Gfx::IntRect PageClient::page_did_request_fullscreen_window() return client().did_request_fullscreen_window(m_id); } -void PageClient::page_did_enter_tooltip_area(Web::CSSPixelPoint content_position, ByteString const& title) +void PageClient::page_did_enter_tooltip_area(ByteString const& title) { - auto device_position = page().css_to_device_point(content_position); - client().async_did_enter_tooltip_area(m_id, { device_position.x(), device_position.y() }, title); + client().async_did_enter_tooltip_area(m_id, title); } void PageClient::page_did_leave_tooltip_area() diff --git a/Userland/Services/WebContent/PageClient.h b/Userland/Services/WebContent/PageClient.h index 141f1e23f4..7e40b083d5 100644 --- a/Userland/Services/WebContent/PageClient.h +++ b/Userland/Services/WebContent/PageClient.h @@ -119,7 +119,7 @@ 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_enter_tooltip_area(Web::CSSPixelPoint, ByteString const&) 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; virtual void page_did_unhover_link() override; diff --git a/Userland/Services/WebContent/WebContentClient.ipc b/Userland/Services/WebContent/WebContentClient.ipc index 3ec9d8ef7b..b1948d84ce 100644 --- a/Userland/Services/WebContent/WebContentClient.ipc +++ b/Userland/Services/WebContent/WebContentClient.ipc @@ -27,7 +27,7 @@ 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_enter_tooltip_area(u64 page_id, Gfx::IntPoint content_position, ByteString title) =| + 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) =| did_unhover_link(u64 page_id) =|