diff options
author | Andreas Kling <kling@serenityos.org> | 2020-06-29 00:37:39 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-06-29 00:39:51 +0200 |
commit | 301ac3c7e5d99f32ac9a70b51844ad7ce8c9d563 (patch) | |
tree | 808e6411a27e207555ee57a598f75877db372d3a /Libraries | |
parent | 9177eea8fe2f6eb36a36422bfc2adbe3ad8785a5 (diff) | |
download | serenity-301ac3c7e5d99f32ac9a70b51844ad7ce8c9d563.zip |
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. :^)
Diffstat (limited to 'Libraries')
-rw-r--r-- | Libraries/LibWeb/Layout/LayoutBlock.cpp | 8 |
1 files 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<LayoutBlock>(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 }; } |