1# cc/input
2
3This directory contains code specific to input handling and scrolling in in the
4compositor.
5
6The renderer compositor typically receives, on the compositor thread, all input
7events arriving from the browser. In some cases, the compositor can process
8input without consulting the main thread. We strive for this since it means
9input doesn't have to block on a potentially busy main thread.
10
11If the compositor determines that Blink must be consulted to correctly handle
12the event. e.g. For detailed hit-testing or correct paint output. In these
13cases, the event will be posted to the Blink main thread.
14
15See [InputHandlerProxy](../../ui/events/blink/input_handler_proxy.cc) for the
16entry point to this code.
17
18## Scrolling
19
20### Viewport
21
22Viewport scrolling is special compared to scrolling regular ScrollNodes. The
23main difference is that the viewport is composed of two scrollers: the inner
24and outer scrollers. These correspond to the visual and layout viewports in
25Blink, respectively.
26
27The reason for this composition is pinch-zoom; when a user zooms in, the layout
28viewport remains unchanged (position: fixed elements don't stick to the user's
29screen) and the user can pan the visual viewport within the layout viewport.
30See [this demo](http://bokand.github.io/viewport/index.html) for a visual,
31interactive example.
32
33This arrangement requires some special distribution and bubbling of
34scroll delta. Additionally, viewport scrolling is also responsible for
35overscroll effects like rubber-banding and gestural-navigation as well as URL
36bar movement on Android.
37
38Notably, that the UI compositor as well as renderer compositors for
39out-of-process iframes will not have an inner or an outer viewport scroll node.
40
41#### Scroll Chain Structure
42
43The inner viewport scroll node is always the first and only child of the root
44scroll node; it is the top-level scrollable node in the scroll tree.  The outer
45viewport will typically be the one child of the inner viewport scroll node;
46however, this may be changed on certain pages. This happens when a page is
47given a non-document root scroller. For more information the root
48scroller see the
49[README](../../third_party/blink/renderer/core/page/scrolling/README.md) in
50Blink's core/page/scrolling directory.
51
52#### Scrolling the Viewport
53
54Viewport scroll nodes are typically not scrolled directly, like other scroll
55nodes. Instead, they're scrolled by using the cc::Viewport object. cc::Viewport
56is an object that's lives on the LayerTreeHostImpl and operates on the active
57tree's inner and outer scroll nodes. It encapsulates the bubbling,
58distribution, top controls, etc. behavior we associate with scrolling the
59viewport.
60
61We use the outer viewport scroll node to represent cc::Viewport scrolling in
62cases where the scroller must be represented by a scroll node (e.g.
63CurrentlyScrollingNode). In these cases we make sure to check for the outer
64scroll node use cc::Viewport instead. This means that in cases where we want
65"viewport" scrolling, we must use the outer viewport scroll node. This can also
66happen when the inner viewport is reached in the scroll chain, for example, by
67scroll bubbling from a `position: fixed` subtree; we use the outer scroll node
68to scroll this case.
69
70The scroll chain is terminated once we've scrolled the cc::Viewport. i.e.
71scrolls don't bubble above the cc::Viewport.
72
73#### Root Scroller Nuances
74
75When we have a non-document root scroller, there are cases where we
76specifically wish to scroll only the inner viewport.  For example, when a
77scroll started from a non-descendant of the root scroller or a `position:
78fixed` element and bubbles up. In these cases, we shouldn't scroll using
79cc::Viewport because that would scroll the root scroller as well. Doing so
80would create a difference in how scrolls chain based on which element is the
81root scroller, something we must avoid for interop and compatibility reasons.
82
83This means that when we reach the inner viewport scroll node in the scroll
84chain we need to know whether to use cc::Viewport or not. Blink sets the
85|prevent\_viewport\_scrolling\_from\_inner| bit on the inner viewport scroll
86node so that the compositor can know that scrolls bubbling to the inner
87viewport should not use the cc::Viewport class.
88
89## Other Docs
90
91* [Blink Scrolling](../../third_party/blink/renderer/core/page/scrolling/README.md)
92  provides information about similar concepts in Blink and the web-platform.
93
94## Glossary
95
96### Inner Viewport
97
98Also called the "Visual Viewport" in web/Blink terminology. This is the
99viewport the user actually sees and corresponds to the content visible in the
100browser window.
101
102### Outer Viewport
103
104Also called the "Layout Viewport" in web/Blink terminology. This is the main
105"content scroller" in a given page, typically the document (`<html>`) element.
106This is the scroller to which position: fixed elements remain fixed to.
107
108## Compositor threaded scrollbar scrolling
109Contact: arakeri@microsoft.com
110
111### Introduction
112Scrollbar scrolling using the mouse happens on the main thread in Chromium. If
113the main thread is busy (due to reasons like long running JS, etc), scrolling
114by clicking on the scrollbar will appear to be janky. To provide a better user
115experience, we have enabled off-main-thread scrollbar interaction for composited
116scrollers. This frees up the main thread to perform other tasks like processing
117javascript, etc. The core principal here is that MouseEvent(s) are converted to
118GestureEvent(s) and dispatched in a VSync aligned manner. Choosing this design
119also helps with the grand scrolling unification.
120
121### High-level design:
122
123![Image has moved. Contact arakeri@microsoft.com](https://github.com/rahul8805/CompositorThreadedScrollbarDocs/blob/master/designDiag.PNG?raw=true)
124
125### Core Implementation Details:
126This is the basic principle:
127- A new class called "cc::ScrollbarController" manages the state and behavior
128 related to translating Mouse events into GestureScrolls.
129- When a kMouseDown arrives at InputHandlerProxy::RouteToTypeSpecificHandler,
130 it gets passed to the ScrollbarController to determine if this event will cause
131 scrollbar manipulation.
132- The ScrollbarController returns enough data to the InputHandlerProxy to inject
133 gesture events to the CompositorThreadEventQueue (CTEQ). For example, in the
134 case of a mouse down, a GestureScrollBegin(GSB) and a GestureScrollUpdate(GSU)
135 are added to the CTEQ.
136- Depending on the action, there can be more synthetic GSUs that get added to
137 the CTEQ. (For eg: thumb drags).
138- The WebInputEvent::kMouseUp is responsible for cleaning up the scroll state.
139- GestureScrollBegin gets dispatched first. This sets up the scroll_node and
140 other state necessary to begin scrolling in LayerTreeHostImpl::ScrollBegin.
141 This is as usual for all gesture based scrolls.
142- GestureScrollUpdate(s) get handled next. Scroll deltas get applied to the node
143 that was set up during GestureScrollBegin. Depending on the type of scroll,
144 this may lead to an animated scroll (eg: LayerTreeHostImpl::ScrollAnimated for
145 autoscroll/mouse clicks) or a regular scroll. (eg: LayerTreeHostImpl::ScrollBy
146 for thumb drags)
147- Finally, the GestureScrollEnd is dispatched and it clears the scrolling state
148 (like the CurrentlyScrollingNode) and calls SetNeedsCommitOnImplThread().
149
150### Miscellaneous resources.
151- [Demo page](https://rahul8805.github.io/DemoPages/BouncyMoon.html)
152- [Lightning talk](https://www.youtube.com/watch?v=FOCHCuGA_MA&t=1150s)
153- [input-dev thread](https://groups.google.com/a/chromium.org/forum/#!topic/input-dev/6ACOSDoAik4)
154- [Full design doc](https://docs.google.com/document/d/1JqykSXnCkqwA1E3bUhhIi-IgEvM9HZdKtIu_S4Ncm6o/edit#heading=h.agf18oiankjh)
155