Skip to content

Commit

Permalink
Let's pass <Alt> to the application
Browse files Browse the repository at this point in the history
  • Loading branch information
zadjii-msft committed Jun 11, 2020
1 parent 7fc7355 commit 1529c27
Show file tree
Hide file tree
Showing 11 changed files with 104 additions and 4 deletions.
35 changes: 35 additions & 0 deletions src/cascadia/TerminalApp/AppLogic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -939,6 +939,41 @@ namespace winrt::TerminalApp::implementation
return false;
}

// Method Description:
// - Implements the Alt handler (per GH#6421)
// Return value:
// - whether Alt was handled
bool AppLogic::OnAltReleased()
{
if (_root)
{
// Manually bubble the OnAltReleased event up through the focus tree.
auto xamlRoot{ _root->XamlRoot() };
auto focusedObject{ Windows::UI::Xaml::Input::FocusManager::GetFocusedElement(xamlRoot) };
do
{
if (auto f7Listener{ focusedObject.try_as<IAltListener>() })
{
if (f7Listener.OnAltReleased())
{
return true;
}
// otherwise, keep walking. bubble the event manually.
}

if (auto focusedElement{ focusedObject.try_as<Windows::UI::Xaml::FrameworkElement>() })
{
focusedObject = focusedElement.Parent();
}
else
{
break; // we hit a non-FE object, stop bubbling.
}
} while (focusedObject);
}
return false;
}

// Method Description:
// - Used to tell the app that the 'X' button has been clicked and
// the user wants to close the app. We kick off the close warning
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalApp/AppLogic.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ namespace winrt::TerminalApp::implementation
hstring Title();
void TitlebarClicked();
bool OnF7Pressed();
bool OnAltReleased();

void WindowCloseButtonClicked();

Expand Down
3 changes: 2 additions & 1 deletion src/cascadia/TerminalApp/AppLogic.idl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import "../TerminalPage.idl";
import "../ShortcutActionDispatch.idl";
import "../IF7Listener.idl";
import "../IAltListener.idl";

namespace TerminalApp
{
Expand All @@ -14,7 +15,7 @@ namespace TerminalApp
FullscreenMode,
};

[default_interface] runtimeclass AppLogic : IF7Listener
[default_interface] runtimeclass AppLogic : IF7Listener, IAltListener
{
AppLogic();

Expand Down
15 changes: 15 additions & 0 deletions src/cascadia/TerminalApp/IAltListener.idl
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

namespace TerminalApp
{
// C++/winrt makes it difficult to share this idl between two projects,
// Instead, we just pin the uuid and include it in both TermControl and App
// If you update this one, please update the one in TerminalControl\TermControl.idl
// If you change this interface, please update the guid.
// If you press Alt and get a runtime error, go make sure both copies are the same.
[uuid("36a6554d-07e9-4861-8d8b-5d882de31e75")]
interface IAltListener {
Boolean OnAltReleased();
}
}
1 change: 1 addition & 0 deletions src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@
<!-- If you add idl files here, make sure to include their implementation's
header in TerminalApp.vcxproj (as well as in this file) -->
<Midl Include="../IF7Listener.idl" />
<Midl Include="../IAltListener.idl" />
<Midl Include="../App.idl">
<DependentUpon>../App.xaml</DependentUpon>
</Midl>
Expand Down
13 changes: 13 additions & 0 deletions src/cascadia/TerminalControl/TermControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,19 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
return handled;
}

// Method Description:
// - Manually generate an Alt KeyUp event into the key bindings or terminal.
// This is required as part of GH#6421.
// - This is basically the same thing as the F7 hack above, but with Alt KeyUp instead.
// Return value:
// - Whether Alt was handled.
bool TermControl::OnAltReleased()
{
const auto modifiers{ _GetPressedModifierKeys() };
(void)_TrySendKeyEvent(VK_MENU, 0, modifiers, false);
return true;
}

void TermControl::_KeyDownHandler(winrt::Windows::Foundation::IInspectable const& /*sender*/,
Input::KeyRoutedEventArgs const& e)
{
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalControl/TermControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
void CreateSearchBoxControl();

bool OnF7Pressed();
bool OnAltReleased();

bool OnMouseWheel(const Windows::Foundation::Point location, const int32_t delta);

Expand Down
12 changes: 9 additions & 3 deletions src/cascadia/TerminalControl/TermControl.idl
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,17 @@ namespace Microsoft.Terminal.TerminalControl
// If you change this interface, please update the guid.
// If you press F7 and get a runtime error, go make sure both copies are the same.
[uuid("339e1a87-5315-4da6-96f0-565549b6472b")]
interface IF7Listener
{
interface IF7Listener {
Boolean OnF7Pressed();
}

// Same as the above, but with Alt
[uuid("36a6554d-07e9-4861-8d8b-5d882de31e75")]
interface IAltListener
{
Boolean OnAltReleased();
}

runtimeclass CopyToClipboardEventArgs
{
String Text { get; };
Expand All @@ -32,7 +38,7 @@ namespace Microsoft.Terminal.TerminalControl
void HandleClipboardData(String data);
}

[default_interface] runtimeclass TermControl : Windows.UI.Xaml.Controls.UserControl, IF7Listener, IMouseWheelListener
[default_interface] runtimeclass TermControl : Windows.UI.Xaml.Controls.UserControl, IF7Listener, IAltListener, IMouseWheelListener
{
TermControl();
TermControl(Microsoft.Terminal.Settings.IControlSettings settings, Microsoft.Terminal.TerminalConnection.ITerminalConnection connection);
Expand Down
9 changes: 9 additions & 0 deletions src/cascadia/WindowsTerminal/AppHost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,15 @@ bool AppHost::OnF7Pressed()
return false;
}

bool AppHost::OnAltReleased()
{
if (_logic)
{
return _logic.OnAltReleased();
}
return false;
}

// Method Description:
// - Retrieve any commandline args passed on the commandline, and pass them to
// the app logic for processing.
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/WindowsTerminal/AppHost.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class AppHost
void LastTabClosed(const winrt::Windows::Foundation::IInspectable& sender, const winrt::TerminalApp::LastTabClosedEventArgs& args);
void Initialize();
bool OnF7Pressed();
bool OnAltReleased();

private:
bool _useNonClientArea;
Expand Down
17 changes: 17 additions & 0 deletions src/cascadia/WindowsTerminal/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ static bool _messageIsF7Keypress(const MSG& message)
{
return (message.message == WM_KEYDOWN || message.message == WM_SYSKEYDOWN) && message.wParam == VK_F7;
}
static bool _messageIsAltKeyup(const MSG& message)
{
return (message.message == WM_KEYUP || message.message == WM_SYSKEYUP) && message.wParam == VK_MENU;
}

int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
{
Expand Down Expand Up @@ -144,6 +148,19 @@ int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
}
}

// GH#6421 - System XAML will never send an Alt KeyUp event. So, similar
// to how we'll steal the F7 KeyDown above, we'll steal the Alt KeyUp
// here, and plumb it through.
if (_messageIsAltKeyup(message))
{
// Let's pass <Alt> to the application
if (host.OnAltReleased())
{
// The application consumed the Alt. Don't let Xaml get it.
continue;
}
}

TranslateMessage(&message);
DispatchMessage(&message);
}
Expand Down

1 comment on commit 1529c27

@github-actions

This comment was marked as outdated.

Please sign in to comment.