Skip to content

Commit

Permalink
[fuchsia] Support all input3.Modifiers and remove modifier caching
Browse files Browse the repository at this point in the history
Bug: 1353772, 850697
Change-Id: I98f6159e238e116f75948ed5d39a710b684588a2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4178340
Commit-Queue: Bryant Chandler <bryantchandler@chromium.org>
Reviewed-by: David Dorwin <ddorwin@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1103498}
  • Loading branch information
Bryant Chandler authored and Chromium LUCI CQ committed Feb 9, 2023
1 parent 1c12da3 commit 1cd0b1a
Show file tree
Hide file tree
Showing 4 changed files with 282 additions and 78 deletions.
182 changes: 178 additions & 4 deletions fuchsia_web/webengine/browser/input_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ KeyEvent CreateCharacterKeyEvent(uint32_t codepoint, KeyEventType event_type) {

struct KeyEventOptions {
bool repeat;
std::vector<fuchsia::ui::input3::Modifiers> modifiers;
};

// Returns a KeyEvent with both |key| and |key_meaning| set.
Expand All @@ -68,6 +69,13 @@ KeyEvent CreateKeyEvent(Key key,
// present.
key_event.set_repeat_sequence(1);
}
if (!options.modifiers.empty()) {
fuchsia::ui::input3::Modifiers modifiers;
for (const auto modifier : options.modifiers) {
modifiers |= modifier;
}
key_event.set_modifiers(modifiers);
}
return key_event;
}
KeyEvent CreateKeyEvent(Key key,
Expand All @@ -86,6 +94,33 @@ KeyEvent CreateKeyEvent(Key key,
event_type, options);
}

base::Value::List FuchsiaModifiersToWebModifiers(
const std::vector<fuchsia::ui::input3::Modifiers> fuchsia_modifiers) {
base::Value::List web_modifiers;
for (const auto modifier : fuchsia_modifiers) {
if (modifier == fuchsia::ui::input3::Modifiers::ALT) {
web_modifiers.Append("Alt");
} else if (modifier == fuchsia::ui::input3::Modifiers::ALT_GRAPH) {
web_modifiers.Append("AltGraph");
} else if (modifier == fuchsia::ui::input3::Modifiers::CAPS_LOCK) {
web_modifiers.Append("CapsLock");
} else if (modifier == fuchsia::ui::input3::Modifiers::CTRL) {
web_modifiers.Append("Control");
} else if (modifier == fuchsia::ui::input3::Modifiers::META) {
web_modifiers.Append("Meta");
} else if (modifier == fuchsia::ui::input3::Modifiers::NUM_LOCK) {
web_modifiers.Append("NumLock");
} else if (modifier == fuchsia::ui::input3::Modifiers::SCROLL_LOCK) {
web_modifiers.Append("ScrollLock");
} else if (modifier == fuchsia::ui::input3::Modifiers::SHIFT) {
web_modifiers.Append("Shift");
} else {
NOTREACHED() << static_cast<uint64_t>(modifier) << " has no web mapping";
}
}
return web_modifiers;
}

base::Value ExpectedKeyValue(base::StringPiece code,
base::StringPiece key,
base::StringPiece type,
Expand All @@ -95,6 +130,7 @@ base::Value ExpectedKeyValue(base::StringPiece code,
expected.Set("key", key);
expected.Set("type", type);
expected.Set("repeat", options.repeat);
expected.Set("modifiers", FuchsiaModifiersToWebModifiers(options.modifiers));
return base::Value(std::move(expected));
}

Expand Down Expand Up @@ -209,10 +245,7 @@ class KeyboardInputTest : public WebEngineBrowserTest {
command_line->AppendSwitch("allow-pre-commit-input");
}

template <typename... Args>
void ExpectKeyEventsEqual(Args... events) {
base::Value::List expected =
content::ListValueOf(std::forward<Args>(events)...).TakeList();
void ExpectKeyEventsEqual(base::Value::List expected) {
frame_for_test_.navigation_listener().RunUntilTitleEquals(
base::NumberToString(expected.size()));

Expand All @@ -221,6 +254,13 @@ class KeyboardInputTest : public WebEngineBrowserTest {
EXPECT_EQ(*actual, base::Value(std::move(expected)));
}

template <typename... Args>
void ExpectKeyEventsEqual(Args... events) {
base::Value::List expected =
content::ListValueOf(std::forward<Args>(events)...).TakeList();
ExpectKeyEventsEqual(std::move(expected));
}

// Used to publish fake services.
absl::optional<base::TestComponentContextForProcess> component_context_;

Expand Down Expand Up @@ -390,6 +430,140 @@ IN_PROC_BROWSER_TEST_F(KeyboardInputTest, RepeatedKeys) {
ExpectedKeyValue("Digit8", "8", kKeyPress, {.repeat = true}));
}

IN_PROC_BROWSER_TEST_F(KeyboardInputTest, AllSupportedWebModifierKeys) {
// All modifiers in the FIDL protocol that Chrome handles on the web.
//
// Missing modifiers:
// * LEFT_*/RIGHT_* are not valid by themselves.
// * FUNCTION and SYMBOL. See AllUnsupportedWebModifierKeys test.
const std::vector kAllSupportedModifiers = {
fuchsia::ui::input3::Modifiers::CAPS_LOCK,
fuchsia::ui::input3::Modifiers::NUM_LOCK,
fuchsia::ui::input3::Modifiers::SCROLL_LOCK,
fuchsia::ui::input3::Modifiers::SHIFT,
fuchsia::ui::input3::Modifiers::ALT,
fuchsia::ui::input3::Modifiers::ALT_GRAPH,
fuchsia::ui::input3::Modifiers::META,
fuchsia::ui::input3::Modifiers::CTRL};
for (const auto& modifier : kAllSupportedModifiers) {
keyboard_service_->SendKeyEvent(CreateKeyEvent(
Key::M, 'm', KeyEventType::PRESSED, {.modifiers = {modifier}}));
}

base::Value::List expected_events;
for (const auto& modifier : kAllSupportedModifiers) {
expected_events.Append(
ExpectedKeyValue("KeyM", "m", kKeyDown, {.modifiers = {modifier}}));
// Chrome doesn't emit keypress events when an ALT or CTRL modifier is
// present.
if (modifier != fuchsia::ui::input3::Modifiers::ALT &&
modifier != fuchsia::ui::input3::Modifiers::CTRL) {
expected_events.Append(
ExpectedKeyValue("KeyM", "m", kKeyPress, {.modifiers = {modifier}}));
}
}

ExpectKeyEventsEqual(std::move(expected_events));
}

IN_PROC_BROWSER_TEST_F(KeyboardInputTest, AllUnsupportedWebModifierKeys) {
// All modifiers in the FIDL protocol that Chrome doesn't handle on the web
// because they aren't included in
// https://crsrc.org/c/ui/events/blink/blink_event_util.cc;l=268?q=EventFlagsToWebEventModifiers
const std::vector kAllUnsupportedModifiers = {
fuchsia::ui::input3::Modifiers::FUNCTION,
fuchsia::ui::input3::Modifiers::SYMBOL};
for (const auto& modifier : kAllUnsupportedModifiers) {
keyboard_service_->SendKeyEvent(CreateKeyEvent(
Key::M, 'm', KeyEventType::PRESSED, {.modifiers = {modifier}}));
}

base::Value::List expected_events;
for (size_t i = 0; i < kAllUnsupportedModifiers.size(); ++i) {
expected_events.Append(ExpectedKeyValue("KeyM", "m", kKeyDown, {}));
expected_events.Append(ExpectedKeyValue("KeyM", "m", kKeyPress, {}));
}

ExpectKeyEventsEqual(std::move(expected_events));
}

// This is a spot check to make sure that modifiers work with other keys and in
// combination with each other.
IN_PROC_BROWSER_TEST_F(KeyboardInputTest, AssortedModifierKeyCombos) {
// Test that sending LEFT/RIGHT SHIFT with agnostic SHIFT passes DCHECK.
keyboard_service_->SendKeyEvent(CreateKeyEvent(
Key::A, 'a', KeyEventType::PRESSED,
{.modifiers = {fuchsia::ui::input3::Modifiers::SHIFT,
fuchsia::ui::input3::Modifiers::LEFT_SHIFT,
fuchsia::ui::input3::Modifiers::RIGHT_SHIFT}}));
// Test that sending LEFT/RIGHT ALT with agnostic ALT passes DCHECK.
keyboard_service_->SendKeyEvent(CreateKeyEvent(
Key::KEY_8, '8', KeyEventType::PRESSED,
{.modifiers = {fuchsia::ui::input3::Modifiers::ALT,
fuchsia::ui::input3::Modifiers::LEFT_ALT,
fuchsia::ui::input3::Modifiers::RIGHT_ALT}}));
// Test that sending LEFT/RIGHT META with agnostic META passes DCHECK.
keyboard_service_->SendKeyEvent(CreateKeyEvent(
Key::B, 'b', KeyEventType::PRESSED,
{.modifiers = {fuchsia::ui::input3::Modifiers::META,
fuchsia::ui::input3::Modifiers::LEFT_META,
fuchsia::ui::input3::Modifiers::RIGHT_META}}));
// Test that sending LEFT/RIGHT CTRL with agnostic CTRL passes DCHECK.
keyboard_service_->SendKeyEvent(CreateKeyEvent(
Key::LEFT, 0, KeyEventType::PRESSED,
{.modifiers = {fuchsia::ui::input3::Modifiers::CTRL,
fuchsia::ui::input3::Modifiers::LEFT_CTRL,
fuchsia::ui::input3::Modifiers::RIGHT_CTRL}}));
keyboard_service_->SendKeyEvent(
CreateKeyEvent(Key::P, 'p', KeyEventType::PRESSED,
{.modifiers = {fuchsia::ui::input3::Modifiers::CTRL,
fuchsia::ui::input3::Modifiers::SHIFT}}));
keyboard_service_->SendKeyEvent(CreateKeyEvent(
Key::RIGHT, 0, KeyEventType::PRESSED,
{.modifiers = {fuchsia::ui::input3::Modifiers::ALT_GRAPH}}));
keyboard_service_->SendKeyEvent(CreateKeyEvent(
Key::UP, 0, KeyEventType::PRESSED,
{.modifiers = {fuchsia::ui::input3::Modifiers::CAPS_LOCK}}));
keyboard_service_->SendKeyEvent(CreateKeyEvent(
Key::DOWN, 0, KeyEventType::PRESSED,
{.modifiers = {fuchsia::ui::input3::Modifiers::NUM_LOCK}}));
keyboard_service_->SendKeyEvent(CreateKeyEvent(
Key::LEFT, 0, KeyEventType::PRESSED,
{.modifiers = {fuchsia::ui::input3::Modifiers::SCROLL_LOCK}}));

ExpectKeyEventsEqual(
ExpectedKeyValue("KeyA", "a", kKeyDown,
{.modifiers = {fuchsia::ui::input3::Modifiers::SHIFT}}),
ExpectedKeyValue("KeyA", "a", kKeyPress,
{.modifiers = {fuchsia::ui::input3::Modifiers::SHIFT}}),
ExpectedKeyValue("Digit8", "8", kKeyDown,
{.modifiers = {fuchsia::ui::input3::Modifiers::ALT}}),
ExpectedKeyValue("KeyB", "b", kKeyDown,
{.modifiers = {fuchsia::ui::input3::Modifiers::META}}),
ExpectedKeyValue("KeyB", "b", kKeyPress,
{.modifiers = {fuchsia::ui::input3::Modifiers::META}}),
ExpectedKeyValue("ArrowLeft", "ArrowLeft", kKeyDown,
{.modifiers = {fuchsia::ui::input3::Modifiers::CTRL}}),
ExpectedKeyValue("KeyP", "p", kKeyDown,
{.modifiers = {fuchsia::ui::input3::Modifiers::CTRL,
fuchsia::ui::input3::Modifiers::SHIFT}}),
ExpectedKeyValue("KeyP", "p", kKeyPress,
{.modifiers = {fuchsia::ui::input3::Modifiers::CTRL,
fuchsia::ui::input3::Modifiers::SHIFT}}),
ExpectedKeyValue(
"ArrowRight", "ArrowRight", kKeyDown,
{.modifiers = {fuchsia::ui::input3::Modifiers::ALT_GRAPH}}),
ExpectedKeyValue(
"ArrowUp", "ArrowUp", kKeyDown,
{.modifiers = {fuchsia::ui::input3::Modifiers::CAPS_LOCK}}),
ExpectedKeyValue(
"ArrowDown", "ArrowDown", kKeyDown,
{.modifiers = {fuchsia::ui::input3::Modifiers::NUM_LOCK}}),
ExpectedKeyValue(
"ArrowLeft", "ArrowLeft", kKeyDown,
{.modifiers = {fuchsia::ui::input3::Modifiers::SCROLL_LOCK}}));
}

IN_PROC_BROWSER_TEST_F(KeyboardInputTest, Disconnect) {
// Disconnect the keyboard service.
keyboard_service_.reset();
Expand Down
26 changes: 23 additions & 3 deletions fuchsia_web/webengine/test/data/keyevents.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,38 @@
<script>
var keyDicts = [];

function getActiveModifiers(e) {
let active_modifiers = [];
// This list contains all modifiers listed in
// https://www.w3.org/TR/uievents-key/#keys-modifier (2017). It also
// includes "OS", which isn't in the spec, but it is listed on the
// MDN page for getModifierState.
//
// Note that several of the listed modifiers aren't yet supported on
// Fuchsia/Chrome.
for (modifier of ["Alt", "AltGraph", "CapsLock", "Control", "Fn",
"FnLock", "Hyper", "Meta", "NumLock", "OS",
"ScrollLock", "Shift", "Super", "Symbol",
"SymbolLock"]) {
if (e.getModifierState(modifier)) {
active_modifiers.push(modifier);
}
}
return active_modifiers;
}

document.addEventListener("keypress", (e) => {
keyDicts.push( { "key" : e.key, "code" : e.code, "type" : e.type, "repeat": e.repeat});
keyDicts.push( { "key" : e.key, "code" : e.code, "type" : e.type, "repeat": e.repeat, "modifiers": getActiveModifiers(e)});
document.title = keyDicts.length;
});

document.addEventListener("keyup", (e) => {
keyDicts.push({ "key" : e.key, "code" : e.code, "type" : e.type, "repeat": e.repeat});
keyDicts.push({ "key" : e.key, "code" : e.code, "type" : e.type, "repeat": e.repeat, "modifiers": getActiveModifiers(e)});
document.title = keyDicts.length;
});

document.addEventListener("keydown", (e) => {
keyDicts.push({ "key" : e.key, "code" : e.code, "type" : e.type, "repeat": e.repeat});
keyDicts.push({ "key" : e.key, "code" : e.code, "type" : e.type, "repeat": e.repeat, "modifiers": getActiveModifiers(e)});
document.title = keyDicts.length;
});

Expand Down

0 comments on commit 1cd0b1a

Please sign in to comment.