Compare commits

...

2 commits

Author SHA1 Message Date
Leonard Hecker 6e9b53750d Fixed Ctrl+Alt shortcuts conflicting with AltGr (#2235)
This moves the detection of AltGr keypresses in front of the shortcut
handling. This allows one to have Ctrl+Alt shortcuts, while
simultaneously being able to use the AltGr key for special characters.

(cherry picked from commit 4529e46d3e)
2019-08-05 15:05:01 -07:00
PankajBhojwani 2096fa5e1f Use ROW.Reset in EraseInDisplay instead of printing millions of spaces per line #2197 2019-08-01 13:48:51 -07:00
4 changed files with 65 additions and 32 deletions

View file

@ -619,35 +619,41 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
}
const auto modifiers = _GetPressedModifierKeys();
const auto vkey = static_cast<WORD>(e.OriginalKey());
// AltGr key combinations don't always contain any meaningful,
// pretranslated unicode character during WM_KEYDOWN.
// E.g. on a German keyboard AltGr+Q should result in a "@" character,
// but actually results in "Q" with Alt and Ctrl modifier states.
// By returning false though, we can abort handling this WM_KEYDOWN
// event and let the WM_CHAR handler kick in, which will be
// provided with an appropriate unicode character.
//
// GH#2235: Make sure to handle AltGr before trying keybindings,
// so Ctrl+Alt keybindings won't eat an AltGr keypress.
if (modifiers.IsAltGrPressed())
{
_HandleVoidKeyEvent();
e.Handled(false);
return;
}
const auto vkey = static_cast<WORD>(e.OriginalKey());
bool handled = false;
auto bindings = _settings.KeyBindings();
if (bindings)
{
KeyChord chord(
handled = bindings.TryKeyChord({
modifiers.IsCtrlPressed(),
modifiers.IsAltPressed(),
modifiers.IsShiftPressed(),
vkey);
handled = bindings.TryKeyChord(chord);
vkey,
});
}
if (!handled)
{
_terminal->ClearSelection();
// If the terminal translated the key, mark the event as handled.
// This will prevent the system from trying to get the character out
// of it and sending us a CharacterRecieved event.
handled = _terminal->SendKeyEvent(vkey, modifiers);
if (_cursorTimer.has_value())
{
// Manually show the cursor when a key is pressed. Restarting
// the timer prevents flickering.
_terminal->SetCursorVisible(true);
_cursorTimer.value().Start();
}
handled = _TrySendKeyEvent(vkey, modifiers);
}
// Manually prevent keyboard navigation with tab. We want to send tab to
@ -661,6 +667,45 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
e.Handled(handled);
}
// Method Description:
// - Some key events cannot be handled (e.g. AltGr combinations) and are
// delegated to the character handler. Just like with _TrySendKeyEvent(),
// the character handler counts on us though to:
// - Clears the current selection.
// - Makes the cursor briefly visible during typing.
void TermControl::_HandleVoidKeyEvent()
{
_TrySendKeyEvent(0, {});
}
// Method Description:
// - Send this particular key event to the terminal.
// See Terminal::SendKeyEvent for more information.
// - Clears the current selection.
// - Makes the cursor briefly visible during typing.
// Arguments:
// - vkey: The vkey of the key pressed.
// - states: The Microsoft::Terminal::Core::ControlKeyStates representing the modifier key states.
bool TermControl::_TrySendKeyEvent(WORD vkey, const ControlKeyStates modifiers)
{
_terminal->ClearSelection();
// If the terminal translated the key, mark the event as handled.
// This will prevent the system from trying to get the character out
// of it and sending us a CharacterRecieved event.
const auto handled = vkey ? _terminal->SendKeyEvent(vkey, modifiers) : true;
if (_cursorTimer.has_value())
{
// Manually show the cursor when a key is pressed. Restarting
// the timer prevents flickering.
_terminal->SetCursorVisible(true);
_cursorTimer.value().Start();
}
return handled;
}
// Method Description:
// - handle a mouse click event. Begin selection process.
// Arguments:

View file

@ -164,6 +164,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
static Windows::UI::Xaml::Thickness _ParseThicknessFromPadding(const hstring padding);
::Microsoft::Terminal::Core::ControlKeyStates _GetPressedModifierKeys() const;
void _HandleVoidKeyEvent();
bool _TrySendKeyEvent(WORD vkey, ::Microsoft::Terminal::Core::ControlKeyStates modifiers);
const COORD _GetTerminalPosition(winrt::Windows::Foundation::Point cursorPosition);
const unsigned int _NumberOfClicks(winrt::Windows::Foundation::Point clickPos, Timestamp clickTime);

View file

@ -210,18 +210,6 @@ bool Terminal::SendKeyEvent(const WORD vkey, const ControlKeyStates states)
_NotifyScrollEvent();
}
// AltGr key combinations don't always contain any meaningful,
// pretranslated unicode character during WM_KEYDOWN.
// E.g. on a German keyboard AltGr+Q should result in a "@" character,
// but actually results in "Q" with Alt and Ctrl modifier states.
// By returning false though, we can abort handling this WM_KEYDOWN
// event and let the WM_CHAR handler kick in, which will be
// provided with an appropriate unicode character.
if (states.IsAltGrPressed())
{
return false;
}
// Alt key sequences _require_ the char to be in the keyevent. If alt is
// pressed, manually get the character that's being typed, and put it in the
// KeyEvent.

View file

@ -337,11 +337,9 @@ bool Terminal::EraseInDisplay(const DispatchTypes::EraseType eraseType)
// and we have to make sure we erase that text
auto eraseStart = _mutableViewport.Height();
auto eraseEnd = _buffer->GetLastNonSpaceCharacter(_mutableViewport).Y;
auto eraseIter = OutputCellIterator(UNICODE_SPACE, _buffer->GetCurrentAttributes(), _mutableViewport.RightInclusive() * (eraseEnd - eraseStart + 1));
for (SHORT i = eraseStart; i <= eraseEnd; i++)
{
COORD erasePos{ 0, i };
_buffer->Write(eraseIter, erasePos);
_buffer->GetRowByOffset(i).Reset(_buffer->GetCurrentAttributes());
}
// Reset the scroll offset now because there's nothing for the user to 'scroll' to