summaryrefslogtreecommitdiff
path: root/Libraries/LibWeb/Layout/LayoutBlock.cpp
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-06-29 00:37:39 +0200
committerAndreas Kling <kling@serenityos.org>2020-06-29 00:39:51 +0200
commit301ac3c7e5d99f32ac9a70b51844ad7ce8c9d563 (patch)
tree808e6411a27e207555ee57a598f75877db372d3a /Libraries/LibWeb/Layout/LayoutBlock.cpp
parent9177eea8fe2f6eb36a36422bfc2adbe3ad8785a5 (diff)
downloadserenity-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/LibWeb/Layout/LayoutBlock.cpp')
-rw-r--r--Libraries/LibWeb/Layout/LayoutBlock.cpp8
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 };
}