1# Gesture Properties 2 3The Gestures library has many parameters which affect its operation. Examples 4include acceleration curves, whether to reverse the scroll direction, and 5thresholds for determining whether a touch is from a palm or a finger. 6 7These parameters are represented by gesture properties, values which can be 8changed by Chromium (though not always through the settings UI). This document 9describes the gesture properties system and how it can be used by developers. 10 11[TOC] 12 13## Property representation 14 15Each pointing device (touchpad, mouse, etc.) connected to a system has its own 16set of gesture properties. Properties are identified by human-readable names, 17such as "Scroll Accel Curve", "Mouse Reverse Scrolling", or "Palm Pressure". 18 19Each property has a type (integer, double, boolean, or string), and a size, 20which is the number of values of that type that it stores. (For strings, the 21size is always 1.) 22 23Chromium creates some read-only properties, which normally means that modifying 24them wouldn't make sense (for example, the "Device Vendor ID" property, which 25reflects a hardware ID). However, the Gestures library itself does not do this, 26so other clients don't need to support them. 27 28## Changing properties without recompiling 29 30All properties have default values which are set in source code. These are 31sometimes overridden by one of the configuration files in the [xorg-conf 32repository][xorg-conf] (normally to tune a touchpad or set the resolution for a 33mouse). However, since most of the time these are things you want to tweak many 34times or toggle quickly, it's easiest to change them using the Gesture 35Properties Service. 36 37[xorg-conf]: https://chromium.googlesource.com/chromiumos/platform/xorg-conf/ 38 39### Enabling the Gesture Properties Service 40 41First, enable the service by going to 42`chrome://flags/#gesture-properties-dbus-service` (which has to be typed or 43pasted into the address bar for security reasons), set the "Enable gesture 44properties service" flag to "Enabled", and restart Chromium. You should only 45have to do this once per Chromium profile. 46 47### From crosh 48 49Now that the service is enabled, you can change property values from `crosh`. To 50open it, press Ctrl+Alt+T. 51 52To determine the ID number of the input device you want to change properties 53for, run `gesture_prop devices` (or `gesture_prop devs` for short). Here's some 54example output: 55 56``` 57crosh> gesture_prop devices 58method return time=1576605764.119024 sender=:1.65 -> destination=:1.77 serial=330 reply_serial=2 59 uint32 1 60 array [ 61 dict entry( 62 int32 9 63 string "Atmel maXTouch Touchpad" 64 ) 65 ] 66``` 67 68In this case, there is one input device with gesture properties, the maXTouch 69Touchpad with ID 9. We can see all of the properties it supports with 70`gesture_prop list 9`: 71 72``` 73crosh> gesture_prop list 9 74method return time=1576606086.727507 sender=:1.65 -> destination=:1.81 serial=503 reply_serial=2 75 uint32 205 76 array [ 77 string "Two Finger Vertical Close Distance Thresh" 78 string "Two Finger Horizontal Close Distance Thresh" 79 string "Logging Notify" 80 string "Damp Scroll Min Move Factor" 81 string "No-Pinch Certain Ratio" 82 string "Merged Finger Suspicious Angle Min Displacement" 83 string "Merged Finger X Jump Min Disp" 84 string "Finger Merge Maximum Pressure" 85 string "Device Touchpad" 86 string "Merged Finger Max Age" 87 string "Mouse CPI" 88 ... 89 string "Australian Scrolling" 90 ... 91 ] 92``` 93 94Let's find the value of the "Australian Scrolling" property, which determines 95whether the scrolling direction is inverted: 96 97``` 98crosh> gesture_prop get 9 "Australian Scrolling" 99method return time=1576606330.909750 sender=:1.65 -> destination=:1.86 serial=574 reply_serial=2 100 boolean false 101 uint32 1 102 variant array [ 103 boolean true 104 ] 105``` 106 107The output tells us multiple things: 108 109* `boolean false` tells us that the property is not read-only; 110* `uint32 1` is the number of values this property has, in this case 1; and 111* the lines inside `variant array [` are the values of the property. 112 113At the moment, "Australian Scrolling" is true, meaning that scroll direction is 114inverted. If we move two fingers up on the pad, the content will scroll down. 115Let's change the value: 116 117``` 118crosh> gesture_prop set 9 "Australian Scrolling" array:boolean:false 119method return time=1576606314.847606 sender=:1.65 -> destination=:1.84 serial=566 reply_serial=2 120``` 121 122This should immediately take effect, meaning that moving two fingers up on the 123pad scrolls the content up. Unless you change it again, the value will remain 124the same until Chromium next restarts. 125 126#### Value syntax 127 128In the example above, we specified the value as `array:boolean:false`, which may 129seem rather obtuse for setting a simple flag. This is because all properties 130(except strings) are counted as arrays, hence the `array:` prefix, and we have 131to specify the type of value we're setting, in this case `boolean`. (The 132available types are `int32`, `double`, `boolean`, and `string`.) To specify 133multiple values, separate them by commas: 134 135``` 136crosh> gesture_prop set 9 "Some array property" array:int32:1,2,3,4 137``` 138 139This syntax is actually borrowed from the Linux `dbus-send` command, so see [its 140`man` page](https://dbus.freedesktop.org/doc/dbus-send.1.html#description) for a 141full description. 142 143### Over D-Bus 144 145On Chromebooks with developer mode enabled, it's also possible to use the 146service over D-Bus from your own program. This could be useful if you need to 147write more advanced tooling to change certain properties, such as the 148acceleration curves, which would be tedious to modify manually. See the 149`cmd_gesture_prop` function in the [`crosh` script][crosh] and the handlers in 150[`gesture_properties_service_provider.cc`][service-provider] as references for 151the D-Bus API. 152 153[crosh]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/HEAD:src/platform2/crosh/crosh?q=cmd_gesture_prop 154[service-provider]: https://source.chromium.org/chromium/chromium/src/+/HEAD:ash/dbus/gesture_properties_service_provider.cc 155 156## Pointer acceleration curves 157 158Perhaps the most important gesture properties are those that represent 159acceleration curves. These define how fast the mouse pointer moves in relation 160to the speed at which the user moves the mouse or their finger. While a default 161for each curve is compiled in to Chromium, a custom curve can be activated by 162setting a corresponding boolean property (e.g. "Use Custom Mouse Pointer Accel 163Curve"). 164 165(Note that mouse wheel scrolling curves are defined more simply, as a single 166polynomial with five terms, so they aren't covered here.) 167 168Acceleration curves are defined by up to 20 quadratic curve segments. Each curve 169segment has four parameters defining a quadratic, where *x* is the magnitude of 170the motion: 171 172* the maximum value of *x* for which this segment will be applied (default 173 infinity, called `x_` in code) 174* *a*, the *x²* multiplier (default 0, called `sqr_`) 175* *b*, the *x* multiplier (default 1, called `mul_`) 176* *c*, the constant (default 0, called `int_`) 177 178So, each quadratic (of the form *ax² + bx + c*) applies to values of 179*x* between the maximum value of the previous segment and its own maximum value. 180 181In the gesture properties, the four parameters from each curve segment are 182concatenated together into an array of 80 doubles. (These are then cast to 183[`struct CurveSegment`][struct-curvesegment]s by `AccelFilterInterpreter`.) 184 185Putting all of this together, we might change the mouse pointer acceleration 186"curve" into a straight line where *y = -x* (therefore inverting pointer 187movement) with the following commands: 188 189``` 190crosh> gesture_prop set 12 "Mouse Pointer Accel Curve" array:double:inf,0,-1,0,inf,0,-1,0,inf,0,-1,0,inf,0,-1,0,inf,0,-1,0,inf,0,-1,0,inf,0,-1,0,inf,0,-1,0,inf,0,-1,0,inf,0,-1,0,inf,0,-1,0,inf,0,-1,0,inf,0,-1,0,inf,0,-1,0,inf,0,-1,0,inf,0,-1,0,inf,0,-1,0,inf,0,-1,0,inf,0,-1,0,inf,0,-1,0 191crosh> gesture_prop set 12 "Use Custom Mouse Pointer Accel Curve" array:boolean:true 192``` 193 194(Of course, really only the first four values of the curve matter here, as the 195maximum *x* of the first segment is infinite.) 196 197[struct-curvesegment]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/HEAD:src/platform/gestures/include/accel_filter_interpreter.h?q=%22struct%20CurveSegment%22 198