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

Miscellaneous bug fixes for Mark Mode #13358

Merged
merged 13 commits into from
Jul 1, 2022
Merged

Conversation

carlos-zamora
Copy link
Member

@carlos-zamora carlos-zamora commented Jun 22, 2022

Summary of the Pull Request

  1. [copy on select] when manually copying text (i.e. kbd or right-click) while in mark/quick-edit mode, we now dismiss the selection.
  2. Enter is now bound to copy by default.
    • This works very well with mark mode and provides a more consistent behavior with conhost's selection experience overall.
    • "why not hardcode Enter as a way to copy when in mark mode?"
      • In an effort to make this as configurable as possible, I decided to make it a configurable keybinding, but am open to suggestions.
  3. selection markers
    a. we now hide the selection markers when multi-clicking the terminal.
    b. selection markers are now properly shown when a single cell selection exists
    • Prior to this PR, any single cell selection would display both markers. Now, we actually track which endpoint we're moving and display the appropriate one.
  4. ensures that when you use keyboard selection to move past the top/bottom of the scroll area, we clamp it to the origin/bottom-right respectively. The fix is also better here in that it provides consistent behavior across all of the _MoveByX functions.
  5. adds toggleBlockSelection to the schema

References

#13053

Validation Steps Performed

Did a whole flowchart of expected behavior with copy on select:

  • enable copyOnSelect
    • make a selection with the mouse
      • ✅ right-click should copy the text --> clear the selection --> paste
    • use keyboard selection to quick-edit the existing selection
      • copy action should clear the selection
      • ✅ right-click should copy the text --> clear the selection --> paste

Played with selection markers a bit in mark mode and quick edit mode. Markers are updating appropriately.

@carlos-zamora

This comment was marked as outdated.

@carlos-zamora
Copy link
Member Author

Discussion points

  1. How do we feel about Enter being bound to copy() by default?
    • It's consistent with conhost, and worst-case, people can disable it. I don't expect people to bind Enter to anything nowadays anyways.
  2. Should we backport a fix for the copy on select stuff?
    • It's a decently sized fix and nobody's complained about it. Ethically, we should, but there is some risk due to the size. I'd basically copy over anything that references IsInQuickEditMode().
  3. Also found another "bug?" where if you select empty text while copy on select is enabled, we end up copying literally nothing. I'm guessing this is because we switched the default copy() behavior to trimming whitespace. Should that be a part of this PR?
    • I vote no. I'm also not sure if we should even commit to fixing this for 1.14 and 1.15. But I could 100% be wrong. Either way, bringing it to your attention.

CC @DHowett as my favorite copyOnSelect user who definitely has opinions on this stuff haha

@carlos-zamora carlos-zamora marked this pull request as ready for review June 22, 2022 19:42
Copy link
Member Author

@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.

While working on the 1.14 backport, found a few things I could clean up

src/cascadia/TerminalCore/TerminalSelection.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalCore/Terminal.hpp Outdated Show resolved Hide resolved
src/cascadia/TerminalControl/ControlCore.h Outdated Show resolved Hide resolved
@ofek
Copy link
Contributor

ofek commented Jun 22, 2022

Nice! So Enter would only copy when there is a selection right?

@carlos-zamora
Copy link
Member Author

Nice! So Enter would only copy when there is a selection right?

Correct! Just like how we handle ctrl+c today 😊

@ofek
Copy link
Contributor

ofek commented Jun 22, 2022

Just like how we handle ctrl+c today

Hmm, not for me. Try:

{ "command": { "action": "copy", "singleLine": false }, "keys": "ctrl+c" }

then go to a previous command, press home to go to the start of it, then shift+end to select it, then finally ctrl+c. For me it interrupts rather than copies

@carlos-zamora
Copy link
Member Author

Just like how we handle ctrl+c today

Hmm, not for me. Try:

{ "command": { "action": "copy", "singleLine": false }, "keys": "ctrl+c" }

then go to a previous command, press home to go to the start of it, then shift+end to select it, then finally ctrl+c. For me it interrupts rather than copies

This seems to work fine on my branch and our internal 1.15 build. @ofek could you file a big report here and be sure to include your settings.json file (if you don't feel comfortable with that, the main things I'd want to check are (1) copy on select and (2) the copy keybindings being used).

@DHowett
Copy link
Member

DHowett commented Jun 23, 2022

I don't understand why this is conflicting with main when I try to merge it...!

@DHowett
Copy link
Member

DHowett commented Jun 23, 2022

Oh, because I ran git merge without actually telling it what ref to merge. WTF?

@ofek
Copy link
Contributor

ofek commented Jun 23, 2022

could you file a bug report

#13369

@@ -382,6 +382,7 @@
// Clipboard Integration
{ "command": { "action": "copy", "singleLine": false }, "keys": "ctrl+shift+c" },
{ "command": { "action": "copy", "singleLine": false }, "keys": "ctrl+insert" },
{ "command": { "action": "copy", "singleLine": false }, "keys": "enter" },
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 potentially a spicy change 🌶️

I know conhost did this in the past. I feel like we've discissed this in the past on the repl, but I can't find the discussion if we specifically said we'd add this to the defaults or not.

We may also want to consider something like #13115 - what does that even mean? Is that something separate from a text selection?

Copy link
Member Author

Choose a reason for hiding this comment

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

We may also want to consider something like #13115 - what does that even mean? Is that something separate from a text selection?

My vision for #13115 (which isn't even specced tbh), is that it's a way to navigate within mark mode. It might even be something as simple as [shift]+tab to move to the next/previous hyperlink. That 100% needs to be specc'd though.

This is potentially a spicy change 🌶️

Yeah, I don't remember the discussion either :/. The paths forward I see are...

  1. bind copy() to Enter in defaults.json (configurable)
  2. make Enter copy the text when in mark mode (non-configurable)
  3. don't even consider Enter entirely. If the user wants it, the user can bind it

Dustin seemed to be a little confused when using mark mode saying that there's no clear way to copy the selection. I think this stems from him using copyOnSelect, which seems fair because you never really had to think about copying your selection before. But we can't copy the selection every time the selection changes in mark mode. That would totally mess up clipboard history for people who use it. :/

We could pull this part out and discuss it at sync on Monday? It's a one-liner with no risk. Really just "political" reasons to decide to add it in or not.

Copy link
Member Author

Choose a reason for hiding this comment

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

Funny enough, now I'm thinking that we don't add this as a keybinding in defaults.json. Maybe we should make it non-configurable to allow for this.

That way, Enter copies when in mark mode, but opens the URL when it's selected/found by tabbing through he buffer in mark mode. It would then go back to copying if the user modified the selection.

Copy link
Member

Choose a reason for hiding this comment

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

Putting it in defaults.json allows the user to unbind it from both behaviors, but still gives us the freedom to change it (as opposed to inserting it in usersettings.json). We don't need to make the decision now, because defaults.json is entirely under our control across app updates.

Copy link
Contributor

Choose a reason for hiding this comment

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

Have we considered adding a mode option to key bindings that would only apply when enabled? They could correspond to this enum #13360 (comment)

Alacritty has the same concept (vi mode is mark mode) https://github.com/alacritty/alacritty/blob/master/alacritty/src/config/bindings.rs

Copy link
Member

Choose a reason for hiding this comment

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

Adding modal key bindings has been hotly debated, we just don't have the cycles to do it right now :)

@zadjii-msft zadjii-msft added this to the Terminal v1.15 milestone Jun 23, 2022
@@ -382,6 +382,7 @@
// Clipboard Integration
{ "command": { "action": "copy", "singleLine": false }, "keys": "ctrl+shift+c" },
{ "command": { "action": "copy", "singleLine": false }, "keys": "ctrl+insert" },
{ "command": { "action": "copy", "singleLine": false }, "keys": "enter" },
Copy link
Member

Choose a reason for hiding this comment

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

Adding modal key bindings has been hotly debated, we just don't have the cycles to do it right now :)

src/cascadia/TerminalControl/ControlCore.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalControl/ControlCore.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalControl/ControlCore.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalControl/ControlInteractivity.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalCore/Terminal.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalCore/TerminalSelection.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalCore/TerminalSelection.cpp Outdated Show resolved Hide resolved
@ghost ghost added the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label Jun 29, 2022
@ghost ghost removed the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label Jun 30, 2022
DHowett pushed a commit that referenced this pull request Jun 30, 2022
A port of commit 0c5a1e9 from #13358.
This fixes an oversight from #13353. That ended up not fixing when trying to move past the top boundary.
This is also a better fix overall. By moving the fix to `_MoveByChar`, we have consistency between all the `_MoveByX` functions in that they automatically clamp to be within the scroll area.
DHowett pushed a commit that referenced this pull request Jun 30, 2022
## Summary of the Pull Request
⚠️This targets release-1.14⚠️
Backport of #13358

This PR fixes a number of interactions between `copyOnSelect` and keyboard selection. Sometimes the selection just wouldn't be cleared or copied appropriately. 

I wrote a whole flowchart of expected behavior with copy on select:
- enable `copyOnSelect`
   - make a selection with the mouse
      - ✅ right-click should copy the text --> clear the selection --> paste
   - use keyboard selection to quick-edit the existing selection
      - ✅ `copy` action should clear the selection
      - ✅ right-click should copy the text --> clear the selection --> paste
Comment on lines +420 to +421
const auto isInMarkMode = _terminal->SelectionMode() == ::Microsoft::Terminal::Core::Terminal::SelectionInteractionMode::Mark;
if (isInMarkMode && modifiers.IsCtrlPressed() && vkey == 'A')
Copy link
Member

Choose a reason for hiding this comment

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

The namespace qualifier seems overly specific. FYI this should work as expected from other languages:

using ::Microsoft::Terminal::Core::Terminal::SelectionInteractionMode;

Comment on lines +1421 to +1422
// DO NOT call _updateSelectionUI() here.
// We don't want to show the markers so manually tell it to clear it.
Copy link
Member

Choose a reason for hiding this comment

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

I personally find this comment a bit hard to understand. Why do we not want to show them?

@@ -257,15 +256,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
else if (WI_IsFlagSet(buttonState, MouseButtonState::IsRightButtonDown))
{
// CopyOnSelect right click always pastes
if (_core->CopyOnSelect() || !_core->HasSelection())
// Try to copy the text and clear the selection
Copy link
Member

Choose a reason for hiding this comment

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

It could be helpful to mention here that CopySelectionToClipboard returns false if the selection is empty, which results in our "unique" right-click behavior (copy if something's selected, paste if it isn't).

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.

Don't automerge this!

@DHowett DHowett merged commit 2cd2351 into main Jul 1, 2022
@DHowett DHowett deleted the dev/cazamor/kbd-sln/polish branch July 1, 2022 01:07
ghost pushed a commit that referenced this pull request Jul 1, 2022
## Summary of the Pull Request
Introduces the `switchSelectionEndpoint` action which switches whichever selection endpoint is targeted when a selection is present. For example, if you are targeting "start", `switchSelectionEndpoint` makes it so that now you are targeting "end". This also updates the selection markers appropriately.

## References
Spec - #5804 
#13358
Closes #3663

## Detailed Description of the Pull Request / Additional comments
Most of the code is just standard code of adding a new action. Other than that, we have...
- if there is no selection, the action fails and the keybinding is passed through (similar to `copy()`)
- when we update the selection endpoint, we need to also update the "pivot". This ensures that future calls of `UpdateSelection()` respect this swap.
- [Corner Case] if the cursor is being moved, we make it so that you basically "anchored" an endpoint and you don't have to hold shift anymore.
@ghost
Copy link

ghost commented Jul 6, 2022

🎉Windows Terminal Preview v1.15.186 has been released which incorporates this pull request.:tada:

Handy links:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants