Repository: microsoft/vscode (TypeScript)
Date: 2022-10-07 13:39:18+00:00
Task type: Bug Fix

Issue:
Remove keybindings with when clause does not work
<!-- ⚠️⚠️ Do Not Delete This! bug_report_template ⚠️⚠️ -->
<!-- Please read our Rules of Conduct: https://opensource.microsoft.com/codeofconduct/ -->
<!-- 🕮 Read our guide about submitting issues: https://github.com/microsoft/vscode/wiki/Submitting-Bugs-and-Suggestions -->
<!-- 🔎 Search existing issues to avoid creating duplicates. -->
<!-- 🧪 Test using the latest Insiders build to see if your issue has already been fixed: https://code.visualstudio.com/insiders/ -->
<!-- 💡 Instead of creating your report here, use 'Report Issue' from the 'Help' menu in VS Code to pre-fill useful information. -->
<!-- 🔧 Launch with `code --disable-extensions` to check. -->
Does this issue occur when all extensions are disabled?: Yes

<!-- 🪓 If you answered No above, use 'Help: Start Extension Bisect' from Command Palette to try to identify the cause. -->
<!-- 📣 Issues caused by an extension need to be reported directly to the extension publisher. The 'Help > Report Issue' dialog can assist with this. -->
- VS Code version: Code 1.71.0 (784b0177c56c607789f9638da7b6bf3230d47a8c, 2022-09-01T07:25:10.472Z)
- OS version: Linux x64 5.19.7-arch1-1.1
- Sandboxed: No

### Steps to Reproduce:

1. Append below item to the `keybindings.json`
```json
    {
        "key": "ctrl+\\",
        "command": "-workbench.action.splitEditor",
        "when": "isLinux"
    }
```
2. Press `Ctrl` + `\`
3. The action is executed
4. Comment out the `when` clause
5. Press `Ctrl` + `\`
6. This time the action is not executed

```
[2022-09-10 18:46:30.596] [renderer1] [info] [KeybindingService]: / Received  keydown event - modifiers: [ctrl], code: ControlLeft, keyCode: 17, key: Control
[2022-09-10 18:46:30.613] [renderer1] [info] [KeybindingService]: | Converted keydown event - modifiers: [ctrl], code: ControlLeft, keyCode: 5 ('Ctrl')
[2022-09-10 18:46:30.613] [renderer1] [info] [KeybindingService]: \ Keyboard event cannot be dispatched in keydown phase.
[2022-09-10 18:46:30.804] [renderer1] [info] [KeybindingService]: / Received  keydown event - modifiers: [ctrl], code: Backslash, keyCode: 220, key: ]
[2022-09-10 18:46:30.804] [renderer1] [info] [KeybindingService]: | Converted keydown event - modifiers: [ctrl], code: Backslash, keyCode: 88 ('\')
[2022-09-10 18:46:30.804] [renderer1] [info] [KeybindingService]: | Resolving ctrl+\
[2022-09-10 18:46:30.805] [renderer1] [info] [KeybindingService]: \ From 1 keybinding entries, matched workbench.action.splitEditor, when: no when condition, source: built-in.
[2022-09-10 18:46:30.805] [renderer1] [info] [KeybindingService]: + Invoking command workbench.action.splitEditor.
[2022-09-10 18:46:30.939] [renderer1] [info] [KeybindingService]: + Ignoring single modifier ctrl due to it being pressed together with other keys.
```

### Expected result:

The action should not be executed.




Issue discussion:

Solution patch:
diff --git a/src/vs/platform/keybinding/common/keybindingResolver.ts b/src/vs/platform/keybinding/common/keybindingResolver.ts
--- a/src/vs/platform/keybinding/common/keybindingResolver.ts
+++ b/src/vs/platform/keybinding/common/keybindingResolver.ts
@@ -70,7 +70,10 @@ export class KeybindingResolver {
 		if (keypressChordPart && defaultKb.keypressParts[1] !== keypressChordPart) {
 			return false;
 		}
-		if (when) {
+
+		// `true` means always, as does `undefined`
+		// so we will treat `true` === `undefined`
+		if (when && when.type !== ContextKeyExprType.True) {
 			if (!defaultKb.when) {
 				return false;
 			}


Test patch:
diff --git a/src/vs/platform/keybinding/test/common/keybindingResolver.test.ts b/src/vs/platform/keybinding/test/common/keybindingResolver.test.ts
--- a/src/vs/platform/keybinding/test/common/keybindingResolver.test.ts
+++ b/src/vs/platform/keybinding/test/common/keybindingResolver.test.ts
@@ -235,7 +235,7 @@ suite('KeybindingResolver', () => {
 		]);
 	});
 
-	test('issue #157751: Keyboard Shortcuts: Change When Expression might actually remove keybinding in Insiders', () => {
+	test('issue #157751: Auto-quoting of context keys prevents removal of keybindings via UI', () => {
 		const defaults = [
 			kbItem(KeyCode.KeyA, 'command1', null, ContextKeyExpr.deserialize(`editorTextFocus && activeEditor != workbench.editor.notebook && editorLangId in julia.supportedLanguageIds`), true),
 		];
@@ -246,6 +246,17 @@ suite('KeybindingResolver', () => {
 		assert.deepStrictEqual(actual, []);
 	});
 
+	test('issue #160604: Remove keybindings with when clause does not work', () => {
+		const defaults = [
+			kbItem(KeyCode.KeyA, 'command1', null, undefined, true),
+		];
+		const overrides = [
+			kbItem(KeyCode.KeyA, '-command1', null, ContextKeyExpr.true(), false),
+		];
+		const actual = KeybindingResolver.handleRemovals([...defaults, ...overrides]);
+		assert.deepStrictEqual(actual, []);
+	});
+
 	test('contextIsEntirelyIncluded', () => {
 		const toContextKeyExpression = (expr: ContextKeyExpression | string | null) => {
 			if (typeof expr === 'string' || !expr) {