# Hit Testing in Exo Hit testing is a concept in Graphics to determine which unit is a target for the input event based on location. Such as touch, click or swipe has a location and we specifies the target by locating the mouse cursor or finger upon the window or object you would like to trigger the event against. [WindowTargeter](https://source.chromium.org/chromium/chromium/src/+/main:ui/aura/window_targeter.h;l=29;drc=d83e99de89c0ccc6fee4ced1e450739b142d4b2c) is a class to identify the target window for an event. ## Even location conversion [WindowTargeter::EventLocationInsideBounds](https://source.chromium.org/chromium/chromium/src/+/main:ui/aura/window_targeter.cc;l=273;drc=d83e99de89c0ccc6fee4ced1e450739b142d4b2c) determins whether the event is inside this input region. If this returns true, [SubtreeShouldBeExploedForEvent](https://source.chromium.org/chromium/chromium/src/+/main:ui/aura/window_targeter.cc;l=31;drc=d83e99de89c0ccc6fee4ced1e450739b142d4b2c) can be true so that [FindTargetForLocatedEventRecursively](https://source.chromium.org/chromium/chromium/src/+/main:ui/aura/window_targeter.cc;l=320;drc=d83e99de89c0ccc6fee4ced1e450739b142d4b2c) continues to search deeper in the subtree. It calls [ConvertEventLocaltionToWindowCoordinates](https://source.chromium.org/chromium/chromium/src/+/main:ui/aura/window_targeter.cc;l=303;drc=d83e99de89c0ccc6fee4ced1e450739b142d4b2c) to convert the given `event.location()` into the parent window coordinates. ```cpp= Window::ConvertPointToTarget(window->parent(), window, &point); ``` [ConvertPointToTarget](https://source.chromium.org/chromium/chromium/src/+/main:ui/aura/window.cc;l=618;drc=d83e99de89c0ccc6fee4ced1e450739b142d4b2c) is a static method in aura::Window. It goes to [Layer::ConvertPointToLayer](https://source.chromium.org/chromium/chromium/src/+/main:ui/compositor/layer.cc;l=833;drc=d83e99de89c0ccc6fee4ced1e450739b142d4b2c) and transform by the scale if needed. The value must be int as a return value, so aura::Window get a floored scaled bounds. Inside [FindTargetForLocatedEventRecursively](https://source.chromium.org/chromium/chromium/src/+/main:ui/aura/window_targeter.cc;l=320;drc=d83e99de89c0ccc6fee4ced1e450739b142d4b2c) which is a implementation of FindTargettForEvent, [ConvertEventToTarget](https://source.chromium.org/chromium/chromium/src/+/main:ui/events/event_target.cc;l=19;drc=d83e99de89c0ccc6fee4ced1e450739b142d4b2c) updates the `location_` of the event to fit in `target` coordinates. This modifies the `event`. ## Exo custom window targeter Exo uses a custom window targeter extending [WindowTargeter](https://source.chromium.org/chromium/chromium/src/+/main:ui/aura/window_targeter.h;l=29;drc=d83e99de89c0ccc6fee4ced1e450739b142d4b2c). Surface, SurfaceTreeHost, ShellSurfaceBase has CustomWindowTargeter for each. All of them runs `surface->HitTest` inside [EventLocationInsideBounds](https://source.chromium.org/chromium/chromium/src/+/main:components/exo/surface_tree_host.cc;l=68;drc=d83e99de89c0ccc6fee4ced1e450739b142d4b2c) to check whether it is included in the region. [SurfaceTreeHost's CustomWindowTargeter](https://source.chromium.org/chromium/chromium/src/+/main:components/exo/surface_tree_host.cc;l=57;drc=d83e99de89c0ccc6fee4ced1e450739b142d4b2c) overrides EventLocationInsideBounds and FindTargetForEvent. If the passed `window` is not host window, we immediately fall back to WindowTargeter's methods. This class is used only when the passed `window` is the host window itself. Host window should not be the event target, so [FindTargetForEvent](https://source.chromium.org/chromium/chromium/src/+/main:components/exo/surface_tree_host.cc;l=84;drc=d83e99de89c0ccc6fee4ced1e450739b142d4b2c) returns null when the target is host window. [Surface's CustomWindowTargeter](https://source.chromium.org/chromium/chromium/src/+/main:components/exo/surface.cc;l=267;drc=d83e99de89c0ccc6fee4ced1e450739b142d4b2c) implements EventLocationInsideBounds. This converts `window` to `surface` and again uses HitTest. [ShellSurfaceBase's CustomWindowTargeter](https://source.chromium.org/chromium/chromium/src/+/main:components/exo/shell_surface_base.cc;l=206;drc=d83e99de89c0ccc6fee4ced1e450739b142d4b2c) checks the current window resizing state. If it's under resizing step, it handles the event specially. ## HitTest [HitTest](https://source.chromium.org/chromium/chromium/src/+/main:components/exo/surface.cc;l=1236;drc=d83e99de89c0ccc6fee4ced1e450739b142d4b2c) checks whether the given `point` is contained in `hit_test_region_`. [`hit_test_region_`](https://source.chromium.org/chromium/chromium/src/+/main:components/exo/surface.h;l=682;drc=d83e99de89c0ccc6fee4ced1e450739b142d4b2c) is [cc::Region](https://source.chromium.org/chromium/chromium/src/+/main:cc/base/region.h;l=31;drc=d83e99de89c0ccc6fee4ced1e450739b142d4b2c) and calculated inside [CommitSurfaceHierarchy](https://source.chromium.org/chromium/chromium/src/+/main:components/exo/surface.cc;l=969;drc=d83e99de89c0ccc6fee4ced1e450739b142d4b2c). First, check `state_.basic_state.input_region` value and use the intersection between `content_size_`. Then calculates the union of the region for children subsurfaces similarly to `surface_hierarchy_content_bounds_`.