1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 14:57:35 +00:00

WindowServer: Make hit test results richer

Instead of just answering hit/no-hit when hit testing windows, we now
return a HitTestResult object which tells you which window was hit,
where it was hit, and whether you hit the frame or the content.
This commit is contained in:
Andreas Kling 2021-06-18 00:47:38 +02:00
parent 370d3749e5
commit 4133caba78
6 changed files with 91 additions and 45 deletions

View file

@ -953,25 +953,36 @@ bool Window::is_descendant_of(Window& window) const
return false;
}
bool Window::hit_test(const Gfx::IntPoint& point, bool include_frame) const
Optional<HitTestResult> Window::hit_test(Gfx::IntPoint const& position, bool include_frame) const
{
if (!frame().rect().contains(point))
return false;
if (!rect().contains(point)) {
if (include_frame)
return frame().hit_test(point);
return false;
}
if (!m_hit_testing_enabled)
return false;
return {};
if (!frame().rect().contains(position))
return {};
if (!rect().contains(position)) {
if (include_frame)
return frame().hit_test(position);
return {};
}
bool hit = false;
u8 threshold = alpha_hit_threshold() * 255;
if (threshold == 0 || !m_backing_store || !m_backing_store->has_alpha_channel())
return true;
auto relative_point = point.translated(-rect().location()) * m_backing_store->scale();
u8 alpha = 0xff;
if (m_backing_store->rect().contains(relative_point))
alpha = m_backing_store->get_pixel(relative_point).alpha();
return alpha >= threshold;
if (threshold == 0 || !m_backing_store || !m_backing_store->has_alpha_channel()) {
hit = true;
} else {
auto relative_point = position.translated(-rect().location()) * m_backing_store->scale();
u8 alpha = 0xff;
if (m_backing_store->rect().contains(relative_point))
alpha = m_backing_store->get_pixel(relative_point).alpha();
hit = alpha >= threshold;
}
if (!hit)
return {};
return HitTestResult {
.window = *this,
.screen_position = position,
.window_relative_position = position.translated(-rect().location()),
.is_frame_hit = false,
};
}
void Window::set_menubar(Menubar* menubar)