Currently, every MacViews window has one large tracking area for the entire window, created by BridgedContentView, and all mouse events flow through the Widget to be dispatched. This provides really inefficient behavior in a lot of circumstances - for example, a large Widget with most of the space not filled by Views receives a lot of MouseMoved events that will not be passed to any View.
A sketch for how this should work instead:
1) Each View gets an associated NSTrackingArea if needed*
2) Each tracking area is configured to listen only for events that View cares to receive*
3) If the tracking area receives an event (note: NSTrackingAreas can only track MouseEntered, MouseExited, and MouseMoved), it sends that event directly to its associated View, NOT to the Widget for dispatch
The asterisk implies another design change or configuration option: right now, there's no way to tell whether a View "wants" a specific kind of event, since events are received by inheritance. There's no way to check whether a subclass of View has overridden, e.g., OnMouseMoved(). Therefore, we'll probably need a new API method like:
virtual bool View::WantsEventsOfType(int type) const;
which will be used when setting up tracking areas for Views on Mac. Almost all Views *don't* want MouseMoved, so MacViews will receive a lot less events. Preliminary experiments with the WIP CL linked above show that the number of events received per second while moving the mouse around the browser UI falls from hundreds per second to tens per second.
So, design in steps:
1) Add View::WantsEventsOfType(), implement it for common base classes (button, label, menu, ...). Danger: if unknown subclasses of these classes *do* want these events, they'll break. There's no easy way to detect this other than checking manually for overrides of OnMouse*().
2) Add a platform-specific View helper class (PlatformViewDelegate in the WIP CL) and have one created for each View.
3) Add the tracking rect thing described above - make sure to deal with movement of Views. The WIP CL does this. Don't yet have these tracking rects actually dispatch events. Don't create tracking rects for views that don't want any mouse movement events.
4) Have BridgedContentView *not* pass on mouse movements in [BridgedContentView mouseEvent:], and instead have the tracking rects dispatch these events to their target views.
5) Remove BridgedContentView's tracking rect.
This might break a lot of tests.
Comment 1 by ellyjo...@chromium.org
, Apr 27 2018