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

Improve copy/paste behavior in Connect terminal #44871

Merged
merged 12 commits into from
Aug 8, 2024

Conversation

gzdunek
Copy link
Contributor

@gzdunek gzdunek commented Jul 31, 2024

Closes #37650 - on Windows and Linux now we use Ctrl+Shift+C/V
Closes #22828 - text can be copied/pasted with a right click (config item terminal.rightClick, enabled by default on Windows)
Closes #24451 - text can be copied by selection (config item terminal.copyOnSelect, disabled by default)

The config options were inspired by Tabby and VS Code.

TODO: Add the new config options to docs.

changelog: Improved copy and paste behavior in the terminal in Teleport Connect. On Windows and Linux, Ctrl+Shift+C/V now copies and pastes text (these shortcuts can be changed with keymap.terminalCopy/keymap.terminalPaste). A mouse right click (terminal.rightClick) can copy/paste text too (enabled by default on Windows).
Optionally, you can also enable auto-copy on select (terminal.copyOnSelect).

// the same time on Linux causes flickering.
e.preventDefault();

if (this.configService.get('terminal.rightClick').value === 'menu') {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Initially, I wanted to pass terminalRightClick as another property in options, but maybe it makes more sense to pass the entire service? It is easy to mock in tests anyway.

Another thing is that this allows us to dynamically read the config, so when one day we make the config panel, new values will be applied without an app restart or opening a new terminal.

@gzdunek gzdunek marked this pull request as ready for review July 31, 2024 12:45
@gzdunek gzdunek requested a review from ravicious July 31, 2024 12:45
@github-actions github-actions bot requested review from avatus and rudream July 31, 2024 12:46
@gzdunek gzdunek removed the request for review from rudream July 31, 2024 12:46
…set reasonable defaults for Windows and Linux
@gzdunek gzdunek force-pushed the gzdunek/terminal-copy-paste branch from eeef7ed to 7a5dd36 Compare July 31, 2024 12:49
@gzdunek gzdunek force-pushed the gzdunek/terminal-copy-paste branch from 7a5dd36 to 124874d Compare July 31, 2024 13:07
@gzdunek gzdunek changed the title Improve copy/paste behavior in terminal Improve copy/paste behavior in Connect terminal Jul 31, 2024
@@ -79,12 +84,85 @@ export default class TtyTerminal {
},
});

this.term.onSelectionChange(() => {
if (
this.configService.get('terminal.copyOnSelect').value &&
Copy link
Member

@ravicious ravicious Aug 1, 2024

Choose a reason for hiding this comment

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

copyOnSelect behaves a bit weird in combination with rightClick: 'copyPaste'.

When I select something and then press right click, the whole "word" gets selected and copied.

Comparison videos

{ rightClick: 'copyPaste', copyOnSelect: true }

rightClick-copyPaste-copyOnSelect-true.mov

{ rightClick: 'copyPaste', copyOnSelect: false }

rightClick-copyPaste-copyOnSelect-false.mov

I think what's happening is that even with copyOnSelect: false, the right click seems to highlight the whole word but copies only the previously selected fragment. With copyOnSelect: true, the right click copies the selected text but it also changes the selection to the full word, which in turn copies the whole word.

idk if there's something we need to do about it. Maybe the config options should look a little bit different? Setting { rightClick: 'copyPaste', copyOnSelect: true } at the same time is "legal" but idk if it makes much sense from the UX standpoint. Perhaps a smaller number of available choices would work well enough. I don't really want to dictate a solution here as I don't intuitively understand all requirements here.

repro.mov

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good finding.

To solve this problem, we could use the xterm.js's option rightClickSelectsWord.
For example, vscode sets this option to false when their terminal.rightClick is selectWord. When this option is active, right click selects a word and then opens the context menu. I don't think we need option too, instead we could set rightClickSelectsWord to false when terminal.rightClick is menu. What do you think?

Copy link
Member

Choose a reason for hiding this comment

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

I don't think we need option too, instead we could set rightClickSelectsWord to false when terminal.rightClick is menu. What do you think?

App Shows context menu Highlights word Does copy/paste
cmd.exe
Powershell
Windows Terminal
Terminal.app
iTerm
Terminal on Ubuntu
Terminal on Fedora

Assuming we don't need to stick to differences between macOS and Linux, what do you say we do rightClickSelectsWord: false if rightClick is paste or copyPaste and rightClickSelectsWord: true if rightClick is menu?

We could consider rightClickSelectsWord: false when rightClick: 'menu', copyOnSelect: true, but I don't know what people would actually want here. We could leave it as is, I think copyOnSelect is something you care about mostly when rightClick is set to pase or copyPaste.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Assuming we don't need to stick to differences between macOS and Linux, what do you say we do rightClickSelectsWord: false if rightClick is paste or copyPaste and rightClickSelectsWord: true if rightClick is menu?

I agree, this makes sense. Actually, I wanted to propose the same in the comment above, but I totally mixed it up 🤦
I wanted to say:

vscode sets this option to true when their terminal.rightClick is selectWord

we could set rightClickSelectsWord to true when terminal.rightClick is menu

And thanks for the table. It's really helpful, I appreciate the effort.
I applied the change, and made the config to be read only when terminal starts. Otherwise, some parts of ctrl.ts would read the config dynamically (in event listeners), and some (rightClickSelectsWord) only in the constructor.


We could consider rightClickSelectsWord: false when rightClick: 'menu', copyOnSelect: true, but I don't know what people would actually want here. We could leave it as is, I think copyOnSelect is something you care about mostly when rightClick is set to pase or copyPaste.

Agree 👍

@@ -182,6 +204,8 @@ const getDefaultKeymap = (
openConnections: 'Ctrl+Shift+P',
openClusters: 'Ctrl+Shift+E',
openProfiles: 'Ctrl+Shift+I',
terminalCopy: 'Ctrl+Shift+C',
terminalPaste: 'Ctrl+Shift+V',
Copy link
Member

Choose a reason for hiding this comment

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

How are people on Linux and Windows going to know that these are the shortcuts for copy and paste inside a terminal? We could include them in the context menu on right click, but I think that would only work on Linux, right? idk if there's a solution on Windows, but I guess people are used to using a mouse for that anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We could include them in the context menu on right click, but I think that would only work on Linux, right? idk if there's a solution on Windows, but I guess people are used to using a mouse for that anyway.

Good news, we can add an accelerator (keyboard shortcut) to menu items. It will be shown on all platforms.
The only problem I see, is that by default we set terminal.rightClick on Windows to copyPaste. Perhaps, we should revert it to the context menu? So users can learn these new shortcuts.

Copy link
Member

Choose a reason for hiding this comment

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

The accelerator added to menu items is fantastic, wow.

Since the equivalent of rightClick: 'copyPaste' is the default on all the other three terminals on Windows, I think we should stick with it there. Windows users can learn the shortcuts from docs I suppose if they absolutely need to, assuming they won't just use right click.

Perhaps we could also modify the tab with keyboard shortcuts to show "Copy in terminal" and "Paste in terminal" if the platform is different than macOS? I think we don't need to show it on macOS since 99% of users are not going to ever change the default shortcut. It'd be mostly shown just for Windows and Linux users.

Another very cool thing we could add is "Show keyboard shortcuts" below "Open config file" in additional actions menu, but I think we could leave this for another time.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since the equivalent of rightClick: 'copyPaste' is the default on all the other three terminals on Windows, I think we should stick with it there. Windows users can learn the shortcuts from docs I suppose if they absolutely need to, assuming they won't just use right click.

👍

Perhaps we could also modify the tab with keyboard shortcuts to show "Copy in terminal" and "Paste in terminal" if the platform is different than macOS?

This a really good idea, done.

Another very cool thing we could add is "Show keyboard shortcuts" below "Open config file" in additional actions menu, but I think we could leave this for another time.

👍

@ravicious ravicious self-requested a review August 6, 2024 14:35
Copy link
Member

@ravicious ravicious left a comment

Choose a reason for hiding this comment

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

It's perfect now. 👌

Copy link

github-actions bot commented Aug 8, 2024

🤖 Vercel preview here: https://docs-f8guyba33-goteleport.vercel.app/docs/ver/preview

Copy link

github-actions bot commented Aug 8, 2024

🤖 Vercel preview here: https://docs-cnftd2nsq-goteleport.vercel.app/docs/ver/preview

Copy link

github-actions bot commented Aug 8, 2024

🤖 Vercel preview here: https://docs-q02j4ix76-goteleport.vercel.app/docs/ver/preview

Copy link

github-actions bot commented Aug 8, 2024

🤖 Vercel preview here: https://docs-3gz84bcga-goteleport.vercel.app/docs/ver/preview

@gzdunek gzdunek added this pull request to the merge queue Aug 8, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Aug 8, 2024
@gzdunek gzdunek added this pull request to the merge queue Aug 8, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Aug 8, 2024
@gzdunek gzdunek added this pull request to the merge queue Aug 8, 2024
Merged via the queue into master with commit ee1a5ba Aug 8, 2024
38 checks passed
@gzdunek gzdunek deleted the gzdunek/terminal-copy-paste branch August 8, 2024 15:03
@public-teleport-github-review-bot

@gzdunek See the table below for backport results.

Branch Result
branch/v14 Failed
branch/v15 Failed
branch/v16 Create PR

gzdunek added a commit that referenced this pull request Aug 8, 2024
* Allow reading clipboard content in renderer process

* Make keyboard shortcuts to copy/paste text in terminal configurable, set reasonable defaults for Windows and Linux

* Allow copying text in terminal with selection and a right click

* Remove check for `selection.trim()`, check if there's something selected in callsites, rename `copy` to `copySelection`

* Show copy/paste keyboard shortcuts in the context menu

* Remove redundant `to`

* Add `Copy in Terminal` and `Paste in Terminal` shortcuts to `KeyboardShortcutsPanel`

* Set `rightClickSelectsWord: true` only if `terminal.rightClick` is `menu`

* Add docs

* Patched jsdom `global.matchMedia` should return `matches: false`, not `true`

* Small docs correction

(cherry picked from commit ee1a5ba)
@gzdunek
Copy link
Contributor Author

gzdunek commented Aug 8, 2024

I abandoned the backport to v14, too many conflicts.

github-merge-queue bot pushed a commit that referenced this pull request Aug 8, 2024
* Allow reading clipboard content in renderer process

* Make keyboard shortcuts to copy/paste text in terminal configurable, set reasonable defaults for Windows and Linux

* Allow copying text in terminal with selection and a right click

* Remove check for `selection.trim()`, check if there's something selected in callsites, rename `copy` to `copySelection`

* Show copy/paste keyboard shortcuts in the context menu

* Remove redundant `to`

* Add `Copy in Terminal` and `Paste in Terminal` shortcuts to `KeyboardShortcutsPanel`

* Set `rightClickSelectsWord: true` only if `terminal.rightClick` is `menu`

* Add docs

* Patched jsdom `global.matchMedia` should return `matches: false`, not `true`

* Small docs correction

(cherry picked from commit ee1a5ba)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants