shortcuts: Add Alt + Esc to cancel inputting an accelerator
Screenshot: screenshot.googleplex.com/BvXzPPQPsMQyAAr
Bug: b/216049298
Test: browser_tests
Change-Id: I6abe77508ab20fa3e3dcefb8e085eba68980bc48
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4764266
Reviewed-by: Michael Checo <michaelcheco@google.com>
Commit-Queue: Jimmy Gong <jimmyxgong@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1182204}
diff --git a/ash/webui/shortcut_customization_ui/resources/js/accelerator_view.ts b/ash/webui/shortcut_customization_ui/resources/js/accelerator_view.ts
index ce8753fd..46db152 100644
--- a/ash/webui/shortcut_customization_ui/resources/js/accelerator_view.ts
+++ b/ash/webui/shortcut_customization_ui/resources/js/accelerator_view.ts
@@ -46,6 +46,8 @@
// change to the backend.
const kAnimationTimeoutMs: number = 300;
+const kEscapeKey: number = 27; // Keycode for VKEY_ESCAPE
+
/**
* @fileoverview
* 'accelerator-view' is wrapper component for an accelerator. It maintains both
@@ -261,10 +263,18 @@
this.hasError = false;
}
+ const pendingAccelerator = this.keystrokeToAccelerator(e);
+ // Alt + Esc will exit input handling immediately.
+ if (pendingAccelerator.modifiers === Modifier.ALT &&
+ pendingAccelerator.keyCode === kEscapeKey) {
+ this.endCapture(/*shouldDelay=*/ false);
+ return;
+ }
+
// Add the key pressed to pendingAccelerator.
this.set(
'pendingAcceleratorInfo.layoutProperties.standardAccelerator.accelerator',
- this.keystrokeToAccelerator(e));
+ pendingAccelerator);
if (this.isModifierKey(e)) {
// Reset the keyDisplay property if the key is a modifier.
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_dialog_test.ts b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_dialog_test.ts
index fcd8d04..ec10848f 100644
--- a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_dialog_test.ts
+++ b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_dialog_test.ts
@@ -173,7 +173,8 @@
const acceleratorElements =
dialog.querySelectorAll('accelerator-edit-view');
const expectedHintMessage =
- 'Press 1-4 modifiers and 1 other key on your keyboard';
+ 'Press 1-4 modifiers and 1 other key on your keyboard. To exit ' +
+ 'editing mode, press alt + esc.';
const statusMessageElement = strictQuery(
'#acceleratorInfoText', acceleratorElements[0]!.shadowRoot,
HTMLDivElement);
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_view_test.ts b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_view_test.ts
index a7b5269..5e99868 100644
--- a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_view_test.ts
+++ b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_view_test.ts
@@ -218,7 +218,8 @@
// Input hint message should be shown.
const expectedHintMessage =
- 'Press 1-4 modifiers and 1 other key on your keyboard';
+ 'Press 1-4 modifiers and 1 other key on your keyboard. To exit ' +
+ 'editing mode, press alt + esc.';
const statusMessageElement = strictQuery(
'#acceleratorInfoText', editViewElement!.shadowRoot, HTMLDivElement);
assertEquals(expectedHintMessage, statusMessageElement.textContent!.trim());
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_view_test.ts b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_view_test.ts
index 5025c5f..398ab2f3 100644
--- a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_view_test.ts
+++ b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_view_test.ts
@@ -17,7 +17,7 @@
import {setShortcutProviderForTesting} from 'chrome://shortcut-customization/js/mojo_interface_provider.js';
import {AcceleratorConfigResult, AcceleratorSource, LayoutStyle, Modifier} from 'chrome://shortcut-customization/js/shortcut_types.js';
import {AcceleratorResultData} from 'chrome://shortcut-customization/mojom-webui/ash/webui/shortcut_customization_ui/mojom/shortcut_customization.mojom-webui.js';
-import {assertEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
+import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
import {flushTasks} from 'chrome://webui-test/polymer_test_util.js';
import {isVisible} from 'chrome://webui-test/test_util.js';
@@ -563,4 +563,87 @@
assertTrue(!!viewContainer.ariaLabel);
assertTrue(regex.test(viewContainer.ariaLabel));
});
+
+ test('CancelInputWithShortcut', async () => {
+ viewElement = initAcceleratorViewElement();
+ await flushTasks();
+
+ const acceleratorInfo = createStandardAcceleratorInfo(
+ Modifier.ALT,
+ /*key=*/ 221,
+ /*keyDisplay=*/ ']');
+
+ viewElement.acceleratorInfo = acceleratorInfo;
+ viewElement.source = AcceleratorSource.kAsh;
+ viewElement.action = 1;
+ // Enable the edit view.
+ viewElement.viewState = ViewState.EDIT;
+
+ await flush();
+
+ // Assert that this is in the EDIT state.
+ assertEquals(ViewState.EDIT, viewElement.viewState);
+
+ let ctrlKey = getInputKey('#ctrlKey');
+ let altKey = getInputKey('#altKey');
+ let shiftKey = getInputKey('#shiftKey');
+ let metaKey = getInputKey('#searchKey');
+ let pendingKey = getInputKey('#pendingKey');
+
+ // By default, no keys should be registered.
+ assertEquals(KeyInputState.NOT_SELECTED, ctrlKey.keyState);
+ assertEquals(KeyInputState.NOT_SELECTED, altKey.keyState);
+ assertEquals(KeyInputState.NOT_SELECTED, shiftKey.keyState);
+ assertEquals(KeyInputState.NOT_SELECTED, metaKey.keyState);
+ assertEquals(KeyInputState.NOT_SELECTED, pendingKey.keyState);
+ assertEquals('key', pendingKey.key);
+
+ // Simulate Alt.
+ viewElement.dispatchEvent(new KeyboardEvent('keydown', {
+ key: 'Alt',
+ keyCode: 18,
+ code: 'Alt',
+ ctrlKey: false,
+ altKey: true,
+ shiftKey: false,
+ metaKey: false,
+ }));
+
+ await flush();
+
+ assertEquals(KeyInputState.NOT_SELECTED, ctrlKey.keyState);
+ assertEquals(KeyInputState.MODIFIER_SELECTED, altKey.keyState);
+ assertEquals(KeyInputState.NOT_SELECTED, shiftKey.keyState);
+ assertEquals(KeyInputState.NOT_SELECTED, metaKey.keyState);
+ assertEquals(KeyInputState.NOT_SELECTED, pendingKey.keyState);
+
+ // Now press Escape.
+ viewElement.dispatchEvent(new KeyboardEvent('keydown', {
+ key: 'Escape',
+ keyCode: 27,
+ code: 'Escape',
+ ctrlKey: false,
+ altKey: true,
+ shiftKey: false,
+ metaKey: false,
+ }));
+
+ await flush();
+ ctrlKey = getInputKey('#ctrlKey');
+ altKey = getInputKey('#altKey');
+ shiftKey = getInputKey('#shiftKey');
+ metaKey = getInputKey('#searchKey');
+ pendingKey = getInputKey('#pendingKey');
+
+ assertEquals(KeyInputState.NOT_SELECTED, ctrlKey.keyState);
+ assertEquals(KeyInputState.MODIFIER_SELECTED, altKey.keyState);
+ assertEquals(KeyInputState.NOT_SELECTED, shiftKey.keyState);
+ assertEquals(KeyInputState.NOT_SELECTED, metaKey.keyState);
+ assertEquals(KeyInputState.NOT_SELECTED, pendingKey.keyState);
+
+ // Expect that press Alt + Esc will cancel the edit state.
+ assertEquals(ViewState.VIEW, viewElement.viewState);
+ assertFalse(viewElement.hasError);
+ assertEquals('', viewElement.statusMessage);
+ });
});
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd
index f95b1da..b358dd04 100644
--- a/chromeos/chromeos_strings.grd
+++ b/chromeos/chromeos_strings.grd
@@ -4024,7 +4024,7 @@
Cancel
</message>
<message name="IDS_SHORTCUT_CUSTOMIZATION_EDIT_VIEW_STATUS_MESSAGE" desc="Instructions to user when they're inputting a new shortcut">
- Press 1-4 modifiers and 1 other key on your keyboard
+ Press 1-4 modifiers and 1 other key on your keyboard. To exit editing mode, press alt + esc.
</message>
<message name="IDS_SHORTCUT_CUSTOMIZATION_RESTORE_DEFAULT_ERROR_MESSAGE" desc="Description text shown to users that their default shortcut is used by another shortcut action">
Shortcut is being used for "<ph name="CONFLICT_ACCEL_NAME">$1<ex>BRIGHTNESS_UP</ex></ph>". Edit or remove to resolve the conflict.
diff --git a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_EDIT_VIEW_STATUS_MESSAGE.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_EDIT_VIEW_STATUS_MESSAGE.png.sha1
index c61fb2c..9cb5f64 100644
--- a/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_EDIT_VIEW_STATUS_MESSAGE.png.sha1
+++ b/chromeos/chromeos_strings_grd/IDS_SHORTCUT_CUSTOMIZATION_EDIT_VIEW_STATUS_MESSAGE.png.sha1
@@ -1 +1 @@
-06f3c03a67b3c9556e45d899c3415446a4ba04f6
\ No newline at end of file
+aeb4e4b019f1d6db044659d0df63649b6d3109e5
\ No newline at end of file