mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 20:35:50 +00:00
Bug 979345 - Implement "touch-action: manipulation" CSS value for Pointer Events. r=kats, r=botond, r=dbaron, r=mbrubeck
This commit is contained in:
parent
6f58a1c0ad
commit
02188c0e1a
@ -32,8 +32,9 @@ enum AllowedTouchBehavior {
|
||||
NONE = 0,
|
||||
VERTICAL_PAN = 1 << 0,
|
||||
HORIZONTAL_PAN = 1 << 1,
|
||||
ZOOM = 1 << 2,
|
||||
UNKNOWN = 1 << 3
|
||||
PINCH_ZOOM = 1 << 2,
|
||||
DOUBLE_TAP_ZOOM = 1 << 3,
|
||||
UNKNOWN = 1 << 4
|
||||
};
|
||||
|
||||
class Layer;
|
||||
|
@ -233,7 +233,8 @@ typedef GeckoContentController::APZStateChange APZStateChange;
|
||||
*/
|
||||
static const uint32_t DefaultTouchBehavior = AllowedTouchBehavior::VERTICAL_PAN |
|
||||
AllowedTouchBehavior::HORIZONTAL_PAN |
|
||||
AllowedTouchBehavior::ZOOM;
|
||||
AllowedTouchBehavior::PINCH_ZOOM |
|
||||
AllowedTouchBehavior::DOUBLE_TAP_ZOOM;
|
||||
|
||||
/**
|
||||
* Angle from axis within which we stay axis-locked
|
||||
@ -781,7 +782,7 @@ nsEventStatus AsyncPanZoomController::OnTouchCancel(const MultiTouchInput& aEven
|
||||
nsEventStatus AsyncPanZoomController::OnScaleBegin(const PinchGestureInput& aEvent) {
|
||||
APZC_LOG("%p got a scale-begin in state %d\n", this, mState);
|
||||
|
||||
if (!TouchActionAllowZoom()) {
|
||||
if (!TouchActionAllowPinchZoom()) {
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
|
||||
@ -972,7 +973,7 @@ nsEventStatus AsyncPanZoomController::OnSingleTapUp(const TapGestureInput& aEven
|
||||
APZC_LOG("%p got a single-tap-up in state %d\n", this, mState);
|
||||
// If mZoomConstraints.mAllowDoubleTapZoom is true we wait for a call to OnSingleTapConfirmed before
|
||||
// sending event to content
|
||||
if (!mZoomConstraints.mAllowDoubleTapZoom) {
|
||||
if (!(mZoomConstraints.mAllowDoubleTapZoom && TouchActionAllowDoubleTapZoom())) {
|
||||
return GenerateSingleTap(aEvent.mPoint, aEvent.modifiers);
|
||||
}
|
||||
return nsEventStatus_eIgnore;
|
||||
@ -987,14 +988,13 @@ nsEventStatus AsyncPanZoomController::OnDoubleTap(const TapGestureInput& aEvent)
|
||||
APZC_LOG("%p got a double-tap in state %d\n", this, mState);
|
||||
nsRefPtr<GeckoContentController> controller = GetGeckoContentController();
|
||||
if (controller) {
|
||||
if (mZoomConstraints.mAllowDoubleTapZoom) {
|
||||
if (mZoomConstraints.mAllowDoubleTapZoom && TouchActionAllowDoubleTapZoom()) {
|
||||
int32_t modifiers = WidgetModifiersToDOMModifiers(aEvent.modifiers);
|
||||
CSSPoint geckoScreenPoint;
|
||||
if (ConvertToGecko(aEvent.mPoint, &geckoScreenPoint)) {
|
||||
controller->HandleDoubleTap(geckoScreenPoint, modifiers, GetGuid());
|
||||
}
|
||||
}
|
||||
|
||||
return nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
return nsEventStatus_eIgnore;
|
||||
@ -1961,19 +1961,29 @@ void AsyncPanZoomController::CheckContentResponse() {
|
||||
}
|
||||
}
|
||||
|
||||
bool AsyncPanZoomController::TouchActionAllowZoom() {
|
||||
bool AsyncPanZoomController::TouchActionAllowPinchZoom() {
|
||||
if (!mTouchActionPropertyEnabled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Pointer events specification implies all touch points to allow zoom
|
||||
// to perform it.
|
||||
for (size_t i = 0; i < mTouchBlockState.mAllowedTouchBehaviors.Length(); i++) {
|
||||
if (!(mTouchBlockState.mAllowedTouchBehaviors[i] & AllowedTouchBehavior::ZOOM)) {
|
||||
if (!(mTouchBlockState.mAllowedTouchBehaviors[i] & AllowedTouchBehavior::PINCH_ZOOM)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AsyncPanZoomController::TouchActionAllowDoubleTapZoom() {
|
||||
if (!mTouchActionPropertyEnabled) {
|
||||
return true;
|
||||
}
|
||||
for (size_t i = 0; i < mTouchBlockState.mAllowedTouchBehaviors.Length(); i++) {
|
||||
if (!(mTouchBlockState.mAllowedTouchBehaviors[i] & AllowedTouchBehavior::DOUBLE_TAP_ZOOM)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -595,9 +595,14 @@ private:
|
||||
};
|
||||
|
||||
/*
|
||||
* Returns whether current touch behavior values allow zooming.
|
||||
* Returns whether current touch behavior values allow pinch-zooming.
|
||||
*/
|
||||
bool TouchActionAllowZoom();
|
||||
bool TouchActionAllowPinchZoom();
|
||||
|
||||
/*
|
||||
* Returns whether current touch behavior values allow double-tap-zooming.
|
||||
*/
|
||||
bool TouchActionAllowDoubleTapZoom();
|
||||
|
||||
/*
|
||||
* Returns allowed touch behavior from the mAllowedTouchBehavior array.
|
||||
|
@ -415,7 +415,7 @@ TEST_F(AsyncPanZoomControllerTester, PinchWithTouchActionNone) {
|
||||
|
||||
nsTArray<uint32_t> values;
|
||||
values.AppendElement(mozilla::layers::AllowedTouchBehavior::VERTICAL_PAN);
|
||||
values.AppendElement(mozilla::layers::AllowedTouchBehavior::ZOOM);
|
||||
values.AppendElement(mozilla::layers::AllowedTouchBehavior::PINCH_ZOOM);
|
||||
apzc->SetTouchActionEnabled(true);
|
||||
|
||||
apzc->SetAllowedTouchBehavior(values);
|
||||
@ -906,7 +906,7 @@ TEST_F(AsyncPanZoomControllerTester, LongPress) {
|
||||
TEST_F(AsyncPanZoomControllerTester, LongPressWithTouchAction) {
|
||||
DoLongPressTest(true, mozilla::layers::AllowedTouchBehavior::HORIZONTAL_PAN
|
||||
| mozilla::layers::AllowedTouchBehavior::VERTICAL_PAN
|
||||
| mozilla::layers::AllowedTouchBehavior::ZOOM);
|
||||
| mozilla::layers::AllowedTouchBehavior::PINCH_ZOOM);
|
||||
}
|
||||
|
||||
TEST_F(AsyncPanZoomControllerTester, LongPressPreventDefault) {
|
||||
@ -916,7 +916,7 @@ TEST_F(AsyncPanZoomControllerTester, LongPressPreventDefault) {
|
||||
TEST_F(AsyncPanZoomControllerTester, LongPressPreventDefaultWithTouchAction) {
|
||||
DoLongPressPreventDefaultTest(true, mozilla::layers::AllowedTouchBehavior::HORIZONTAL_PAN
|
||||
| mozilla::layers::AllowedTouchBehavior::VERTICAL_PAN
|
||||
| mozilla::layers::AllowedTouchBehavior::ZOOM);
|
||||
| mozilla::layers::AllowedTouchBehavior::PINCH_ZOOM);
|
||||
}
|
||||
|
||||
// Layer tree for HitTesting1
|
||||
|
@ -372,6 +372,7 @@ CSS_KEY(lowercase, lowercase)
|
||||
CSS_KEY(ltr, ltr)
|
||||
CSS_KEY(luminance, luminance)
|
||||
CSS_KEY(luminosity, luminosity)
|
||||
CSS_KEY(manipulation, manipulation)
|
||||
CSS_KEY(manual, manual)
|
||||
CSS_KEY(margin-box, margin_box)
|
||||
CSS_KEY(markers, markers)
|
||||
|
@ -12405,8 +12405,10 @@ CSSParserImpl::ParseTextOverflow(nsCSSValue& aValue)
|
||||
bool
|
||||
CSSParserImpl::ParseTouchAction(nsCSSValue& aValue)
|
||||
{
|
||||
if (!ParseVariant(aValue, VARIANT_HK | VARIANT_NONE | VARIANT_AUTO,
|
||||
nsCSSProps::kTouchActionKTable)) {
|
||||
// Avaliable values of property touch-action:
|
||||
// auto | none | [pan-x || pan-y] | manipulation
|
||||
|
||||
if (!ParseVariant(aValue, VARIANT_HK, nsCSSProps::kTouchActionKTable)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -12426,6 +12428,13 @@ CSSParserImpl::ParseTouchAction(nsCSSValue& aValue)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Auto and None and Manipulation is not allowed in conjunction with others.
|
||||
if ((intValue | nextIntValue) & (NS_STYLE_TOUCH_ACTION_NONE |
|
||||
NS_STYLE_TOUCH_ACTION_AUTO |
|
||||
NS_STYLE_TOUCH_ACTION_MANIPULATION)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aValue.SetIntValue(nextIntValue | intValue, eCSSUnit_Enumerated);
|
||||
}
|
||||
|
||||
|
@ -1620,9 +1620,12 @@ const KTableValue nsCSSProps::kTextTransformKTable[] = {
|
||||
};
|
||||
|
||||
const KTableValue nsCSSProps::kTouchActionKTable[] = {
|
||||
eCSSKeyword_pan_x, NS_STYLE_TOUCH_ACTION_PAN_X,
|
||||
eCSSKeyword_pan_y, NS_STYLE_TOUCH_ACTION_PAN_Y,
|
||||
eCSSKeyword_UNKNOWN, -1
|
||||
eCSSKeyword_none, NS_STYLE_TOUCH_ACTION_NONE,
|
||||
eCSSKeyword_auto, NS_STYLE_TOUCH_ACTION_AUTO,
|
||||
eCSSKeyword_pan_x, NS_STYLE_TOUCH_ACTION_PAN_X,
|
||||
eCSSKeyword_pan_y, NS_STYLE_TOUCH_ACTION_PAN_Y,
|
||||
eCSSKeyword_manipulation, NS_STYLE_TOUCH_ACTION_MANIPULATION,
|
||||
eCSSKeyword_UNKNOWN, -1
|
||||
};
|
||||
|
||||
const KTableValue nsCSSProps::kTransitionTimingFunctionKTable[] = {
|
||||
|
@ -1048,8 +1048,8 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult,
|
||||
|
||||
case eCSSProperty_touch_action:
|
||||
nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
|
||||
NS_STYLE_TOUCH_ACTION_PAN_X,
|
||||
NS_STYLE_TOUCH_ACTION_PAN_Y,
|
||||
NS_STYLE_TOUCH_ACTION_NONE,
|
||||
NS_STYLE_TOUCH_ACTION_MANIPULATION,
|
||||
aResult);
|
||||
break;
|
||||
|
||||
|
@ -4063,20 +4063,14 @@ nsComputedDOMStyle::DoGetTouchAction()
|
||||
|
||||
int32_t intValue = StyleDisplay()->mTouchAction;
|
||||
|
||||
// None and Auto values aren't allowed to be in conjunction with
|
||||
// other values.
|
||||
if (NS_STYLE_TOUCH_ACTION_AUTO == intValue) {
|
||||
val->SetIdent(eCSSKeyword_auto);
|
||||
} else if (NS_STYLE_TOUCH_ACTION_NONE == intValue) {
|
||||
val->SetIdent(eCSSKeyword_none);
|
||||
} else {
|
||||
nsAutoString valueStr;
|
||||
nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_touch_action,
|
||||
intValue, NS_STYLE_TOUCH_ACTION_PAN_X,
|
||||
NS_STYLE_TOUCH_ACTION_PAN_Y, valueStr);
|
||||
val->SetString(valueStr);
|
||||
}
|
||||
|
||||
// None and Auto and Manipulation values aren't allowed
|
||||
// to be in conjunction with other values.
|
||||
// But there are all checks in CSSParserImpl::ParseTouchAction
|
||||
nsAutoString valueStr;
|
||||
nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_touch_action, intValue,
|
||||
NS_STYLE_TOUCH_ACTION_NONE, NS_STYLE_TOUCH_ACTION_MANIPULATION,
|
||||
valueStr);
|
||||
val->SetString(valueStr);
|
||||
return val;
|
||||
}
|
||||
|
||||
|
@ -779,6 +779,7 @@ static inline mozilla::css::Side operator++(mozilla::css::Side& side, int) {
|
||||
#define NS_STYLE_TOUCH_ACTION_AUTO (1 << 1)
|
||||
#define NS_STYLE_TOUCH_ACTION_PAN_X (1 << 2)
|
||||
#define NS_STYLE_TOUCH_ACTION_PAN_Y (1 << 3)
|
||||
#define NS_STYLE_TOUCH_ACTION_MANIPULATION (1 << 4)
|
||||
|
||||
// See nsStyleDisplay
|
||||
#define NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE 0
|
||||
|
@ -4373,10 +4373,17 @@ if (SpecialPowers.getBoolPref("layout.css.touch_action.enabled")) {
|
||||
inherited: false,
|
||||
type: CSS_TYPE_LONGHAND,
|
||||
initial_values: ["auto"],
|
||||
other_values: ["none", "pan-x", "pan-y", "pan-x pan-y", "pan-y pan-x"],
|
||||
other_values: ["none", "pan-x", "pan-y", "pan-x pan-y", "pan-y pan-x", "manipulation"],
|
||||
invalid_values: ["zoom", "pinch", "tap", "10px", "2", "auto pan-x", "pan-x auto", "none pan-x", "pan-x none",
|
||||
"auto pan-y", "pan-y auto", "none pan-y", "pan-y none",
|
||||
"pan-x pan-y none", "none pan-x pan-y", "pan-x pan-y auto", "auto pan-x pan-y"]
|
||||
"auto pan-y", "pan-y auto", "none pan-y", "pan-y none", "pan-x pan-x", "pan-y pan-y",
|
||||
"pan-x pan-y none", "pan-x none pan-y", "none pan-x pan-y", "pan-y pan-x none", "pan-y none pan-x", "none pan-y pan-x",
|
||||
"pan-x pan-y auto", "pan-x auto pan-y", "auto pan-x pan-y", "pan-y pan-x auto", "pan-y auto pan-x", "auto pan-y pan-x",
|
||||
"pan-x pan-y zoom", "pan-x zoom pan-y", "zoom pan-x pan-y", "pan-y pan-x zoom", "pan-y zoom pan-x", "zoom pan-y pan-x",
|
||||
"pan-x pan-y pan-x", "pan-x pan-x pan-y", "pan-y pan-x pan-x", "pan-y pan-x pan-y", "pan-y pan-y pan-x", "pan-x pan-y pan-y",
|
||||
"manipulation none", "none manipulation", "manipulation auto", "auto manipulation", "manipulation zoom", "zoom manipulation",
|
||||
"manipulation manipulation", "manipulation pan-x", "pan-x manipulation", "manipulation pan-y", "pan-y manipulation",
|
||||
"manipulation pan-x pan-y", "pan-x manipulation pan-y", "pan-x pan-y manipulation",
|
||||
"manipulation pan-y pan-x", "pan-y manipulation pan-x", "pan-y pan-x manipulation"]
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -35,9 +35,12 @@ void
|
||||
ContentHelper::UpdateAllowedBehavior(uint32_t aTouchActionValue, bool aConsiderPanning, TouchBehaviorFlags& aOutBehavior)
|
||||
{
|
||||
if (aTouchActionValue != NS_STYLE_TOUCH_ACTION_AUTO) {
|
||||
// Dropping zoom flag since zooming requires touch-action values of all touches
|
||||
// to be AUTO.
|
||||
aOutBehavior &= ~AllowedTouchBehavior::ZOOM;
|
||||
// Double-tap-zooming need property value AUTO
|
||||
aOutBehavior &= ~AllowedTouchBehavior::DOUBLE_TAP_ZOOM;
|
||||
if (aTouchActionValue != NS_STYLE_TOUCH_ACTION_MANIPULATION) {
|
||||
// Pinch-zooming need value AUTO or MANIPULATION
|
||||
aOutBehavior &= ~AllowedTouchBehavior::PINCH_ZOOM;
|
||||
}
|
||||
}
|
||||
|
||||
if (aConsiderPanning) {
|
||||
@ -86,7 +89,7 @@ ContentHelper::GetAllowedTouchBehavior(nsIWidget* aWidget, const nsIntPoint& aPo
|
||||
|
||||
bool considerPanning = true;
|
||||
TouchBehaviorFlags behavior = AllowedTouchBehavior::VERTICAL_PAN | AllowedTouchBehavior::HORIZONTAL_PAN |
|
||||
AllowedTouchBehavior::ZOOM;
|
||||
AllowedTouchBehavior::PINCH_ZOOM |
|
||||
|
||||
for (nsIFrame *frame = target; frame && frame->GetContent() && behavior; frame = frame->GetParent()) {
|
||||
UpdateAllowedBehavior(GetTouchActionFromFrame(frame), considerPanning, behavior);
|
||||
@ -102,4 +105,4 @@ ContentHelper::GetAllowedTouchBehavior(nsIWidget* aWidget, const nsIntPoint& aPo
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user