Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass <Alt> to the application #6461

Merged
merged 7 commits into from
Jun 11, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved
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();
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved
}
}
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