mirror of
https://github.com/microsoft/terminal.git
synced 2026-07-08 18:16:28 +00:00
Add an action for manually invoking the control context menu (#15254)
Adds
```
{ "command": "showContextMenu", "keys": "menu" },
```
as a default action. This will manually invoke the control context menu
(from #14775), even with the setting disabled.
As discussed with Dustin.
This commit is contained in:
@@ -1241,4 +1241,14 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleShowContextMenu(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
if (const auto& control{ _GetActiveControl() })
|
||||
{
|
||||
control.ShowContextMenu();
|
||||
}
|
||||
args.Handled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2513,6 +2513,28 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
return flags;
|
||||
}
|
||||
|
||||
til::point TermControl::_toControlOrigin(const til::point terminalPos)
|
||||
{
|
||||
const auto fontSize{ CharacterDimensions() };
|
||||
|
||||
// Convert text buffer cursor position to client coordinate position
|
||||
// within the window. This point is in _pixels_
|
||||
const double clientCursorPosX = terminalPos.x * fontSize.Width;
|
||||
const double clientCursorPosY = terminalPos.y * fontSize.Height;
|
||||
|
||||
// Get scale factor for view
|
||||
const double scaleFactor = SwapChainPanel().CompositionScaleX();
|
||||
|
||||
const double clientCursorInDipsX = clientCursorPosX / scaleFactor;
|
||||
const double clientCursorInDipsY = clientCursorPosY / scaleFactor;
|
||||
|
||||
auto padding{ GetPadding() };
|
||||
til::point relativeToOrigin{ til::math::rounding,
|
||||
clientCursorInDipsX + padding.Left,
|
||||
clientCursorInDipsY + padding.Top };
|
||||
return relativeToOrigin;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Gets the corresponding viewport pixel position for the cursor
|
||||
// by excluding the padding.
|
||||
@@ -3344,10 +3366,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void TermControl::_contextMenuHandler(IInspectable /*sender*/,
|
||||
Control::ContextMenuRequestedEventArgs args)
|
||||
{
|
||||
Controls::Primitives::FlyoutShowOptions myOption{};
|
||||
myOption.ShowMode(Controls::Primitives::FlyoutShowMode::Standard);
|
||||
myOption.Placement(Controls::Primitives::FlyoutPlacementMode::TopEdgeAlignedLeft);
|
||||
|
||||
// Position the menu where the pointer is. This was the best way I found how.
|
||||
const til::point absolutePointerPos{ til::math::rounding, CoreWindow::GetForCurrentThread().PointerPosition() };
|
||||
const til::point absoluteWindowOrigin{ til::math::rounding,
|
||||
@@ -3357,8 +3375,16 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
const til::point controlOrigin{ til::math::flooring,
|
||||
this->TransformToVisual(nullptr).TransformPoint(Windows::Foundation::Point(0, 0)) };
|
||||
|
||||
const auto pos = (absolutePointerPos - absoluteWindowOrigin - controlOrigin).to_winrt_point();
|
||||
myOption.Position(pos);
|
||||
const auto pos = (absolutePointerPos - absoluteWindowOrigin - controlOrigin);
|
||||
_showContextMenuAt(pos);
|
||||
}
|
||||
|
||||
void TermControl::_showContextMenuAt(const til::point& controlRelativePos)
|
||||
{
|
||||
Controls::Primitives::FlyoutShowOptions myOption{};
|
||||
myOption.ShowMode(Controls::Primitives::FlyoutShowMode::Standard);
|
||||
myOption.Placement(Controls::Primitives::FlyoutPlacementMode::TopEdgeAlignedLeft);
|
||||
myOption.Position(controlRelativePos.to_winrt_point());
|
||||
|
||||
// The "Select command" and "Select output" buttons should only be
|
||||
// visible if shell integration is actually turned on.
|
||||
@@ -3374,6 +3400,22 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
.ShowAt(*this, myOption);
|
||||
}
|
||||
|
||||
void TermControl::ShowContextMenu()
|
||||
{
|
||||
const bool hasSelection = _core.HasSelection();
|
||||
til::point cursorPos{
|
||||
hasSelection ? _core.SelectionInfo().EndPos :
|
||||
_core.CursorPosition()
|
||||
};
|
||||
// Offset this position a bit:
|
||||
// * {+0,+1} if there's a selection. The selection endpoint is already
|
||||
// exclusive, so add one row to align to the bottom of the selection
|
||||
// * {+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 };
|
||||
_showContextMenuAt(_toControlOrigin(cursorPos));
|
||||
}
|
||||
|
||||
void TermControl::_PasteCommandHandler(const IInspectable& /*sender*/,
|
||||
const IInspectable& /*args*/)
|
||||
{
|
||||
|
||||
@@ -143,6 +143,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
void AdjustOpacity(const double opacity, const bool relative);
|
||||
|
||||
void ShowContextMenu();
|
||||
|
||||
void Detach();
|
||||
|
||||
TerminalConnection::ITerminalConnection Connection();
|
||||
@@ -320,7 +322,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
static void _ClearKeyboardState(const WORD vkey, const WORD scanCode) noexcept;
|
||||
bool _TrySendKeyEvent(const WORD vkey, const WORD scanCode, ::Microsoft::Terminal::Core::ControlKeyStates modifiers, const bool keyDown);
|
||||
|
||||
til::point _toControlOrigin(const til::point terminalPosition);
|
||||
const til::point _toTerminalOrigin(winrt::Windows::Foundation::Point cursorPosition);
|
||||
|
||||
double _GetAutoScrollSpeed(double cursorDistanceFromBorder) const;
|
||||
|
||||
void _Search(const winrt::hstring& text, const bool goForward, const bool caseSensitive);
|
||||
@@ -346,6 +350,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void _throttledUpdateScrollbar(const ScrollBarUpdate& update);
|
||||
|
||||
void _contextMenuHandler(IInspectable sender, Control::ContextMenuRequestedEventArgs args);
|
||||
void _showContextMenuAt(const til::point& controlRelativePos);
|
||||
|
||||
void _PasteCommandHandler(const IInspectable& sender, const IInspectable& args);
|
||||
void _CopyCommandHandler(const IInspectable& sender, const IInspectable& args);
|
||||
|
||||
@@ -115,6 +115,8 @@ namespace Microsoft.Terminal.Control
|
||||
|
||||
void ColorSelection(SelectionColor fg, SelectionColor bg, Microsoft.Terminal.Core.MatchMode matchMode);
|
||||
|
||||
void ShowContextMenu();
|
||||
|
||||
void Detach();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +89,7 @@ static constexpr std::string_view MarkModeKey{ "markMode" };
|
||||
static constexpr std::string_view ToggleBlockSelectionKey{ "toggleBlockSelection" };
|
||||
static constexpr std::string_view SwitchSelectionEndpointKey{ "switchSelectionEndpoint" };
|
||||
static constexpr std::string_view ColorSelectionKey{ "experimental.colorSelection" };
|
||||
static constexpr std::string_view ShowContextMenuKey{ "showContextMenu" };
|
||||
static constexpr std::string_view ExpandSelectionToWordKey{ "expandSelectionToWord" };
|
||||
static constexpr std::string_view RestartConnectionKey{ "restartConnection" };
|
||||
|
||||
@@ -418,6 +419,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
{ ShortcutAction::ToggleBlockSelection, RS_(L"ToggleBlockSelectionCommandKey") },
|
||||
{ ShortcutAction::SwitchSelectionEndpoint, RS_(L"SwitchSelectionEndpointCommandKey") },
|
||||
{ ShortcutAction::ColorSelection, MustGenerate },
|
||||
{ ShortcutAction::ShowContextMenu, RS_(L"ShowContextMenuCommandKey") },
|
||||
{ ShortcutAction::ExpandSelectionToWord, RS_(L"ExpandSelectionToWordCommandKey") },
|
||||
{ ShortcutAction::RestartConnection, RS_(L"RestartConnectionKey") },
|
||||
};
|
||||
|
||||
@@ -102,6 +102,7 @@
|
||||
ON_ALL_ACTIONS(ToggleBlockSelection) \
|
||||
ON_ALL_ACTIONS(SwitchSelectionEndpoint) \
|
||||
ON_ALL_ACTIONS(ColorSelection) \
|
||||
ON_ALL_ACTIONS(ShowContextMenu) \
|
||||
ON_ALL_ACTIONS(ExpandSelectionToWord) \
|
||||
ON_ALL_ACTIONS(CloseOtherPanes) \
|
||||
ON_ALL_ACTIONS(RestartConnection)
|
||||
|
||||
@@ -678,6 +678,9 @@
|
||||
<data name="ExpandSelectionToWordCommandKey" xml:space="preserve">
|
||||
<value>Expand selection to word</value>
|
||||
</data>
|
||||
<data name="ShowContextMenuCommandKey" xml:space="preserve">
|
||||
<value>Show context menu</value>
|
||||
</data>
|
||||
<data name="CloseOtherPanesCommandKey" xml:space="preserve">
|
||||
<value>Close all other panes</value>
|
||||
</data>
|
||||
|
||||
@@ -464,6 +464,7 @@
|
||||
{ "command": "toggleBlockSelection" },
|
||||
{ "command": "switchSelectionEndpoint" },
|
||||
{ "command": "expandSelectionToWord" },
|
||||
{ "command": "showContextMenu", "keys": "menu" },
|
||||
|
||||
// Scrollback
|
||||
{ "command": "scrollDown", "keys": "ctrl+shift+down" },
|
||||
|
||||
Reference in New Issue
Block a user