Skip to content

Commit

Permalink
Allow Ctrl+Alt <> AltGr aliasing to be disabled (#6212)
Browse files Browse the repository at this point in the history
## Summary of the Pull Request

Some people wish to use Ctrl+Alt combinations without Windows treating those as an alias for AltGr combinations. This PR adds a new `altGrAliasing` setting allowing one to control this behavior.

## PR Checklist
* [x] Closes #6211
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [x] Manual testing
* [x] Requires documentation to be updated: MicrosoftDocs/terminal#50
* [x] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx

## Validation Steps Performed

* Choose a German keyboard layout
* Using `showkey -a` ensured that both `Ctrl+Alt+Q/E` and `AltGr+Q/E` produce `@/€`
* Added `"altGrAliasing": false` to the WSL profile
* Using `showkey -a` ensured `Ctrl+Alt+Q/E` now produces `^[^Q/E` while `AltGr+Q/E` continues to produce `@/€`
  • Loading branch information
donno2048 committed Jun 5, 2020
1 parent 9921d86 commit 4018876
Show file tree
Hide file tree
Showing 11 changed files with 33 additions and 4 deletions.
1 change: 1 addition & 0 deletions doc/cascadia/SettingsSchema.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ Properties listed below are specific to each unique profile.
| `scrollbarState` | Optional | String | `"visible"` | Defines the visibility of the scrollbar. Possible values: `"visible"`, `"hidden"` |
| `selectionBackground` | Optional | String | | Sets the selection background color of the profile. Overrides `selectionBackground` set in color scheme if `colorscheme` is set. Uses hex color format: `"#rrggbb"`. |
| `snapOnInput` | Optional | Boolean | `true` | When set to `true`, the window will scroll to the command input line when typing. When set to `false`, the window will not scroll when you start typing. |
| `altGrAliasing` | Optional | Boolean | `true` | By default Windows treats Ctrl+Alt as an alias for AltGr. When altGrAliasing is set to false, this behavior will be disabled. |
| `source` | Optional | String | | Stores the name of the profile generator that originated this profile. _There are no discoverable values for this field._ |
| `startingDirectory` | Optional | String | `%USERPROFILE%` | The directory the shell starts in when it is loaded. |
| `suppressApplicationTitle` | Optional | Boolean | `false` | When set to `true`, `tabTitle` overrides the default title of the tab and any title change messages from the application will be suppressed. When set to `false`, `tabTitle` behaves as normal. |
Expand Down
5 changes: 5 additions & 0 deletions doc/cascadia/profiles.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,11 @@
"description": "When set to true, the window will scroll to the command input line when typing. When set to false, the window will not scroll when you start typing.",
"type": "boolean"
},
"altGrAliasing": {
"default": true,
"description": "By default Windows treats Ctrl+Alt as an alias for AltGr. When altGrAliasing is set to false, this behavior will be disabled.",
"type": "boolean"
},
"source": {
"description": "Stores the name of the profile generator that originated this profile.",
"type": ["string", "null"]
Expand Down
5 changes: 5 additions & 0 deletions src/cascadia/TerminalApp/Profile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ static constexpr std::string_view TabTitleKey{ "tabTitle" };
static constexpr std::string_view SuppressApplicationTitleKey{ "suppressApplicationTitle" };
static constexpr std::string_view HistorySizeKey{ "historySize" };
static constexpr std::string_view SnapOnInputKey{ "snapOnInput" };
static constexpr std::string_view AltGrAliasingKey{ "altGrAliasing" };
static constexpr std::string_view CursorColorKey{ "cursorColor" };
static constexpr std::string_view CursorShapeKey{ "cursorShape" };
static constexpr std::string_view CursorHeightKey{ "cursorHeight" };
Expand Down Expand Up @@ -121,6 +122,7 @@ Profile::Profile(const std::optional<GUID>& guid) :
_suppressApplicationTitle{},
_historySize{ DEFAULT_HISTORY_SIZE },
_snapOnInput{ true },
_altGrAliasing{ true },
_cursorShape{ CursorStyle::Bar },
_cursorHeight{ DEFAULT_CURSOR_HEIGHT },

Expand Down Expand Up @@ -188,6 +190,7 @@ TerminalSettings Profile::CreateTerminalSettings(const std::unordered_map<std::w
// Fill in the Terminal Setting's CoreSettings from the profile
terminalSettings.HistorySize(_historySize);
terminalSettings.SnapOnInput(_snapOnInput);
terminalSettings.AltGrAliasing(_altGrAliasing);
terminalSettings.CursorHeight(_cursorHeight);
terminalSettings.CursorShape(_cursorShape);

Expand Down Expand Up @@ -475,6 +478,8 @@ void Profile::LayerJson(const Json::Value& json)

JsonUtils::GetBool(json, SnapOnInputKey, _snapOnInput);

JsonUtils::GetBool(json, AltGrAliasingKey, _altGrAliasing);

JsonUtils::GetUInt(json, CursorHeightKey, _cursorHeight);

if (json.isMember(JsonKey(CursorShapeKey)))
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalApp/Profile.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ class TerminalApp::Profile final
bool _suppressApplicationTitle;
int32_t _historySize;
bool _snapOnInput;
bool _altGrAliasing;
uint32_t _cursorHeight;
winrt::Microsoft::Terminal::Settings::CursorStyle _cursorShape;

Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalApp/defaults-universal.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"icon": "ms-appx:///ProfileIcons/{550ce7b8-d500-50ad-8a1a-c400c3262db3}.png",
"padding": "8, 8, 8, 8",
"snapOnInput": true,
"altGrAliasing": true,
"useAcrylic": false,
"backgroundImage": "ms-appx:///internal-background.png",
"backgroundImageAlignment": "bottomRight",
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalApp/defaults.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"historySize": 9001,
"padding": "8, 8, 8, 8",
"snapOnInput": true,
"altGrAliasing": true,
"startingDirectory": "%USERPROFILE%",
"useAcrylic": false
},
Expand All @@ -60,6 +61,7 @@
"historySize": 9001,
"padding": "8, 8, 8, 8",
"snapOnInput": true,
"altGrAliasing": true,
"startingDirectory": "%USERPROFILE%",
"useAcrylic": false
}
Expand Down
17 changes: 13 additions & 4 deletions src/cascadia/TerminalCore/Terminal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,9 @@ void Terminal::UpdateSettings(winrt::Microsoft::Terminal::Settings::ICoreSetting
}

_snapOnInput = settings.SnapOnInput();

_altGrAliasing = settings.AltGrAliasing();
_wordDelimiters = settings.WordDelimiters();

_suppressApplicationTitle = settings.SuppressApplicationTitle();

_startingTitle = settings.StartingTitle();

// TODO:MSFT:21327402 - if HistorySize has changed, resize the buffer so we
Expand Down Expand Up @@ -419,6 +417,7 @@ bool Terminal::SendKeyEvent(const WORD vkey, const WORD scanCode, const ControlK
_StoreKeyEvent(vkey, scanCode);

const auto isAltOnlyPressed = states.IsAltPressed() && !states.IsCtrlPressed();
const auto isSuppressedAltGrAlias = !_altGrAliasing && states.IsAltPressed() && states.IsCtrlPressed();

// DON'T manually handle Alt+Space - the system will use this to bring up
// the system menu for restore, min/maximize, size, move, close.
Expand All @@ -428,7 +427,17 @@ bool Terminal::SendKeyEvent(const WORD vkey, const WORD scanCode, const ControlK
return false;
}

const auto ch = _CharacterFromKeyEvent(vkey, scanCode, states);
// By default Windows treats Ctrl+Alt as an alias for AltGr.
// When the altGrAliasing setting is set to false, this behaviour should be disabled.
//
// Whenever possible _CharacterFromKeyEvent() will return a valid character.
// For instance both Ctrl+Alt+Q as well as AltGr+Q return @ on a German keyboard.
//
// We can achieve the altGrAliasing functionality by skipping the call to _CharacterFromKeyEvent,
// as TerminalInput::HandleKey will then fall back to using the vkey which
// is the underlying ASCII character (e.g. A-Z) on the keyboard in our case.
// See GH#5525/GH#6211 for more details
const auto ch = isSuppressedAltGrAlias ? UNICODE_NULL : _CharacterFromKeyEvent(vkey, scanCode, states);

// Delegate it to the character event handler if this key event can be
// mapped to one (see method description above). For Alt+key combinations
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalCore/Terminal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ class Microsoft::Terminal::Core::Terminal final :
COLORREF _defaultBg;

bool _snapOnInput;
bool _altGrAliasing;
bool _suppressApplicationTitle;

#pragma region Text Selection
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettings/ICoreSettings.idl
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ namespace Microsoft.Terminal.Settings
Int32 RowsToScroll;

Boolean SnapOnInput;
Boolean AltGrAliasing;

UInt32 CursorColor;
CursorStyle CursorShape;
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettings/terminalsettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
GETSET_PROPERTY(int32_t, InitialCols, 80);

GETSET_PROPERTY(bool, SnapOnInput, true);
GETSET_PROPERTY(bool, AltGrAliasing, true);
GETSET_PROPERTY(uint32_t, CursorColor, DEFAULT_CURSOR_COLOR);
GETSET_PROPERTY(CursorStyle, CursorShape, CursorStyle::Vintage);
GETSET_PROPERTY(uint32_t, CursorHeight, DEFAULT_CURSOR_HEIGHT);
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/UnitTests_TerminalCore/MockTermSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ namespace TerminalCoreUnitTests
uint32_t DefaultForeground() { return COLOR_WHITE; }
uint32_t DefaultBackground() { return COLOR_BLACK; }
bool SnapOnInput() { return false; }
bool AltGrAliasing() { return true; }
uint32_t CursorColor() { return COLOR_WHITE; }
CursorStyle CursorShape() const noexcept { return CursorStyle::Vintage; }
uint32_t CursorHeight() { return 42UL; }
Expand All @@ -49,6 +50,7 @@ namespace TerminalCoreUnitTests
void DefaultForeground(uint32_t) {}
void DefaultBackground(uint32_t) {}
void SnapOnInput(bool) {}
void AltGrAliasing(bool) {}
void CursorColor(uint32_t) {}
void CursorShape(CursorStyle const&) noexcept {}
void CursorHeight(uint32_t) {}
Expand Down

0 comments on commit 4018876

Please sign in to comment.