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 { ...@@ -63,10 +63,11 @@ namespace test_runner {
namespace { namespace {
const int kRawMousePointerId = -1; const int kRawMousePointerId = -1;
const char* kPointerTypeStringUnknown = ""; const char* const kPointerTypeStringUnknown = "";
const char* kPointerTypeStringMouse = "mouse"; const char* const kPointerTypeStringMouse = "mouse";
const char* kPointerTypeStringPen = "pen"; const char* const kPointerTypeStringTouch = "touch";
const char* kPointerTypeStringTouch = "touch"; const char* const kPointerTypeStringPen = "pen";
const char* const kPointerTypeStringEraser = "eraser";
// Assigns |pointerType| from the provided |args|. Returns false if there was // Assigns |pointerType| from the provided |args|. Returns false if there was
// any error. // any error.
...@@ -90,10 +91,12 @@ bool getPointerType(gin::Arguments* args, ...@@ -90,10 +91,12 @@ bool getPointerType(gin::Arguments* args,
pointerType = WebMouseEvent::PointerType::Unknown; pointerType = WebMouseEvent::PointerType::Unknown;
} else if (pointer_type_string == kPointerTypeStringMouse) { } else if (pointer_type_string == kPointerTypeStringMouse) {
pointerType = WebMouseEvent::PointerType::Mouse; pointerType = WebMouseEvent::PointerType::Mouse;
} else if (pointer_type_string == kPointerTypeStringPen) {
pointerType = WebMouseEvent::PointerType::Pen;
} else if (pointer_type_string == kPointerTypeStringTouch) { } else if (pointer_type_string == kPointerTypeStringTouch) {
pointerType = WebMouseEvent::PointerType::Touch; 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 { } else {
args->ThrowError(); args->ThrowError();
return false; return false;
...@@ -175,6 +178,10 @@ int GetWebMouseEventModifierForButton(WebMouseEvent::Button button) { ...@@ -175,6 +178,10 @@ int GetWebMouseEventModifierForButton(WebMouseEvent::Button button) {
return WebMouseEvent::MiddleButtonDown; return WebMouseEvent::MiddleButtonDown;
case WebMouseEvent::Button::Right: case WebMouseEvent::Button::Right:
return WebMouseEvent::RightButtonDown; return WebMouseEvent::RightButtonDown;
case WebPointerProperties::Button::X1:
case WebPointerProperties::Button::X2:
case WebPointerProperties::Button::Eraser:
return 0; // Not implemented yet
} }
NOTREACHED(); NOTREACHED();
return 0; return 0;
......
...@@ -20,6 +20,8 @@ description("Verifies that pointer event parameters are correct when fired throu ...@@ -20,6 +20,8 @@ description("Verifies that pointer event parameters are correct when fired throu
var checkKeyModifiers = false; var checkKeyModifiers = false;
var inputPointerType = "";
var pointerType = ""; var pointerType = "";
var penId = 0; var penId = 0;
var penPressure = 0; var penPressure = 0;
...@@ -54,6 +56,33 @@ var numericAttributes = [ ...@@ -54,6 +56,33 @@ var numericAttributes = [
"height", "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() { function init() {
var targetDiv = document.getElementById("target"); var targetDiv = document.getElementById("target");
...@@ -89,24 +118,10 @@ function init() { ...@@ -89,24 +118,10 @@ function init() {
shouldBeTrue("lastPointerEvents[0].isPrimary"); shouldBeTrue("lastPointerEvents[0].isPrimary");
numericAttributes.forEach(function(attribute) { numericAttributes.forEach(function(attribute) {
var expectedValue = eval("event." + attribute); var expectedValue = getExpectedNumericAttributeValueForPE(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;
shouldBeEqualToNumber("lastPointerEvents[0]." + attribute, expectedValue); shouldBeEqualToNumber("lastPointerEvents[0]." + attribute, expectedValue);
}); });
shouldBeEqualToString("lastPointerEvents[0].view.name", "mainWindow"); shouldBeEqualToString("lastPointerEvents[0].view.name", "mainWindow");
} else { } else {
...@@ -164,29 +179,30 @@ function runMouseTests(x, y) { ...@@ -164,29 +179,30 @@ function runMouseTests(x, y) {
debug(""); debug("");
} }
function runPenTests(x, y) { function runPenTests(x, y, id, eraseMode) {
debug("===== pen tests ====="); debug("===== pen tests " + (eraseMode? "(erase mode)" : "(draw mode)") + " =====");
pointerType = "pen"; pointerType = "pen";
penId = 2; inputPointerType = eraseMode? "eraser" : "pen";
penId = id;
penPressure = 0.0; penPressure = 0.0;
penTiltX = 0; penTiltX = 0;
penTiltY = 0; penTiltY = 0;
debug("--- move pen into target ---"); 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("");
debug("--- move within target & tap ---"); debug("--- move within target & tap ---");
penTiltX = 45; penTiltX = 45;
penTiltY = -34; 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; penPressure = 0.75;
eventSender.mouseDown(0, [], "pen", penId, penPressure, penTiltX, penTiltY); eventSender.mouseDown(0, [], inputPointerType, penId, penPressure, penTiltX, penTiltY);
penPressure = 0.0; 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 ---"); 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(""); debug("");
} }
...@@ -195,7 +211,8 @@ function runAllTests() { ...@@ -195,7 +211,8 @@ function runAllTests() {
var rect = document.getElementById("target").getBoundingClientRect(); var rect = document.getElementById("target").getBoundingClientRect();
runMouseTests(rect.left, rect.top); 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(); init();
......
...@@ -150,11 +150,11 @@ unsigned short MouseEvent::platformModifiersToButtons(unsigned modifiers) ...@@ -150,11 +150,11 @@ unsigned short MouseEvent::platformModifiersToButtons(unsigned modifiers)
unsigned short buttons = 0; unsigned short buttons = 0;
if (modifiers & PlatformEvent::LeftButtonDown) if (modifiers & PlatformEvent::LeftButtonDown)
buttons |= static_cast<unsigned short>(Buttons::Left); buttons |= static_cast<unsigned short>(WebPointerProperties::Buttons::Left);
if (modifiers & PlatformEvent::RightButtonDown) if (modifiers & PlatformEvent::RightButtonDown)
buttons |= static_cast<unsigned short>(Buttons::Right); buttons |= static_cast<unsigned short>(WebPointerProperties::Buttons::Right);
if (modifiers & PlatformEvent::MiddleButtonDown) if (modifiers & PlatformEvent::MiddleButtonDown)
buttons |= static_cast<unsigned short>(Buttons::Middle); buttons |= static_cast<unsigned short>(WebPointerProperties::Buttons::Middle);
return buttons; return buttons;
} }
......
...@@ -92,13 +92,6 @@ public: ...@@ -92,13 +92,6 @@ public:
EventDispatchMediator* createMediator() override; EventDispatchMediator* createMediator() override;
enum class Buttons : unsigned {
None = 0,
Left = 1 << 0,
Right = 1 << 1,
Middle = 1 << 2
};
DECLARE_VIRTUAL_TRACE(); DECLARE_VIRTUAL_TRACE();
protected: protected:
......
...@@ -22,8 +22,7 @@ const char* pointerTypeNameForWebPointPointerType(WebPointerProperties::PointerT ...@@ -22,8 +22,7 @@ const char* pointerTypeNameForWebPointPointerType(WebPointerProperties::PointerT
return "touch"; return "touch";
case WebPointerProperties::PointerType::Pen: case WebPointerProperties::PointerType::Pen:
case WebPointerProperties::PointerType::Eraser: case WebPointerProperties::PointerType::Eraser:
// TODO(mustaq): Continue eraser plumbing to web API. // TODO(mustaq): Fix when the spec starts supporting hovering erasers.
// See crbug.com/642455
return "pen"; return "pen";
case WebPointerProperties::PointerType::Mouse: case WebPointerProperties::PointerType::Mouse:
return "mouse"; return "mouse";
...@@ -57,16 +56,22 @@ const AtomicString& pointerEventNameForMouseEventName( ...@@ -57,16 +56,22 @@ const AtomicString& pointerEventNameForMouseEventName(
unsigned short buttonToButtonsBitfield(WebPointerProperties::Button button) 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) { switch (button) {
case WebPointerProperties::Button::NoButton: CASE_BUTTON_TO_BUTTONS(NoButton);
return static_cast<unsigned short>(MouseEvent::Buttons::None); CASE_BUTTON_TO_BUTTONS(Left);
case WebPointerProperties::Button::Left: CASE_BUTTON_TO_BUTTONS(Right);
return static_cast<unsigned short>(MouseEvent::Buttons::Left); CASE_BUTTON_TO_BUTTONS(Middle);
case WebPointerProperties::Button::Right: CASE_BUTTON_TO_BUTTONS(X1);
return static_cast<unsigned short>(MouseEvent::Buttons::Right); CASE_BUTTON_TO_BUTTONS(X2);
case WebPointerProperties::Button::Middle: CASE_BUTTON_TO_BUTTONS(Eraser);
return static_cast<unsigned short>(MouseEvent::Buttons::Middle);
} }
#undef CASE_BUTTON_TO_BUTTONS
NOTREACHED(); NOTREACHED();
return 0; return 0;
} }
...@@ -92,7 +97,15 @@ void PointerEventFactory::setIdTypeButtons(PointerEventInit& pointerEventInit, ...@@ -92,7 +97,15 @@ void PointerEventFactory::setIdTypeButtons(PointerEventInit& pointerEventInit,
const IncomingId incomingId(pointerType, pointerProperties.id); const IncomingId incomingId(pointerType, pointerProperties.id);
int pointerId = addIdAndActiveButtons(incomingId, buttons != 0); 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.setButtons(buttons);
pointerEventInit.setPointerId(pointerId); pointerEventInit.setPointerId(pointerId);
pointerEventInit.setPointerType(pointerTypeNameForWebPointPointerType(pointerType)); pointerEventInit.setPointerType(pointerTypeNameForWebPointPointerType(pointerType));
pointerEventInit.setIsPrimary(isPrimary(pointerId)); pointerEventInit.setIsPrimary(isPrimary(pointerId));
...@@ -145,7 +158,12 @@ PointerEvent* PointerEventFactory::create( ...@@ -145,7 +158,12 @@ PointerEvent* PointerEventFactory::create(
if (pointerEventName == EventTypeNames::pointerdown if (pointerEventName == EventTypeNames::pointerdown
|| pointerEventName == EventTypeNames::pointerup) { || 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 { } else {
DCHECK(pointerEventName == EventTypeNames::pointermove); DCHECK(pointerEventName == EventTypeNames::pointermove);
pointerEventInit.setButton(static_cast<int>(WebPointerProperties::Button::NoButton)); pointerEventInit.setButton(static_cast<int>(WebPointerProperties::Button::NoButton));
......
...@@ -31,7 +31,20 @@ public: ...@@ -31,7 +31,20 @@ public:
NoButton = -1, NoButton = -1,
Left, Left,
Middle, 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 { 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