Cannot copy text in terminal/console-only display mode
When selecting text in a non-GUI VM (i.e. “Console Only” under “Display” settings), both “Edit → Copy” under menu bar menu and Command+C shortcut do nothing. It’s possible to drag-and-drop selected text though.
Configuration
- UTM Version: v2.1.2, v2.2.4
- macOS Version: 11.6
- Intel or Apple Silicon? Intel
This is a limitation of the javascript terminal. I think if you right click, it will copy.
@tie You can try this patch: hterm_all.js.patch.txt
Steps to apply:
- Download the patch
- Rename it to
hterm_all.js.patch - Open
Terminal.app - Type
cd /Applications/UTM.app/Contents/Resourcesand press enter - Type
patch <, then drag the patch file over the terminal and drop it, which will autofill the path, then press enter. - Open UTM and test if it's fixed.
@osy can you please confirm, it seems that changing files in Contents/Resources doesn't invalidate the code signature?
It definitely will.
Not sure why but it still runs for me?
Edit: So it seems that changing files in Contents/Resources invalidates the signature but the app can still be used?
Thanks, runs for me too 🙂 I ended up enabling default window copy behavior. It’d be also nice to have GUI for hterm settings.
I ended up enabling default window copy behavior.
@tie how did you do this? Just wondering.
Uh, I just hardcoded the preferences.
Also, use-default-window-copy doesn’t work that well with line wrapping, so I’m actually not using it now.
For some reason Cmd+C didn’t work out of the box even with patched hterm.copySelectionToClipboard, but adding copySelectionToClipboard call in onMetaC_ fixed that for me.
hterm_all.js diff
--- a/UTM.app/Contents/Resources/hterm_all.js
+++ b/UTM.app/Contents/Resources/hterm_all.js
@@ -5471,106 +5471,7 @@
* @return {!Promise<void>}
*/
hterm.copySelectionToClipboard = function(document, str) {
- // Request permission if need be.
- const requestPermission = () => {
- // Use the Permissions API if available.
- if (navigator.permissions && navigator.permissions.query) {
- return navigator.permissions.query({name: 'clipboard-write'})
- .then((status) => {
- const checkState = (resolve, reject) => {
- switch (status.state) {
- case 'granted':
- return resolve();
- case 'denied':
- return reject();
- default:
- // Wait for the user to approve/disprove.
- return new Promise((resolve, reject) => {
- status.onchange = () => checkState(resolve, reject);
- });
- }
- };
-
- return new Promise(checkState);
- })
- // If the platform doesn't support "clipboard-write", or is denied,
- // we move on to the copying step anyways.
- .catch(() => Promise.resolve());
- } else {
- // No permissions API, so resolve right away.
- return Promise.resolve();
- }
- };
-
- // Write to the clipboard.
- const writeClipboard = () => {
- // Use the Clipboard API if available.
- if (navigator.clipboard && navigator.clipboard.writeText) {
- // If this fails (perhaps due to focus changing windows), fallback to the
- // legacy copy method.
- return navigator.clipboard.writeText(str)
- .catch(execCommand);
- } else {
- // No Clipboard API, so use the old execCommand style.
- return execCommand();
- }
- };
-
- // Write to the clipboard using the legacy execCommand method.
- // TODO: Once we can rely on the Clipboard API everywhere, we can simplify
- // this a lot by deleting the custom selection logic.
- const execCommand = () => {
- const copySource = document.createElement('pre');
- copySource.id = 'hterm:copy-to-clipboard-source';
- copySource.textContent = str;
- copySource.style.cssText = (
- '-webkit-user-select: text;' +
- '-moz-user-select: text;' +
- 'position: absolute;' +
- 'top: -99px');
-
- document.body.appendChild(copySource);
-
- const selection = document.getSelection();
- const anchorNode = selection.anchorNode;
- const anchorOffset = selection.anchorOffset;
- const focusNode = selection.focusNode;
- const focusOffset = selection.focusOffset;
-
- // FF sometimes throws NS_ERROR_FAILURE exceptions when we make this call.
- // Catch it because a failure here leaks the copySource node.
- // https://bugzilla.mozilla.org/show_bug.cgi?id=1178676
- try {
- selection.selectAllChildren(copySource);
- } catch (ex) {}
-
- try {
- document.execCommand('copy');
- } catch (firefoxException) {
- // Ignore this. FF throws an exception if there was an error, even
- // though the spec says just return false.
- }
-
- // IE doesn't support selection.extend. This means that the selection won't
- // return on IE.
- if (selection.extend) {
- // When running in the test harness, we won't have any related nodes.
- if (anchorNode) {
- selection.collapse(anchorNode, anchorOffset);
- }
- if (focusNode) {
- selection.extend(focusNode, focusOffset);
- }
- }
-
- copySource.parentNode.removeChild(copySource);
-
- // Since execCommand is synchronous, resolve right away.
- return Promise.resolve();
- };
-
- // Kick it all off!
- return requestPermission().then(writeClipboard);
+ return navigator.clipboard.writeText(str);
};
/**
@@ -8245,6 +8146,7 @@
if (this.keyboard.terminal.clearSelectionAfterCopy) {
setTimeout(function() { document.getSelection().collapseToEnd(); }, 50);
}
+ this.keyboard.terminal.copySelectionToClipboard();
return hterm.Keyboard.KeyActions.PASS;
};
@@ -9438,7 +9340,7 @@
'copy-on-select': hterm.PreferenceManager.definePref_(
'Automatically copy selected content',
hterm.PreferenceManager.Categories.CopyPaste,
- true, 'bool',
+ false, 'bool',
`Automatically copy mouse selection to the clipboard.`
),
@@ -9459,7 +9361,7 @@
'clear-selection-after-copy': hterm.PreferenceManager.definePref_(
'Automatically clear text selection',
hterm.PreferenceManager.Categories.CopyPaste,
- true, 'bool',
+ false, 'bool',
`Whether to clear the selection after copying.`
),
I think I am encountering that too
@tie You can try this patch: hterm_all.js.patch.txt
Steps to apply:
1. Download the patch 2. Rename it to `hterm_all.js.patch` 3. Open `Terminal.app` 4. Type `cd /Applications/UTM.app/Contents/Resources` and press enter 5. Type `patch <`, then drag the patch file over the terminal and drop it, which will autofill the path, then press enter. 6. Open UTM and test if it's fixed.@osy can you please confirm, it seems that changing files in
Contents/Resourcesdoesn't invalidate the code signature? Can I still use this patch in UTM 4.2.5 ?
It is indeed very annoying that I can't copy / paste from / to the console window. I mean the console window of a non-GUI OS which is not (yet) reachable via SSH.
Does not work.
mac:/Applications/UTM.app/Contents/Resources % patch < /Users/klaas/Downloads/hterm_all.js.patch.txt
File to patch: /Users/klaas/Downloads/hterm_all.js.patch.txt
patching file '/Users/klaas/Downloads/hterm_all.js.patch.txt'
patching file '/Users/klaas/Downloads/hterm_all.js.patch.txt'
No such line 16251 in input file, ignoring
1 out of 1 hunks failed--saving rejects to '/Users/klaas/Downloads/hterm_all.js.patch.txt.rej'