Merge branch 'dev/migrie/fhl/vscode-autocomplete-prototype' into dev/migrie/fhl/tasks-view-2022

This commit is contained in:
Mike Griese
2022-09-15 09:21:00 -05:00
41 changed files with 522 additions and 10 deletions

View File

@@ -183,6 +183,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Terminal.Control.
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Terminal.Control", "src\cascadia\TerminalControl\dll\TerminalControl.vcxproj", "{CA5CAD1A-F542-4635-A069-7CAEFB930070}"
ProjectSection(ProjectDependencies) = postProject
{3C67784E-1453-49C2-9660-483E2CC7F7AD} = {3C67784E-1453-49C2-9660-483E2CC7F7AD}
{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED} = {CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED}
EndProjectSection
EndProject

2
gitbranch.cmd Normal file
View File

@@ -0,0 +1,2 @@
@echo off
git branch | D:\dev\private\OpenConsole\bin\x64\Debug\Scratch.exe --prefix "git checkout "

View File

@@ -50,6 +50,7 @@ namespace winrt::TerminalApp::implementation
{
case ShortcutAction::SetColorScheme:
case ShortcutAction::AdjustOpacity:
case ShortcutAction::SendInput:
{
_RunRestorePreviews();
break;
@@ -150,6 +151,12 @@ namespace winrt::TerminalApp::implementation
case ShortcutAction::AdjustOpacity:
_PreviewAdjustOpacity(args.Args().try_as<AdjustOpacityArgs>());
break;
case ShortcutAction::SendInput:
{
// _PreviewSendInput(args.Args().try_as<SendInputArgs>());
break;
}
}
// GH#9818 Other ideas for actions that could be preview-able:
@@ -163,6 +170,27 @@ namespace winrt::TerminalApp::implementation
_lastPreviewedAction = args;
}
void TerminalPage::_PreviewSendInput(const Settings::Model::SendInputArgs& args)
{
const auto backup = _restorePreviewFuncs.empty();
_ApplyToActiveControls([&](const auto& control) {
// // Stash a copy of the original opacity.
// auto originalOpacity{ control.BackgroundOpacity() };
// Apply the new opacity
control.PreviewInput(args.Input());
if (backup)
{
_restorePreviewFuncs.emplace_back([=]() {
// On dismiss:
control.PreviewInput(L"");
});
}
});
}
// Method Description:
// - Handler for the CommandPalette::PreviewAction event. The Command
// Palette will raise this even when an action is selected, but _not_

View File

@@ -225,13 +225,17 @@ namespace winrt::TerminalApp::implementation
void CommandPalette::_selectedCommandChanged(const IInspectable& /*sender*/,
const Windows::UI::Xaml::RoutedEventArgs& /*args*/)
{
const auto currentlyVisible{ Visibility() == Visibility::Visible };
const auto selectedCommand = _filteredActionsView().SelectedItem();
const auto filteredCommand{ selectedCommand.try_as<winrt::TerminalApp::FilteredCommand>() };
if (_currentMode == CommandPaletteMode::TabSwitchMode)
{
_switchToTab(filteredCommand);
}
else if (_currentMode == CommandPaletteMode::ActionMode && filteredCommand != nullptr)
else if (_currentMode == CommandPaletteMode::ActionMode &&
filteredCommand != nullptr &&
currentlyVisible)
{
if (const auto actionPaletteItem{ filteredCommand.Item().try_as<winrt::TerminalApp::ActionPaletteItem>() })
{
@@ -956,6 +960,15 @@ namespace winrt::TerminalApp::implementation
{
_updateFilteredActions();
}
else if (_currentMode == CommandPaletteMode::ActionMode)
{
auto actions = _collectFilteredActions();
_filteredActions.Clear();
for (const auto& action : actions)
{
_filteredActions.Append(action);
}
}
}
// Method Description:
@@ -1083,7 +1096,9 @@ namespace winrt::TerminalApp::implementation
{
std::copy(begin(commandsToFilter), end(commandsToFilter), std::back_inserter(actions));
}
else if (_currentMode == CommandPaletteMode::TabSearchMode || _currentMode == CommandPaletteMode::ActionMode || _currentMode == CommandPaletteMode::CommandlineMode)
else if (_currentMode == CommandPaletteMode::TabSearchMode ||
_currentMode == CommandPaletteMode::ActionMode ||
_currentMode == CommandPaletteMode::CommandlineMode)
{
for (const auto& action : commandsToFilter)
{
@@ -1369,4 +1384,30 @@ namespace winrt::TerminalApp::implementation
ApplicationState::SharedInstance().RecentCommands(single_threaded_vector(std::move(newRecentCommands)));
}
void CommandPalette::PositionManually(Windows::Foundation::Point origin, Windows::Foundation::Size size)
{
Controls::Grid::SetRow(_backdrop(), 0);
Controls::Grid::SetColumn(_backdrop(), 0);
Controls::Grid::SetRowSpan(_backdrop(), 2);
Controls::Grid::SetColumnSpan(_backdrop(), 3);
// Set thie Max* versions here, otherwise when there are few results,
// the cmdpal will _still_ be 300x300 and filled with empty space
_backdrop().MaxWidth(size.Width);
_backdrop().MaxHeight(size.Height);
_backdrop().HorizontalAlignment(HorizontalAlignment::Stretch);
_backdrop().VerticalAlignment(VerticalAlignment::Stretch);
// // We can fake this. We're only using this method for the autocomplete
// // version of the cmdpal. Set the BG to acrylic.
// const auto colorControlStyle{ Resources().Lookup(winrt::box_value(L"CommandPaletteAcrylicBackground")).as<Windows::UI::Xaml::Style>() };
// _backdrop().Style(colorControlStyle);
Windows::UI::Xaml::Thickness margins{};
margins.Left = origin.X;
margins.Top = origin.Y;
_backdrop().Margin(margins);
}
}

View File

@@ -46,6 +46,8 @@ namespace winrt::TerminalApp::implementation
void EnableTabSwitcherMode(const uint32_t startIdx, Microsoft::Terminal::Settings::Model::TabSwitcherMode tabSwitcherMode);
void EnableTabSearchMode();
void PositionManually(Windows::Foundation::Point origin, Windows::Foundation::Size size);
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, NoMatchesText, _PropertyChangedHandlers);
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, SearchBoxPlaceholderText, _PropertyChangedHandlers);

View File

@@ -33,6 +33,8 @@ namespace TerminalApp
void EnableTabSwitcherMode(UInt32 startIdx, Microsoft.Terminal.Settings.Model.TabSwitcherMode tabSwitcherMode);
void EnableTabSearchMode();
void PositionManually(Windows.Foundation.Point origin, Windows.Foundation.Size size);
event Windows.Foundation.TypedEventHandler<CommandPalette, TabBase> SwitchToTabRequested;
event Windows.Foundation.TypedEventHandler<CommandPalette, Microsoft.Terminal.Settings.Model.Command> DispatchCommandRequested;
event Windows.Foundation.TypedEventHandler<CommandPalette, String> CommandLineExecutionRequested;

View File

@@ -215,7 +215,6 @@
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Dark">
<!-- KeyChordText styles -->
<Style x:Key="KeyChordBorderStyle"
TargetType="Border">
@@ -243,7 +242,6 @@
</Style>
</ResourceDictionary>
<ResourceDictionary x:Key="Light">
<!-- KeyChordText styles -->
<Style x:Key="KeyChordBorderStyle"
TargetType="Border">
@@ -271,7 +269,6 @@
</Style>
</ResourceDictionary>
<ResourceDictionary x:Key="HighContrast">
<!-- KeyChordText styles (use XAML defaults for High Contrast theme) -->
<Style x:Key="KeyChordBorderStyle"
TargetType="Border" />

View File

@@ -287,6 +287,17 @@ namespace winrt::TerminalApp::implementation
CommandPalette().SwitchToTabRequested({ this, &TerminalPage::_OnSwitchToTabRequested });
CommandPalette().PreviewAction({ this, &TerminalPage::_PreviewActionHandler });
AutoCompleteMenu().PositionManually(Windows::Foundation::Point{ 0, 0 }, Windows::Foundation::Size{ 200, 300 });
AutoCompleteMenu().RegisterPropertyChangedCallback(UIElement::VisibilityProperty(), [this](auto&&, auto&&) {
if (AutoCompleteMenu().Visibility() == Visibility::Collapsed)
{
AutoCompletePopup().IsOpen(false);
_FocusActiveControl(nullptr, nullptr);
}
});
AutoCompleteMenu().DispatchCommandRequested({ this, &TerminalPage::_OnDispatchCommandRequested });
AutoCompleteMenu().PreviewAction({ this, &TerminalPage::_PreviewActionHandler });
// Settings AllowDependentAnimations will affect whether animations are
// enabled application-wide, so we don't need to check it each time we
// want to create an animation.
@@ -1308,7 +1319,13 @@ namespace winrt::TerminalApp::implementation
return;
}
if (const auto p = CommandPalette(); p.Visibility() == Visibility::Visible && cmd.ActionAndArgs().Action() != ShortcutAction::ToggleCommandPalette)
if (const auto p = CommandPalette(); p.Visibility() == Visibility::Visible &&
cmd.ActionAndArgs().Action() != ShortcutAction::ToggleCommandPalette)
{
p.Visibility(Visibility::Collapsed);
}
if (const auto p = AutoCompleteMenu(); p.Visibility() == Visibility::Visible &&
cmd.ActionAndArgs().Action() != ShortcutAction::ToggleCommandPalette)
{
p.Visibility(Visibility::Collapsed);
}
@@ -1476,6 +1493,8 @@ namespace winrt::TerminalApp::implementation
});
term.ShowWindowChanged({ get_weak(), &TerminalPage::_ShowWindowChangedHandler });
term.MenuChanged({ get_weak(), &TerminalPage::_ControlMenuChangedHandler });
}
// Method Description:
@@ -4233,4 +4252,49 @@ namespace winrt::TerminalApp::implementation
_activated = activated;
_updateThemeColors();
}
winrt::fire_and_forget TerminalPage::_ControlMenuChangedHandler(const IInspectable /*sender*/,
const winrt::Microsoft::Terminal::Control::MenuChangedEventArgs args)
{
// co_await winrt::resume_background();
// May be able to fake this by not creating whole Commands for these
// actions, instead just binding them at the cmdpal layer (like tab item
// vs action item)
// auto entries = control.MenuEntries();
// parse json
auto commandsCollection = Command::ParsePowerShellMenuComplete(args.MenuJson(), args.ReplacementLength());
co_await wil::resume_foreground(Dispatcher(), CoreDispatcherPriority::Normal);
auto control{ _GetActiveControl() };
if (!control)
{
co_return;
}
if (commandsCollection.Size() == 0)
{
AutoCompletePopup().IsOpen(false);
AutoCompleteMenu().Visibility(Visibility::Collapsed);
co_return;
}
// CommandPalette has an internal margin of 8, so set to -4,-4 to position closer to the actual line
AutoCompleteMenu().PositionManually(Windows::Foundation::Point{ -4, -4 }, Windows::Foundation::Size{ 300, 300 });
// CommandPalette().EnableCommandPaletteMode(CommandPaletteLaunchMode::Action);
const til::point cursorPos{ control.CursorPositionInDips() };
const auto characterSize{ control.CharacterDimensions() };
// Position relative to the actual term control
AutoCompletePopup().HorizontalOffset(cursorPos.x);
AutoCompletePopup().VerticalOffset(cursorPos.y + characterSize.Height);
AutoCompletePopup().IsOpen(true);
// ~Make visible first, then set commands. Other way around and the list
// doesn't actually update the first time (weird)~
AutoCompleteMenu().SetCommands(commandsCollection);
AutoCompleteMenu().Visibility(commandsCollection.Size() > 0 ? Visibility::Visible : Visibility::Collapsed);
}
}

View File

@@ -423,6 +423,7 @@ namespace winrt::TerminalApp::implementation
void _RunRestorePreviews();
void _PreviewColorScheme(const Microsoft::Terminal::Settings::Model::SetColorSchemeArgs& args);
void _PreviewAdjustOpacity(const Microsoft::Terminal::Settings::Model::AdjustOpacityArgs& args);
void _PreviewSendInput(const Microsoft::Terminal::Settings::Model::SendInputArgs& args);
winrt::Microsoft::Terminal::Settings::Model::ActionAndArgs _lastPreviewedAction{ nullptr };
std::vector<std::function<void()>> _restorePreviewFuncs{};
@@ -456,6 +457,8 @@ namespace winrt::TerminalApp::implementation
winrt::fire_and_forget _ShowWindowChangedHandler(const IInspectable sender, const winrt::Microsoft::Terminal::Control::ShowWindowArgs args);
winrt::fire_and_forget _ControlMenuChangedHandler(const winrt::Windows::Foundation::IInspectable sender, const winrt::Microsoft::Terminal::Control::MenuChangedEventArgs args);
#pragma region ActionHandlers
// These are all defined in AppActionHandlers.cpp
#define ON_ALL_ACTIONS(action) DECLARE_ACTION_HANDLER(action);

View File

@@ -195,6 +195,18 @@
PreviewKeyDown="_KeyDownHandler"
Visibility="Collapsed" />
<Popup x:Name="AutoCompletePopup"
HorizontalOffset="200"
IsOpen="False"
ShouldConstrainToRootBounds="False"
VerticalOffset="200">
<local:CommandPalette x:Name="AutoCompleteMenu"
VerticalAlignment="Stretch"
PreviewKeyDown="_KeyDownHandler"
Visibility="Collapsed" />
</Popup>
<!--
A TeachingTip with IsLightDismissEnabled="True" will immediately
dismiss itself if the window is unfocused (In Xaml Islands). This is
@@ -226,4 +238,5 @@
</mux:TeachingTip.Content>
</mux:TeachingTip>
</Grid>
</Page>

View File

@@ -143,6 +143,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
auto pfnPlayMidiNote = std::bind(&ControlCore::_terminalPlayMidiNote, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
_terminal->SetPlayMidiNoteCallback(pfnPlayMidiNote);
auto pfnMenuChanged = std::bind(&ControlCore::_terminalMenuChanged, this, std::placeholders::_1, std::placeholders::_2);
_terminal->MenuChangedCallback(pfnMenuChanged);
// MSFT 33353327: Initialize the renderer in the ctor instead of Initialize().
// We need the renderer to be ready to accept new engines before the SwapChainPanel is ready to go.
// If we wait, a screen reader may try to get the AutomationPeer (aka the UIA Engine), and we won't be able to attach
@@ -230,6 +233,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
});
// _updateMenu = std::make_shared<ThrottledFuncTrailing<winrt::hstring, int32_t>>(
// _dispatcher,
// UpdatePatternLocationsInterval,
// [weakThis = get_weak()](const auto& menuJson, const auto& replaceLength) {
// if (auto core{ weakThis.get() }; !core->_IsClosing())
// {
// auto args = winrt::make<MenuChangedEventArgs>(menuJson, replaceLength);
// core->_MenuChangedHandlers(*core, args);
// }
// });
UpdateSettings(settings, unfocusedAppearance);
}
@@ -1440,6 +1454,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
}
void ControlCore::_terminalMenuChanged(std::wstring_view menuJson, int32_t replaceLength)
{
// _updateMenu->Run(winrt::hstring{ menuJson }, replaceLength);
// _MenuChangedHandlers(*this, nullptr);
auto args = winrt::make_self<MenuChangedEventArgs>(winrt::hstring{ menuJson }, replaceLength);
_MenuChangedHandlers(*this, *args);
}
bool ControlCore::HasSelection() const
{
return _terminal->IsSelectionActive();

View File

@@ -232,6 +232,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
TYPED_EVENT(ShowWindowChanged, IInspectable, Control::ShowWindowArgs);
TYPED_EVENT(UpdateSelectionMarkers, IInspectable, Control::UpdateSelectionMarkersEventArgs);
TYPED_EVENT(OpenHyperlink, IInspectable, Control::OpenHyperlinkEventArgs);
TYPED_EVENT(MenuChanged, IInspectable, Control::MenuChangedEventArgs);
// clang-format on
private:
@@ -281,6 +283,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
std::shared_ptr<ThrottledFuncTrailing<>> _tsfTryRedrawCanvas;
std::unique_ptr<til::throttled_func_trailing<>> _updatePatternLocations;
std::shared_ptr<ThrottledFuncTrailing<Control::ScrollPositionChangedArgs>> _updateScrollBar;
std::shared_ptr<ThrottledFuncTrailing<winrt::hstring, int32_t>> _updateMenu;
bool _setFontSizeUnderLock(int fontSize);
void _updateFont(const bool initialUpdate = false);
@@ -299,10 +302,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
const int bufferSize);
void _terminalCursorPositionChanged();
void _terminalTaskbarProgressChanged();
void _terminalShowWindowChanged(bool showOrHide);
void _terminalPlayMidiNote(const int noteNumber,
const int velocity,
const std::chrono::microseconds duration);
void _terminalMenuChanged(std::wstring_view menuJson, int32_t replaceLength);
#pragma endregion
std::unique_ptr<MidiAudio> _midiAudio;

View File

@@ -161,5 +161,9 @@ namespace Microsoft.Terminal.Control
event Windows.Foundation.TypedEventHandler<Object, ShowWindowArgs> ShowWindowChanged;
event Windows.Foundation.TypedEventHandler<Object, UpdateSelectionMarkersEventArgs> UpdateSelectionMarkers;
event Windows.Foundation.TypedEventHandler<Object, OpenHyperlinkEventArgs> OpenHyperlink;
event Windows.Foundation.TypedEventHandler<Object, MenuChangedEventArgs> MenuChanged;
};
}

View File

@@ -14,3 +14,4 @@
#include "FoundResultsArgs.g.cpp"
#include "ShowWindowArgs.g.cpp"
#include "UpdateSelectionMarkersEventArgs.g.cpp"
#include "MenuChangedEventArgs.g.cpp"

View File

@@ -14,6 +14,7 @@
#include "FoundResultsArgs.g.h"
#include "ShowWindowArgs.g.h"
#include "UpdateSelectionMarkersEventArgs.g.h"
#include "MenuChangedEventArgs.g.h"
namespace winrt::Microsoft::Terminal::Control::implementation
{
@@ -169,4 +170,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
WINRT_PROPERTY(bool, ClearMarkers, false);
};
struct MenuChangedEventArgs : public MenuChangedEventArgsT<MenuChangedEventArgs>
{
public:
MenuChangedEventArgs(const winrt::hstring menuJson, const int32_t replaceLength) :
_MenuJson(menuJson),
_ReplacementLength(replaceLength)
{
}
WINRT_PROPERTY(winrt::hstring, MenuJson, L"");
WINRT_PROPERTY(int32_t, ReplacementLength, 0);
};
}

View File

@@ -83,4 +83,10 @@ namespace Microsoft.Terminal.Control
{
Boolean ClearMarkers { get; };
}
runtimeclass MenuChangedEventArgs
{
String MenuJson { get; };
Int32 ReplacementLength { get; };
}
}

View File

@@ -29,6 +29,13 @@ namespace Microsoft.Terminal.Control
Last
};
struct MenuEntry
{
String Name;
String Comment;
String Input;
};
// These are properties of the TerminalCore that should be queryable by the
// rest of the app.
interface ICoreState
@@ -51,6 +58,7 @@ namespace Microsoft.Terminal.Control
Microsoft.Terminal.Core.Scheme ColorScheme { get; set; };
UInt64 OwningHwnd;
void AddMark(ScrollMark mark);

View File

@@ -437,4 +437,27 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void TSFInputControl::_formatUpdatingHandler(CoreTextEditContext sender, const CoreTextFormatUpdatingEventArgs& /*args*/)
{
}
void TSFInputControl::ManuallyDisplayText(const winrt::hstring& text)
{
_focused = !text.empty();
Canvas().Visibility(text.empty() ? Visibility::Collapsed : Visibility::Visible);
_inputBuffer.clear();
// _editContext.NotifyFocusLeave();
_activeTextStart = 0;
_inComposition = false;
// HACK trim off leading DEL chars.
std::wstring_view view{ text.c_str() };
const auto strBegin = view.find_first_not_of(L"\x7f");
if (strBegin != std::wstring::npos)
{
view = view.substr(strBegin*2);
}
TextBlock().Text(winrt::hstring{ view });
TextBlock().UpdateLayout();
TryRedrawCanvas();
}
}

View File

@@ -40,6 +40,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void ClearBuffer();
void TryRedrawCanvas();
void ManuallyDisplayText(const winrt::hstring& text);
void Close();
// -------------------------------- WinRT Events ---------------------------------

View File

@@ -31,6 +31,9 @@ namespace Microsoft.Terminal.Control
void ClearBuffer();
void TryRedrawCanvas();
void ManuallyDisplayText(String text);
void Close();
}
}

View File

@@ -388,6 +388,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// - <none>
void TermControl::SendInput(const winrt::hstring& wstr)
{
PreviewInput(L"");
_core.SendInput(wstr);
}
void TermControl::ClearBuffer(Control::ClearBufferType clearType)
@@ -3109,4 +3110,35 @@ namespace winrt::Microsoft::Terminal::Control::implementation
{
_core.ColorSelection(fg, bg, matchMode);
}
Microsoft::Terminal::Core::Point TermControl::CursorPositionInDips()
{
// const auto cursorPosition{ _core.CursorPosition() };
const til::point cursorPos{ _core.CursorPosition() };
const til::size fontSize{ til::math::flooring, CharacterDimensions() };
// Convert text buffer cursor position to client coordinate position
// within the window. This point is in _pixels_
const til::point clientCursorPos{ cursorPos * fontSize };
// Get scale factor for view
const double scaleFactor = DisplayInformation::GetForCurrentView().RawPixelsPerViewPixel();
const til::point clientCursorInDips{ til::math::flooring, clientCursorPos.x / scaleFactor, clientCursorPos.y / scaleFactor };
// + SwapChainPanel().Margin().Top
auto padding{ GetPadding() };
til::point relativeToOrigin{ til::math::flooring,
clientCursorInDips.x + padding.Left,
clientCursorInDips.y + padding.Top };
return relativeToOrigin.to_core_point();
}
void TermControl::PreviewInput(const winrt::hstring& text)
{
TSFInputControl().ManuallyDisplayText(text);
}
}

View File

@@ -46,6 +46,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
Windows::Foundation::Size CharacterDimensions() const;
Windows::Foundation::Size MinimumSize();
float SnapDimensionToGrid(const bool widthOrHeight, const float dimension);
Microsoft::Terminal::Core::Point CursorPositionInDips();
void PreviewInput(const winrt::hstring& text);
void WindowVisibilityChanged(const bool showOrHide);
@@ -78,6 +80,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void ClearAllMarks();
void ScrollToMark(const Control::ScrollToMarkDirection& direction);
Windows::Foundation::Collections::IVector<Control::MenuEntry> MenuEntries() const;
#pragma endregion
void ScrollViewport(int viewTop);
@@ -146,6 +150,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
PROJECTED_FORWARDED_TYPED_EVENT(ConnectionStateChanged, IInspectable, IInspectable, _core, ConnectionStateChanged);
PROJECTED_FORWARDED_TYPED_EVENT(ShowWindowChanged, IInspectable, Control::ShowWindowArgs, _core, ShowWindowChanged);
PROJECTED_FORWARDED_TYPED_EVENT(MenuChanged , IInspectable, Control::MenuChangedEventArgs, _core, MenuChanged);
PROJECTED_FORWARDED_TYPED_EVENT(PasteFromClipboard, IInspectable, Control::PasteFromClipboardEventArgs, _interactivity, PasteFromClipboard);
TYPED_EVENT(OpenHyperlink, IInspectable, Control::OpenHyperlinkEventArgs);

View File

@@ -41,6 +41,7 @@ namespace Microsoft.Terminal.Control
event Windows.Foundation.TypedEventHandler<Object, Object> TabColorChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> ReadOnlyChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> FocusFollowMouseRequested;
event Windows.Foundation.TypedEventHandler<Object, MenuChangedEventArgs> MenuChanged;
event Windows.Foundation.TypedEventHandler<TermControl, Windows.UI.Xaml.RoutedEventArgs> Initialized;
// This is an event handler forwarder for the underlying connection.
@@ -95,5 +96,10 @@ namespace Microsoft.Terminal.Control
Windows.UI.Xaml.Media.Brush BackgroundBrush { get; };
void ColorSelection(SelectionColor fg, SelectionColor bg, Microsoft.Terminal.Core.MatchMode matchMode);
Microsoft.Terminal.Core.Point CursorPositionInDips { get; };
void PreviewInput(String text);
}
}

View File

@@ -1389,6 +1389,11 @@ void Microsoft::Terminal::Core::Terminal::TaskbarProgressChangedCallback(std::fu
_pfnTaskbarProgressChanged.swap(pfn);
}
void Microsoft::Terminal::Core::Terminal::MenuChangedCallback(std::function<void(std::wstring_view, int32_t)> pfn) noexcept
{
_pfnMenuChanged.swap(pfn);
}
// Method Description:
// - Propagates an incoming set window visibility call from the PTY up into our window control layers
// Arguments:

View File

@@ -104,6 +104,7 @@ public:
RenderSettings& GetRenderSettings() noexcept { return _renderSettings; };
const RenderSettings& GetRenderSettings() const noexcept { return _renderSettings; };
// const std::vector<Microsoft::Console::VirtualTerminal::DispatchTypes::MenuEntry>& GetMenu() const;
const std::vector<Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark>& GetScrollMarks() const;
void AddMark(const Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark& mark,
@@ -143,6 +144,11 @@ public:
bool IsConsolePty() const override;
bool IsVtInputEnabled() const override;
void NotifyAccessibilityChange(const til::rect& changedRect) override;
void InvokeMenu(std::wstring_view menuJson, int32_t replaceLength) override;
// void ClearMenu();
// void AddToMenu(const Microsoft::Console::VirtualTerminal::DispatchTypes::MenuEntry& menu);
#pragma endregion
void ClearMark();
@@ -221,6 +227,8 @@ public:
void SetShowWindowCallback(std::function<void(bool)> pfn) noexcept;
void SetPlayMidiNoteCallback(std::function<void(const int, const int, const std::chrono::microseconds)> pfn) noexcept;
void MenuChangedCallback(std::function<void(std::wstring_view, int32_t)> pfn) noexcept;
void SetCursorOn(const bool isOn);
bool IsCursorBlinkingAllowed() const noexcept;
@@ -320,6 +328,8 @@ private:
std::function<void(bool)> _pfnShowWindowChanged;
std::function<void(const int, const int, const std::chrono::microseconds)> _pfnPlayMidiNote;
std::function<void(std::wstring_view, int32_t)> _pfnMenuChanged;
RenderSettings _renderSettings;
std::unique_ptr<::Microsoft::Console::VirtualTerminal::StateMachine> _stateMachine;
std::unique_ptr<::Microsoft::Console::VirtualTerminal::TerminalInput> _terminalInput;
@@ -407,6 +417,8 @@ private:
std::vector<Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark> _scrollMarks;
// std::vector<Microsoft::Console::VirtualTerminal::DispatchTypes::MenuEntry> _menu;
static WORD _ScanCodeFromVirtualKey(const WORD vkey) noexcept;
static WORD _VirtualKeyFromScanCode(const WORD scanCode) noexcept;
static WORD _VirtualKeyFromCharacter(const wchar_t ch) noexcept;

View File

@@ -332,3 +332,48 @@ void Terminal::NotifyAccessibilityChange(const til::rect& /*changedRect*/)
{
// This is only needed in conhost. Terminal handles accessibility in another way.
}
// void Terminal::ClearMenu()
// {
// _menu.clear();
// if (_pfnMenuChanged)
// {
// _pfnMenuChanged();
// }
// }
// void Terminal::AddToMenu(const Microsoft::Console::VirtualTerminal::DispatchTypes::MenuEntry& entry)
// {
// // entry;
// // for (const auto& entry : menu)
// // {
// auto n = entry._name;
// n;
// auto a = 9;
// a++;
// a;
// _menu.push_back(entry);
// if (_pfnMenuChanged)
// {
// _pfnMenuChanged();
// }
// // }
// }
void Terminal::InvokeMenu(std::wstring_view menuJson, int32_t replaceLength)
{
// menu;
// for (const auto& entry : menu)
// {
// auto n = entry._name;
// n;
// auto a = 9;
// a++;
// a;
// }
// DebugBreak();
if (_pfnMenuChanged)
_pfnMenuChanged(menuJson, replaceLength);
}

View File

@@ -750,6 +750,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation
BASIC_FACTORY(RenameTabArgs);
BASIC_FACTORY(SwapPaneArgs);
BASIC_FACTORY(SplitPaneArgs);
BASIC_FACTORY(SendInputArgs);
BASIC_FACTORY(SetFocusModeArgs);
BASIC_FACTORY(SetFullScreenArgs);
BASIC_FACTORY(SetMaximizedArgs);

View File

@@ -192,6 +192,7 @@ namespace Microsoft.Terminal.Settings.Model
[default_interface] runtimeclass SendInputArgs : IActionArgs
{
SendInputArgs(String input);
String Input { get; };
};

View File

@@ -637,4 +637,38 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
return newCommands;
}
winrt::Windows::Foundation::Collections::IVector<Model::Command> Command::ParsePowerShellMenuComplete(winrt::hstring json, int32_t replaceLength)
{
auto data = winrt::to_string(json);
std::string errs;
static std::unique_ptr<Json::CharReader> reader{ Json::CharReaderBuilder::CharReaderBuilder().newCharReader() };
Json::Value root;
if (!reader->parse(data.data(), data.data() + data.size(), &root, &errs))
{
throw winrt::hresult_error(WEB_E_INVALID_JSON_STRING, winrt::to_hstring(errs));
}
auto result = winrt::single_threaded_vector<Model::Command>();
auto backspaces = std::wstring(::base::saturated_cast<size_t>(replaceLength), L'\x7f');
for (const auto& element : root)
{
winrt::hstring completionText;
winrt::hstring listText;
JsonUtils::GetValueForKey(element, "CompletionText", completionText);
JsonUtils::GetValueForKey(element, "ListItemText", listText);
Model::SendInputArgs args{ winrt::hstring{ fmt::format(L"{}{}", backspaces, completionText.c_str()) } };
Model::ActionAndArgs actionAndArgs{ ShortcutAction::SendInput, args };
Model::Command command{};
command.ActionAndArgs(actionAndArgs);
command.Name(listText);
result.Append(command);
}
return result;
}
}

View File

@@ -67,6 +67,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
hstring IconPath() const noexcept;
void IconPath(const hstring& val);
static Windows::Foundation::Collections::IVector<Model::Command> ParsePowerShellMenuComplete(winrt::hstring json, int32_t replaceLength);
winrt::Windows::UI::Xaml::Data::INotifyPropertyChanged::PropertyChanged_revoker propertyChangedRevoker;
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);

View File

@@ -32,8 +32,8 @@ namespace Microsoft.Terminal.Settings.Model
{
Command();
String Name { get; };
ActionAndArgs ActionAndArgs { get; };
String Name;
ActionAndArgs ActionAndArgs;
Microsoft.Terminal.Control.KeyChord Keys { get; };
void RegisterKey(Microsoft.Terminal.Control.KeyChord keys);
String KeyChordText { get; };
@@ -47,5 +47,7 @@ namespace Microsoft.Terminal.Settings.Model
Windows.Foundation.Collections.IVectorView<Profile> profiles,
Windows.Foundation.Collections.IVectorView<ColorScheme> schemes,
Windows.Foundation.Collections.IVector<SettingsLoadWarnings> warnings);
static IVector<Command> ParsePowerShellMenuComplete(String json, Int32 replaceLength);
}
}

View File

@@ -493,3 +493,7 @@ void ConhostInternalGetSet::AddMark(const Microsoft::Console::VirtualTerminal::D
{
// Not implemented for conhost.
}
void ConhostInternalGetSet::InvokeMenu(std::wstring_view /*menuJson*/, int32_t /*replaceLength*/)
{
// Not implemented for conhost.
}

View File

@@ -75,6 +75,7 @@ public:
void NotifyAccessibilityChange(const til::rect& changedRect) override;
void AddMark(const Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark& mark) override;
void InvokeMenu(std::wstring_view menuJson, int32_t replaceLength) override;
private:
Microsoft::Console::IIoProvider& _io;

View File

@@ -515,4 +515,14 @@ namespace Microsoft::Console::VirtualTerminal::DispatchTypes
// Other things we may want to think about in the future are listed in
// GH#11000
};
struct MenuEntry
{
std::wstring _name;
std::wstring _comment;
std::wstring _input;
MenuEntry(std::wstring_view name, std::wstring_view comment, std::wstring_view input) :
_name{ name }, _comment{ comment }, _input{ input }
{
}
};
}

View File

@@ -139,6 +139,8 @@ public:
virtual bool DoFinalTermAction(const std::wstring_view string) = 0;
virtual bool DoXtermJsAction(const std::wstring_view string) = 0;
virtual StringHandler DownloadDRCS(const VTInt fontNumber,
const VTParameter startChar,
const DispatchTypes::DrcsEraseControl eraseControl,

View File

@@ -78,5 +78,6 @@ namespace Microsoft::Console::VirtualTerminal
virtual void NotifyAccessibilityChange(const til::rect& changedRect) = 0;
virtual void AddMark(const Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark& mark) = 0;
virtual void InvokeMenu(std::wstring_view menuJson, int32_t replaceLength) = 0;
};
}

View File

@@ -2561,6 +2561,51 @@ bool AdaptDispatch::DoFinalTermAction(const std::wstring_view string)
return false;
}
// Method Description:
// - Performs a XtermJs action
// - Ascribes to the ITermDispatch interface
// - Currently, the actions we support are:
// * TODO!
// - Not actually used in conhost
// Arguments:
// - string: contains the parameters that define which action we do
// Return Value:
// - false in conhost, true for the SetMark action, otherwise false.
bool AdaptDispatch::DoXtermJsAction(const std::wstring_view string)
{
// This is not implemented in conhost.
if (_api.IsConsolePty())
{
// Flush the frame manually, to make sure marks end up on the right line, like the alt buffer sequence.
_renderer.TriggerFlush(false);
return false;
}
const auto parts = Utils::SplitString(string, L';');
if (parts.size() < 1)
{
return false;
}
const auto action = til::at(parts, 0);
if (action == L"Completions")
{
unsigned int replacementChars = 0;
bool succeeded = (parts.size() >= 3) &&
(Utils::StringToUint(til::at(parts, 2), replacementChars));
if (succeeded)
{
_api.InvokeMenu(parts.size() < 4 ? L"" : til::at(parts, 3),
static_cast<int32_t>(replacementChars));
}
return true;
}
return false;
}
// Method Description:
// - DECDLD - Downloads one or more characters of a dynamically redefinable
// character set (DRCS) with a specified pixel pattern. The pixel array is

View File

@@ -134,6 +134,8 @@ namespace Microsoft::Console::VirtualTerminal
bool DoFinalTermAction(const std::wstring_view string) override;
bool DoXtermJsAction(const std::wstring_view string) override;
StringHandler DownloadDRCS(const VTInt fontNumber,
const VTParameter startChar,
const DispatchTypes::DrcsEraseControl eraseControl,

View File

@@ -847,6 +847,11 @@ bool OutputStateMachineEngine::ActionOscDispatch(const wchar_t /*wch*/,
success = _dispatch->DoFinalTermAction(string);
break;
}
case OscActionCodes::XtermJsAction:
{
success = _dispatch->DoXtermJsAction(string);
break;
}
default:
// If no functions to call, overall dispatch was a failure.
success = false;

View File

@@ -189,6 +189,7 @@ namespace Microsoft::Console::VirtualTerminal
ResetBackgroundColor = 111, // Not implemented
ResetCursorColor = 112,
FinalTermAction = 133,
XtermJsAction = 633,
ITerm2Action = 1337,
};

View File

@@ -1,10 +1,60 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include <windows.h>
#include "../../inc/LibraryIncludes.h"
// #include <windows.h>
// #include <stdio.h>
// #include <iostream>
#define GS L"\x1D"
#define US L"\x1F"
#define DEL L"\x7F"
#define ST L"\x07"
std::wstring trim(const std::wstring& str,
const std::wstring& whitespace = L" \t")
{
const auto strBegin = str.find_first_not_of(whitespace);
if (strBegin == std::wstring::npos)
return L""; // no content
const auto strEnd = str.find_last_not_of(whitespace);
const auto strRange = strEnd - strBegin + 1;
return str.substr(strBegin, strRange);
}
// This wmain exists for help in writing scratch programs while debugging.
int __cdecl wmain(int /*argc*/, WCHAR* /*argv[]*/)
int __cdecl wmain(int argc, WCHAR* argv[])
{
wprintf(L"\x1b]9001;0\x07");
std::wstring prefix{};
std::wstring suffix{};
for (int i = 0; i < argc; i++)
{
std::wstring arg{ argv[i] };
if (arg == L"--prefix" && (i + 1) <= argc)
{
prefix = argv[i + 1];
i++;
}
else if (arg == L"--suffix" && (i + 1) <= argc)
{
suffix = argv[i + 1];
i++;
}
}
for (std::wstring line; std::getline(std::wcin, line);)
{
std::wstring trimmed{ trim(line) };
std::wstring command{ fmt::format(L"{}{}{}", prefix, trimmed, suffix) };
std::wstring entry{ fmt::format(L"\x1b]9001;1;{}\x7f{}\x7f{}\x7f{}\x07", trimmed, L"a comment", command, L"whatever extras we want") };
wprintf(entry.c_str());
}
return 0;
}