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

Switch context menu generation to use a flags enum of actions #15481

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
45 changes: 17 additions & 28 deletions src/cascadia/TerminalControl/ControlCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2816,14 +2816,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
}

void ControlCore::AnchorContextMenu(const til::point viewportRelativeCharacterPosition)
{
// viewportRelativeCharacterPosition is relative to the current
// viewport, so adjust for that:
const auto lock = _terminal->LockForReading();
_contextMenuBufferPosition = _terminal->GetViewport().Origin() + viewportRelativeCharacterPosition;
}

void ControlCore::_contextMenuSelectMark(
const til::point& pos,
bool (*filter)(const ::MarkExtents&),
Expand Down Expand Up @@ -2859,17 +2851,19 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
}

void ControlCore::ContextMenuSelectCommand()
void ControlCore::ContextMenuSelectCommand(Core::Point viewportRelativeCharacterPosition)
{
const auto contextMenuBufferPosition = _terminal->GetViewport().Origin() + til::point{ viewportRelativeCharacterPosition };
_contextMenuSelectMark(
_contextMenuBufferPosition,
contextMenuBufferPosition,
[](const ::MarkExtents& m) -> bool { return !m.HasCommand(); },
[](const ::MarkExtents& m) { return til::point_span{ m.end, *m.commandEnd }; });
}
void ControlCore::ContextMenuSelectOutput()
void ControlCore::ContextMenuSelectOutput(Core::Point viewportRelativeCharacterPosition)
{
const auto contextMenuBufferPosition = _terminal->GetViewport().Origin() + til::point{ viewportRelativeCharacterPosition };
_contextMenuSelectMark(
_contextMenuBufferPosition,
contextMenuBufferPosition,
[](const ::MarkExtents& m) -> bool { return !m.HasOutput(); },
[](const ::MarkExtents& m) { return til::point_span{ *m.commandEnd, *m.outputEnd }; });
}
Expand Down Expand Up @@ -2909,24 +2903,19 @@ namespace winrt::Microsoft::Terminal::Control::implementation
return false;
}

// Method Description:
// * Don't show this if the click was on the _current_ selection
// * Don't show this if the click wasn't on a mark with at least a command
// * Otherwise yea, show it.
bool ControlCore::ShouldShowSelectCommand()
MenuAction ControlCore::GetApplicableMenuActionsAtPosition(Core::Point viewportRelativeCharacterPosition)
{
// Relies on the anchor set in AnchorContextMenu
return _clickedOnMark(_contextMenuBufferPosition,
[](const ::MarkExtents& m) -> bool { return !m.HasCommand(); });
}
const auto contextMenuBufferPosition = _terminal->GetViewport().Origin() + til::point{ viewportRelativeCharacterPosition };
MenuAction r{};

// Method Description:
// * Same as ShouldShowSelectCommand, but with the mark needing output
bool ControlCore::ShouldShowSelectOutput()
{
// Relies on the anchor set in AnchorContextMenu
return _clickedOnMark(_contextMenuBufferPosition,
[](const ::MarkExtents& m) -> bool { return !m.HasOutput(); });
const auto clickedOnCommand = _clickedOnMark(contextMenuBufferPosition,
[](const ::MarkExtents& m) -> bool { return !m.HasCommand(); });
const auto clickedOnOutput = _clickedOnMark(contextMenuBufferPosition,
[](const ::MarkExtents& m) -> bool { return !m.HasOutput(); });

WI_UpdateFlag(r, MenuAction::SelectCommand, clickedOnCommand);
WI_UpdateFlag(r, MenuAction::SelectOutput, clickedOnOutput);
return r;
}

void ControlCore::PreviewInput(std::wstring_view input)
Expand Down
9 changes: 3 additions & 6 deletions src/cascadia/TerminalControl/ControlCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void SelectCommand(const bool goUp);
void SelectOutput(const bool goUp);

void ContextMenuSelectCommand();
void ContextMenuSelectOutput();
void ContextMenuSelectCommand(winrt::Microsoft::Terminal::Core::Point viewportRelativeCharacterPosition);
void ContextMenuSelectOutput(winrt::Microsoft::Terminal::Core::Point viewportRelativeCharacterPosition);
#pragma endregion

#pragma region ITerminalInput
Expand Down Expand Up @@ -258,10 +258,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
TerminalConnection::ITerminalConnection Connection();
void Connection(const TerminalConnection::ITerminalConnection& connection);

void AnchorContextMenu(til::point viewportRelativeCharacterPosition);

bool ShouldShowSelectCommand();
bool ShouldShowSelectOutput();
MenuAction GetApplicableMenuActionsAtPosition(winrt::Microsoft::Terminal::Core::Point viewportRelativeCharacterPosition);

void PreviewInput(std::wstring_view input);

Expand Down
12 changes: 8 additions & 4 deletions src/cascadia/TerminalControl/ControlCore.idl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ namespace Microsoft.Terminal.Control
IsRightButtonDown = 0x4
};

[flags] enum MenuAction {
SelectCommand = 0x1,
SelectOutput = 0x2,
};

enum ClearBufferType
{
Screen,
Expand Down Expand Up @@ -163,10 +168,9 @@ namespace Microsoft.Terminal.Control

void ColorSelection(SelectionColor fg, SelectionColor bg, Microsoft.Terminal.Core.MatchMode matchMode);

void ContextMenuSelectCommand();
void ContextMenuSelectOutput();
Boolean ShouldShowSelectCommand();
Boolean ShouldShowSelectOutput();
MenuAction GetApplicableMenuActionsAtPosition(Microsoft.Terminal.Core.Point pos);
void ContextMenuSelectCommand(Microsoft.Terminal.Core.Point pos);
void ContextMenuSelectOutput(Microsoft.Terminal.Core.Point pos);

void ClearQuickFix();

Expand Down
9 changes: 3 additions & 6 deletions src/cascadia/TerminalControl/ControlInteractivity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,12 +301,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
{
if (_core->Settings().RightClickContextMenu())
{
// Let the core know we're about to open a menu here. It has
// some separate conditional logic based on _where_ the user
// wanted to open the menu.
_core->AnchorContextMenu(terminalPosition);

auto contextArgs = winrt::make<ContextMenuRequestedEventArgs>(til::point{ pixelPosition }.to_winrt_point());
auto contextArgs = winrt::make<ContextMenuRequestedEventArgs>(
til::point{ pixelPosition }.to_winrt_point(),
terminalPosition.to_core_point());
ContextMenuRequested.raise(*this, contextArgs);
}
else
Expand Down
8 changes: 5 additions & 3 deletions src/cascadia/TerminalControl/EventArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
struct ContextMenuRequestedEventArgs : public ContextMenuRequestedEventArgsT<ContextMenuRequestedEventArgs>
{
public:
ContextMenuRequestedEventArgs(winrt::Windows::Foundation::Point pos) :
_Position(pos) {}
ContextMenuRequestedEventArgs(winrt::Windows::Foundation::Point pos, winrt::Microsoft::Terminal::Core::Point pos2) :
_PixelPosition(pos),
_TerminalPosition(pos2) {}

WINRT_PROPERTY(winrt::Windows::Foundation::Point, Position);
WINRT_PROPERTY(winrt::Windows::Foundation::Point, PixelPosition);
WINRT_PROPERTY(winrt::Microsoft::Terminal::Core::Point, TerminalPosition);
};

struct PasteFromClipboardEventArgs : public PasteFromClipboardEventArgsT<PasteFromClipboardEventArgs>
Expand Down
3 changes: 2 additions & 1 deletion src/cascadia/TerminalControl/EventArgs.idl
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ namespace Microsoft.Terminal.Control

runtimeclass ContextMenuRequestedEventArgs
{
Windows.Foundation.Point Position { get; };
Windows.Foundation.Point PixelPosition { get; };
Microsoft.Terminal.Core.Point TerminalPosition { get; };
}

runtimeclass TitleChangedEventArgs
Expand Down
26 changes: 1 addition & 25 deletions src/cascadia/TerminalControl/Resources/en-US/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -253,14 +253,6 @@ Please either install the missing font or choose another one.</value>
<value>Copy</value>
<comment>The tooltip for a copy button</comment>
</data>
<data name="PasteWithSelectionCommandButton.Label" xml:space="preserve">
<value>Paste</value>
<comment>The label of a button for pasting the contents of the clipboard.</comment>
</data>
<data name="PasteWithSelectionCommandButton.ToolTipService.ToolTip" xml:space="preserve">
<value>Paste</value>
<comment>The tooltip for a paste button</comment>
</data>
<data name="SearchCommandButton.Label" xml:space="preserve">
<value>Find...</value>
<comment>The label of a button for searching for the selected text</comment>
Expand All @@ -285,22 +277,6 @@ Please either install the missing font or choose another one.</value>
<value>Select output</value>
<comment>The tooltip for a button for selecting all of a command's output</comment>
</data>
<data name="SelectCommandWithSelectionButton.Label" xml:space="preserve">
<value>Select command</value>
<comment>The label of a button for selecting all of the text of a command</comment>
</data>
<data name="SelectCommandWithSelectionButton.ToolTipService.ToolTip" xml:space="preserve">
<value>Select command</value>
<comment>The tooltip for a button for selecting all of the text of a command</comment>
</data>
<data name="SelectOutputWithSelectionButton.Label" xml:space="preserve">
<value>Select output</value>
<comment>The label of a button for selecting all of a command's output</comment>
</data>
<data name="SelectOutputWithSelectionButton.ToolTipService.ToolTip" xml:space="preserve">
<value>Select output</value>
<comment>The tooltip for a button for selecting all of a command's output</comment>
</data>
<data name="QuickFixButton.ToolTipService.ToolTip" xml:space="preserve">
<value>Quick fix</value>
</data>
Expand Down Expand Up @@ -334,4 +310,4 @@ Please either install the missing font or choose another one.</value>
<value>Suggested input: {0}</value>
<comment>{Locked="{0}"} {0} will be replaced with a string of input that is suggested for the user to input</comment>
</data>
</root>
</root>
22 changes: 14 additions & 8 deletions src/cascadia/TerminalControl/TermControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3844,6 +3844,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
this->TransformToVisual(nullptr).TransformPoint(Windows::Foundation::Point(0, 0)) };

const auto pos = (absolutePointerPos - absoluteWindowOrigin - controlOrigin);
_lastContextMenuTerminalPosition = args.TerminalPosition();
_showContextMenuAt(pos);
}

Expand All @@ -3854,14 +3855,18 @@ namespace winrt::Microsoft::Terminal::Control::implementation
myOption.Placement(Controls::Primitives::FlyoutPlacementMode::TopEdgeAlignedLeft);
myOption.Position(controlRelativePos.to_winrt_point());

const auto applicableActions{ _core.GetApplicableMenuActionsAtPosition(_lastContextMenuTerminalPosition) };

const auto applicabilityToVisibility = [applicableActions](MenuAction a) {
return (applicableActions & a) != (MenuAction)0 ? Visibility::Visible : Visibility::Collapsed;
};

// The "Select command" and "Select output" buttons should only be
// visible if shell integration is actually turned on.
const auto shouldShowSelectCommand{ _core.ShouldShowSelectCommand() };
const auto shouldShowSelectOutput{ _core.ShouldShowSelectOutput() };
SelectCommandButton().Visibility(shouldShowSelectCommand ? Visibility::Visible : Visibility::Collapsed);
SelectOutputButton().Visibility(shouldShowSelectOutput ? Visibility::Visible : Visibility::Collapsed);
SelectCommandWithSelectionButton().Visibility(shouldShowSelectCommand ? Visibility::Visible : Visibility::Collapsed);
SelectOutputWithSelectionButton().Visibility(shouldShowSelectOutput ? Visibility::Visible : Visibility::Collapsed);
SelectCommandButton().Visibility(applicabilityToVisibility(MenuAction::SelectCommand));
SelectCommandWithSelectionButton().Visibility(applicabilityToVisibility(MenuAction::SelectCommand));
SelectOutputButton().Visibility(applicabilityToVisibility(MenuAction::SelectOutput));
SelectOutputWithSelectionButton().Visibility(applicabilityToVisibility(MenuAction::SelectOutput));

(_core.HasSelection() ? SelectionContextMenu() :
ContextMenu())
Expand All @@ -3881,6 +3886,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// * {+1,+1} if there's no selection, to be on the bottom-right corner of
// the cursor position
cursorPos += til::point{ hasSelection ? 0 : 1, 1 };
_lastContextMenuTerminalPosition = cursorPos.to_core_point();
_showContextMenuAt(_toControlOrigin(cursorPos));
}

Expand Down Expand Up @@ -4014,15 +4020,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
{
ContextMenu().Hide();
SelectionContextMenu().Hide();
_core.ContextMenuSelectCommand();
_core.ContextMenuSelectCommand(_lastContextMenuTerminalPosition);
}

void TermControl::_SelectOutputHandler(const IInspectable& /*sender*/,
const IInspectable& /*args*/)
{
ContextMenu().Hide();
SelectionContextMenu().Hide();
_core.ContextMenuSelectOutput();
_core.ContextMenuSelectOutput(_lastContextMenuTerminalPosition);
}

// Should the text cursor be displayed, even when the control isn't focused?
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalControl/TermControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
std::optional<std::chrono::high_resolution_clock::time_point> _lastAutoScrollUpdateTime;
bool _pointerPressedInBounds{ false };

winrt::Microsoft::Terminal::Core::Point _lastContextMenuTerminalPosition{};

winrt::Windows::UI::Composition::ScalarKeyFrameAnimation _bellLightAnimation{ nullptr };
winrt::Windows::UI::Composition::ScalarKeyFrameAnimation _bellDarkAnimation{ nullptr };
SafeDispatcherTimer _bellLightTimer;
Expand Down
6 changes: 3 additions & 3 deletions src/cascadia/TerminalControl/TermControl.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
Click="_CopyCommandHandler"
Icon="Copy" />
<AppBarButton x:Name="PasteWithSelectionCommandButton"
x:Uid="PasteWithSelectionCommandButton"
x:Uid="PasteCommandButton"
Click="_PasteCommandHandler"
Icon="Paste" />
<mux:CommandBarFlyout.SecondaryCommands>
Expand All @@ -69,7 +69,7 @@
Click="_SearchCommandHandler"
Icon="Find" />
<AppBarButton x:Name="SelectCommandWithSelectionButton"
x:Uid="SelectCommandWithSelectionButton"
x:Uid="SelectCommandButton"
Click="_SelectCommandHandler">
<AppBarButton.Icon>
<FontIcon FontFamily="{ThemeResource SymbolThemeFontFamily}"
Expand All @@ -78,7 +78,7 @@
</AppBarButton.Icon>
</AppBarButton>
<AppBarButton x:Name="SelectOutputWithSelectionButton"
x:Uid="SelectOutputWithSelectionButton"
x:Uid="SelectOutputButton"
Click="_SelectOutputHandler"
Icon="AlignLeft" />
</mux:CommandBarFlyout.SecondaryCommands>
Expand Down
Loading