From 301ac3c7e5d99f32ac9a70b51844ad7ce8c9d563 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 29 Jun 2020 00:37:39 +0200 Subject: [PATCH] LibWeb: Improve hit testing on the right of line boxes We now remember the last candidate fragment when hit testing past the right end of text and use that as the fallback result if nothing else matches. This makes it possible to drag-select outside the line boxes in a way that feels mostly natural. :^) --- Libraries/LibWeb/Layout/LayoutBlock.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Libraries/LibWeb/Layout/LayoutBlock.cpp b/Libraries/LibWeb/Layout/LayoutBlock.cpp index 264e37fcae..a043f3c216 100644 --- a/Libraries/LibWeb/Layout/LayoutBlock.cpp +++ b/Libraries/LibWeb/Layout/LayoutBlock.cpp @@ -722,7 +722,7 @@ HitTestResult LayoutBlock::hit_test(const Gfx::IntPoint& position) const if (!children_are_inline()) return LayoutBox::hit_test(position); - HitTestResult result; + HitTestResult last_good_candidate; for (auto& line_box : m_line_boxes) { for (auto& fragment : line_box.fragments()) { if (enclosing_int_rect(fragment.absolute_rect()).contains(position)) { @@ -730,11 +730,13 @@ HitTestResult LayoutBlock::hit_test(const Gfx::IntPoint& position) const return to(fragment.layout_node()).hit_test(position); return { fragment.layout_node(), fragment.text_index_at(position.x()) }; } + if (fragment.absolute_rect().top() <= position.y()) + last_good_candidate = { fragment.layout_node(), fragment.text_index_at(position.x()) }; } } - // FIXME: This should be smarter about the text position if we're hitting a block - // that has text inside it, but `position` is to the right of the text box. + if (last_good_candidate.layout_node) + return last_good_candidate; return { absolute_rect().contains(position.x(), position.y()) ? this : nullptr }; }