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