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:
parent
370d3749e5
commit
4133caba78
6 changed files with 91 additions and 45 deletions
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue