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

Add support for a right-click context menu #14775

Merged
merged 36 commits into from
Mar 17, 2023

Conversation

zadjii-msft
Copy link
Member

@zadjii-msft zadjii-msft commented Feb 2, 2023

Experimental for now. experimental.rightClickContextMenu, a per-profile setting. Long term we want to enable full mouse bindings, at which point this would be replaced.

Closes #3337

This adds two context menus to the TermControl - one for right-clicking with a selection, and one without. The implementation is designed to follows the API experience of the context menu on something like a RichEditBox. The hosting application adds a handler for the menu's Opening event, and appends whatever items it wants at that time.

So TermControl only implements a few "actions" by default - copy, past, find. TerminalApp is then responsible for adding anything else it needs. Right now, those actions are:

  • Duplicate tab
  • Duplicate pane
  • Close Tab
  • Close pane

Screenshots in #14775 (comment)

@github-actions

This comment has been minimized.

@zadjii-msft
Copy link
Member Author

The default context menu:

image

With a selection:
image

When there are multiple panes, "Close pane" gets added
image

src/cascadia/TerminalApp/Resources/en-US/Resources.resw Outdated Show resolved Hide resolved
src/cascadia/TerminalApp/TerminalPage.h Outdated Show resolved Hide resolved
src/cascadia/TerminalApp/TerminalPage.cpp Show resolved Hide resolved
Comment on lines 4511 to 4515
// Only wire up "Close Pane" if there's multiple panes.
if (_GetFocusedTabImpl()->GetLeafPaneCount() > 1)
{
makeItem(RS_(L"ClosePaneContextMenuEntryText"), L"\xE89F", ActionAndArgs{ ShortcutAction::ClosePane, nullptr });
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like guidance is that we should always include this option, but disable it if it can't be used. That way, the user can always see what options are available.

Ironically, ClosePane is still valid though, so maybe we shouldn't even disable/remove it at all haha.

Curious what others think

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My consideration was that when there's only one pane, closeTab == closePane. So putting closePane there, even if it's disabled, just adds noise. That's my thought. Furthermore, just doing closePane when there's only one pane might confuse people who don't get that there are panes (probably most people)

src/cascadia/TerminalControl/EventArgs.idl Outdated Show resolved Hide resolved
src/cascadia/TerminalControl/TermControl.h Outdated Show resolved Hide resolved
src/cascadia/TerminalControl/TermControl.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalControl/TermControl.xaml Outdated Show resolved Hide resolved
src/inc/til/winrt.h Outdated Show resolved Hide resolved
src/inc/til/winrt.h Outdated Show resolved Hide resolved
@zadjii-msft zadjii-msft added Area-User Interface Issues pertaining to the user interface of the Console or Terminal Product-Terminal The new Windows Terminal. labels Feb 5, 2023
@zadjii-msft
Copy link
Member Author

Copy link
Member

@DHowett DHowett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

partway through (11/24) but I've got to go for now

src/cascadia/TerminalApp/TerminalPage.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalApp/TerminalPage.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalApp/TerminalPage.cpp Show resolved Hide resolved
makeItem(RS_(L"SplitPaneText"), L"\xF246", ActionAndArgs{ ShortcutAction::SplitPane, SplitPaneArgs{ SplitType::Duplicate } });
makeItem(RS_(L"DuplicateTabText"), L"\xF5ED", ActionAndArgs{ ShortcutAction::DuplicateTab, nullptr });

// Only wire up "Close Pane" if there's multiple panes.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Design q: should we display this but leave it disabled?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given past conversations on the repo, I reckon that most users don't even know what a Pane is, so that might be confusing. I erred on the side of "display the fewest possible valid options".

I am open to being overruled, idgaf.

src/cascadia/TerminalApp/TerminalPage.cpp Outdated Show resolved Hide resolved
Comment on lines +208 to +209
ctrlEnabled &&
!hyperlink.empty())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: change req'd?

src/cascadia/TerminalControl/ControlInteractivity.cpp Outdated Show resolved Hide resolved
{
// formats = nullptr -> copy all formats
_interactivity.CopySelectionToClipboard(false, nullptr);
ContextMenu().Hide();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If somebody else provides the implementation of the command handler, how do THEY get to hide the menu?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose makeCallback could have called Hide itself. I guess I never hit that in selfhosting. Interesting...

Copy link
Member

@DHowett DHowett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe your build failure is due to TerminalControl rolling up a duplicate copy of MUX (if i had to guess). Otherwise... looks good.

Copy link
Member

@carlos-zamora carlos-zamora left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving, but not adding "Automerge" in case you want to go in and resolve my suggestions.

@@ -22,6 +22,11 @@ namespace Microsoft.Terminal.Control
Windows.Foundation.IReference<CopyFormat> Formats { get; };
}

runtimeclass ContextMenuRequestedEventArgs
{
Windows.Foundation.Point Point { get; };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is such a nit, but I don't like that it's a Point Point. Maybe rename it to Position?

Comment on lines 164 to 173
control->ContextMenu().PrimaryCommands().Clear();
control->ContextMenu().SecondaryCommands().Clear();
for (const auto& e : control->_originalPrimaryElements)
{
control->ContextMenu().PrimaryCommands().Append(e);
}
for (const auto& e : control->_originalSecondaryElements)
{
control->ContextMenu().SecondaryCommands().Append(e);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
control->ContextMenu().PrimaryCommands().Clear();
control->ContextMenu().SecondaryCommands().Clear();
for (const auto& e : control->_originalPrimaryElements)
{
control->ContextMenu().PrimaryCommands().Append(e);
}
for (const auto& e : control->_originalSecondaryElements)
{
control->ContextMenu().SecondaryCommands().Append(e);
}
auto& menu = control->ContextMenu();
menu.PrimaryCommands().Clear();
menu.SecondaryCommands().Clear();
for (const auto& e : control->_originalPrimaryElements)
{
menu.PrimaryCommands().Append(e);
}
for (const auto& e : control->_originalSecondaryElements)
{
menu.SecondaryCommands().Append(e);
}

Comment on lines 179 to 188
control->SelectionContextMenu().PrimaryCommands().Clear();
control->SelectionContextMenu().SecondaryCommands().Clear();
for (const auto& e : control->_originalSelectedPrimaryElements)
{
control->SelectionContextMenu().PrimaryCommands().Append(e);
}
for (const auto& e : control->_originalSelectedSecondaryElements)
{
control->SelectionContextMenu().SecondaryCommands().Append(e);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
control->SelectionContextMenu().PrimaryCommands().Clear();
control->SelectionContextMenu().SecondaryCommands().Clear();
for (const auto& e : control->_originalSelectedPrimaryElements)
{
control->SelectionContextMenu().PrimaryCommands().Append(e);
}
for (const auto& e : control->_originalSelectedSecondaryElements)
{
control->SelectionContextMenu().SecondaryCommands().Append(e);
}
auto& menu = control->SelectionContextMenu();
menu.PrimaryCommands().Clear();
menu.SecondaryCommands().Clear();
for (const auto& e : control->_originalSelectedPrimaryElements)
{
menu.PrimaryCommands().Append(e);
}
for (const auto& e : control->_originalSelectedSecondaryElements)
{
menu.SecondaryCommands().Append(e);
}

Comment on lines 476 to 477
_useRightClickContextMenu = settings.RightClickContextMenu();

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we use _useRightClickContextMenu anywhere? Why can't we call _settings.RightClickContextMenu() when we need it?

@carlos-zamora carlos-zamora removed their assignment Mar 17, 2023
@DHowett DHowett merged commit 7383b26 into main Mar 17, 2023
@DHowett DHowett deleted the dev/migrie/f/3337-just-for-funsies branch March 17, 2023 18:54
DHowett pushed a commit that referenced this pull request May 11, 2023
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.
@EduardDurech
Copy link

Would it be possible to allow the "See less" and "See more" to be persistent? At the moment, when I click "See less" it only stays while active, consecutive right-clicks show the expanded context menu

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-User Interface Issues pertaining to the user interface of the Console or Terminal Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Product-Terminal The new Windows Terminal.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Request: Right-click menu inside TerminalControl (w/ Copy & Paste?)
4 participants