Commit 758b1155 authored by mustaq's avatar mustaq Committed by Commit bot

Make a pen in eraser mode visible thru PointerEvent.buttons

The PointerEvent spec can't gracefully support a hovering pen in eraser
mode because a non-zero |buttons| field indicate an active buttons
state. The issue is currently being discussed in github:
  https://github.com/w3c/pointerevents/issues/134

Until the spec gets fixed, this CL exposes the eraser mode in a
spec-compliant way by hiding the eraser mode until the pen touches the
digitizer. Edge shows the same behavior.

This CL also adds X1, X2 & Eraser button/buttons values to
WebPointerProperties.

BUG=642455

Review-Url: https://codereview.chromium.org/2296303002
Cr-Commit-Position: refs/heads/master@{#416360}
parent eef1d9c8
......@@ -63,10 +63,11 @@ namespace test_runner {
namespace {
const int kRawMousePointerId = -1;
const char* kPointerTypeStringUnknown = "";
const char* kPointerTypeStringMouse = "mouse";
const char* kPointerTypeStringPen = "pen";
const char* kPointerTypeStringTouch = "touch";
const char* const kPointerTypeStringUnknown = "";
const char* const kPointerTypeStringMouse = "mouse";
const char* const kPointerTypeStringTouch = "touch";
const char* const kPointerTypeStringPen = "pen";
const char* const kPointerTypeStringEraser = "eraser";
// Assigns |pointerType| from the provided |args|. Returns false if there was
// any error.
......@@ -90,10 +91,12 @@ bool getPointerType(gin::Arguments* args,
pointerType = WebMouseEvent::PointerType::Unknown;
} else if (pointer_type_string == kPointerTypeStringMouse) {
pointerType = WebMouseEvent::PointerType::Mouse;
} else if (pointer_type_string == kPointerTypeStringPen) {
pointerType = WebMouseEvent::PointerType::Pen;
} else if (pointer_type_string == kPointerTypeStringTouch) {
pointerType = WebMouseEvent::PointerType::Touch;
} else if (pointer_type_string == kPointerTypeStringPen) {
pointerType = WebMouseEvent::PointerType::Pen;
} else if (pointer_type_string == kPointerTypeStringEraser) {
pointerType = WebMouseEvent::PointerType::Eraser;
} else {
args->ThrowError();
return false;
......@@ -175,6 +178,10 @@ int GetWebMouseEventModifierForButton(WebMouseEvent::Button button) {
return WebMouseEvent::MiddleButtonDown;
case WebMouseEvent::Button::Right:
return WebMouseEvent::RightButtonDown;
case WebPointerProperties::Button::X1:
case WebPointerProperties::Button::X2:
case WebPointerProperties::Button::Eraser:
return 0; // Not implemented yet
}
NOTREACHED();
return 0;
......
......@@ -20,6 +20,8 @@ description("Verifies that pointer event parameters are correct when fired throu
var checkKeyModifiers = false;
var inputPointerType = "";
var pointerType = "";
var penId = 0;
var penPressure = 0;
......@@ -54,6 +56,33 @@ var numericAttributes = [
"height",
];
function getExpectedNumericAttributeValueForPE(mouseEvent, attribute) {
var expectedValue = eval("mouseEvent." + attribute);
// Fix expectedValue for the cases where PE & ME differs
if (attribute == "button") {
if (mouseEvent.type != "mousedown" && mouseEvent.type != "mouseup")
expectedValue = -1;
else if (inputPointerType == "eraser")
expectedValue = 5;
} else if (attribute == "buttons") {
if (inputPointerType == "eraser" && mouseEvent.type == "mousedown")
expectedValue = 32;
} else if (attribute == "width" || attribute == "height") {
expectedValue = 1;
} else if (attribute == "pressure") {
if (pointerType == "mouse")
expectedValue = (mouseEvent.buttons == 0)? 0.0 : 0.5;
else
expectedValue = penPressure;
} else if (attribute == "tiltX") {
expectedValue = (pointerType == "mouse")? 0 : penTiltX;
} else if (attribute == "tiltY") {
expectedValue = (pointerType == "mouse")? 0 : penTiltY;
}
return expectedValue;
}
function init() {
var targetDiv = document.getElementById("target");
......@@ -89,24 +118,10 @@ function init() {
shouldBeTrue("lastPointerEvents[0].isPrimary");
numericAttributes.forEach(function(attribute) {
var expectedValue = eval("event." + attribute);
if (attribute == "button" && event.type != "mousedown" && event.type != "mouseup")
expectedValue = -1;
else if (attribute == "width" || attribute == "height")
expectedValue = 1;
else if (attribute == "pressure") {
if (pointerType == "mouse")
expectedValue = (event.buttons == 0)? 0.0 : 0.5;
else
expectedValue = penPressure;
}
else if (attribute == "tiltX")
expectedValue = (pointerType == "mouse")? 0 : penTiltX;
else if (attribute == "tiltY")
expectedValue = (pointerType == "mouse")? 0 : penTiltY;
var expectedValue = getExpectedNumericAttributeValueForPE(event, attribute);
shouldBeEqualToNumber("lastPointerEvents[0]." + attribute, expectedValue);
});
shouldBeEqualToString("lastPointerEvents[0].view.name", "mainWindow");
} else {
......@@ -164,29 +179,30 @@ function runMouseTests(x, y) {
debug("");
}
function runPenTests(x, y) {
debug("===== pen tests =====");
function runPenTests(x, y, id, eraseMode) {
debug("===== pen tests " + (eraseMode? "(erase mode)" : "(draw mode)") + " =====");
pointerType = "pen";
penId = 2;
inputPointerType = eraseMode? "eraser" : "pen";
penId = id;
penPressure = 0.0;
penTiltX = 0;
penTiltY = 0;
debug("--- move pen into target ---");
eventSender.mouseMoveTo(x + 5, y + 5, [], "pen", penId, penPressure, penTiltX, penTiltY);
eventSender.mouseMoveTo(x + 5, y + 5, [], inputPointerType, penId, penPressure, penTiltX, penTiltY);
debug("");
debug("--- move within target & tap ---");
penTiltX = 45;
penTiltY = -34;
eventSender.mouseMoveTo(x + 15, y + 15, [], "pen", penId, penPressure, penTiltX, penTiltY);
eventSender.mouseMoveTo(x + 15, y + 15, [], inputPointerType, penId, penPressure, penTiltX, penTiltY);
penPressure = 0.75;
eventSender.mouseDown(0, [], "pen", penId, penPressure, penTiltX, penTiltY);
eventSender.mouseDown(0, [], inputPointerType, penId, penPressure, penTiltX, penTiltY);
penPressure = 0.0;
eventSender.mouseUp(0, [], "pen", penId, penPressure, penTiltX, penTiltY);
eventSender.mouseUp(0, [], inputPointerType, penId, penPressure, penTiltX, penTiltY);
debug("--- move pen out of target ---");
eventSender.mouseMoveTo(x - 5, y - 5, [], "pen", penId, penPressure, penTiltX, penTiltY);
eventSender.mouseMoveTo(x - 5, y - 5, [], inputPointerType, penId, penPressure, penTiltX, penTiltY);
debug("");
}
......@@ -195,7 +211,8 @@ function runAllTests() {
var rect = document.getElementById("target").getBoundingClientRect();
runMouseTests(rect.left, rect.top);
runPenTests(rect.left, rect.top);
runPenTests(rect.left, rect.top, 2, false);
runPenTests(rect.left, rect.top, 3, true);
}
init();
......
......@@ -150,11 +150,11 @@ unsigned short MouseEvent::platformModifiersToButtons(unsigned modifiers)
unsigned short buttons = 0;
if (modifiers & PlatformEvent::LeftButtonDown)
buttons |= static_cast<unsigned short>(Buttons::Left);
buttons |= static_cast<unsigned short>(WebPointerProperties::Buttons::Left);
if (modifiers & PlatformEvent::RightButtonDown)
buttons |= static_cast<unsigned short>(Buttons::Right);
buttons |= static_cast<unsigned short>(WebPointerProperties::Buttons::Right);
if (modifiers & PlatformEvent::MiddleButtonDown)
buttons |= static_cast<unsigned short>(Buttons::Middle);
buttons |= static_cast<unsigned short>(WebPointerProperties::Buttons::Middle);
return buttons;
}
......
......@@ -92,13 +92,6 @@ public:
EventDispatchMediator* createMediator() override;
enum class Buttons : unsigned {
None = 0,
Left = 1 << 0,
Right = 1 << 1,
Middle = 1 << 2
};
DECLARE_VIRTUAL_TRACE();
protected:
......
......@@ -22,8 +22,7 @@ const char* pointerTypeNameForWebPointPointerType(WebPointerProperties::PointerT
return "touch";
case WebPointerProperties::PointerType::Pen:
case WebPointerProperties::PointerType::Eraser:
// TODO(mustaq): Continue eraser plumbing to web API.
// See crbug.com/642455
// TODO(mustaq): Fix when the spec starts supporting hovering erasers.
return "pen";
case WebPointerProperties::PointerType::Mouse:
return "mouse";
......@@ -57,16 +56,22 @@ const AtomicString& pointerEventNameForMouseEventName(
unsigned short buttonToButtonsBitfield(WebPointerProperties::Button button)
{
#define CASE_BUTTON_TO_BUTTONS(enumLabel) \
case WebPointerProperties::Button::enumLabel:\
return static_cast<unsigned short>(WebPointerProperties::Buttons::enumLabel)
switch (button) {
case WebPointerProperties::Button::NoButton:
return static_cast<unsigned short>(MouseEvent::Buttons::None);
case WebPointerProperties::Button::Left:
return static_cast<unsigned short>(MouseEvent::Buttons::Left);
case WebPointerProperties::Button::Right:
return static_cast<unsigned short>(MouseEvent::Buttons::Right);
case WebPointerProperties::Button::Middle:
return static_cast<unsigned short>(MouseEvent::Buttons::Middle);
CASE_BUTTON_TO_BUTTONS(NoButton);
CASE_BUTTON_TO_BUTTONS(Left);
CASE_BUTTON_TO_BUTTONS(Right);
CASE_BUTTON_TO_BUTTONS(Middle);
CASE_BUTTON_TO_BUTTONS(X1);
CASE_BUTTON_TO_BUTTONS(X2);
CASE_BUTTON_TO_BUTTONS(Eraser);
}
#undef CASE_BUTTON_TO_BUTTONS
NOTREACHED();
return 0;
}
......@@ -92,7 +97,15 @@ void PointerEventFactory::setIdTypeButtons(PointerEventInit& pointerEventInit,
const IncomingId incomingId(pointerType, pointerProperties.id);
int pointerId = addIdAndActiveButtons(incomingId, buttons != 0);
// Tweak the |buttons| to reflect pen eraser mode only if the pen is in
// active buttons state w/o even considering the eraser button.
// TODO(mustaq): Fix when the spec starts supporting hovering erasers.
if (pointerType == WebPointerProperties::PointerType::Eraser && buttons != 0) {
buttons |= static_cast<unsigned>(WebPointerProperties::Buttons::Eraser);
buttons &= ~static_cast<unsigned>(WebPointerProperties::Buttons::Left);
}
pointerEventInit.setButtons(buttons);
pointerEventInit.setPointerId(pointerId);
pointerEventInit.setPointerType(pointerTypeNameForWebPointPointerType(pointerType));
pointerEventInit.setIsPrimary(isPrimary(pointerId));
......@@ -145,7 +158,12 @@ PointerEvent* PointerEventFactory::create(
if (pointerEventName == EventTypeNames::pointerdown
|| pointerEventName == EventTypeNames::pointerup) {
pointerEventInit.setButton(static_cast<int>(mouseEvent.pointerProperties().button));
WebPointerProperties::Button button = mouseEvent.pointerProperties().button;
// TODO(mustaq): Fix when the spec starts supporting hovering erasers.
if (mouseEvent.pointerProperties().pointerType == WebPointerProperties::PointerType::Eraser
&& button == WebPointerProperties::Button::Left)
button = WebPointerProperties::Button::Eraser;
pointerEventInit.setButton(static_cast<int>(button));
} else {
DCHECK(pointerEventName == EventTypeNames::pointermove);
pointerEventInit.setButton(static_cast<int>(WebPointerProperties::Button::NoButton));
......
......@@ -31,7 +31,20 @@ public:
NoButton = -1,
Left,
Middle,
Right
Right,
X1,
X2,
Eraser
};
enum class Buttons : unsigned {
NoButton = 0,
Left = 1 << 0,
Right = 1 << 1,
Middle = 1 << 2,
X1 = 1 << 3,
X2 = 1 << 4,
Eraser = 1 << 5
};
enum class PointerType {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment