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

Copying text inside CC to a user's clipboard #827

Open
exerro opened this issue Jun 14, 2021 · 14 comments
Open

Copying text inside CC to a user's clipboard #827

exerro opened this issue Jun 14, 2021 · 14 comments
Labels
area-Core This affects CC's core (the Lua runtime, APIs, computer internals). area-Minecraft This affects CC's Minecraft-specific content. enhancement An extension of a feature or a new feature. feedback wanted Tell me what you want, what you really really want.

Comments

@exerro
Copy link
Contributor

exerro commented Jun 14, 2021

Introduction

I'm suggesting that there should be a mechanism to copy text within CC to a user's real clipboard. There are a few concerns here which I believe are addressed. Firstly, security: you don't want some arbitrary CC script to have control over a user's clipboard. Secondly, multi-user madness: CC computers are accessed by zero-or-more users at once, so the behaviour gets a bit weird.

Suggested solution

My solution to these is having an intermediate buffer of text which I'll refer to as "copyable text". A function such as os.setCopyableText(text: string) can change the contents of this buffer whenever. The buffer is persistent until reboots/shutdowns etc. When a user presses ctrl+C (or another keybind specified by MC I guess), the copyable text of the computer they're viewing is set as their clipboard text.

This works for multiple computers and doesn't give CC scripts any direct control over any users' clipboard.

Here, have a beautiful diagram.

Note that, while in the diagram it says "user selects something", this also works for scripts offering something to be copied and then exiting, as discussed below.

Use cases

pastebin put By default, pastebin put generates a pastebin code and prints that to the screen. You still need to write that out by hand to get the pastebin URL for what you uploaded. Instead, the full URL or just the code could be set as the copyable text so the user just presses ctrl+C to get that out from MC.
General purpose standard clipboard A bunch of programs, OSes, shells etc implement custom clipboard within CC. These are incompatible with one another and code needs to be written specifically for that system to work. By allowing real-world clipboard interactions like this, there's no need for ad-hoc clipboards inside CC.
Websocket based code Generally, when using websockets, you need to do something on the server to get a link then paste that into CC. It's minor, but it'd be more convenient to get that link from CC, particularly when you might not remember/know the server URL but there's easy to use software running on the CC computer.
TypeScript! My original motivation behind this was when I was thinking of a package manager that handled typescript nicely from CC. You can't compile TS from CC afaik, but it would be awesome if the computer could generate a short bash command to compile your code for you (in watch mode, for example).

Complications

Click to expand...

Exploitation

While the user still has full control of *when* to copy something, they don't strictly know *what* they're copying. A malicious program could claim to be offering some innocent text while actually offering something dodgy. It's been suggested that Windows 10 has clipboard exploits but I've not found any evidence of this in a way that would impact this system.

In my opinion, this isn't really a problem - clipboard text is pretty innocent on its own, the worst things that could happen are a user going to a link that's been copied without checking it (which is more of a general internet problem and fairly unavoidable) and something profane being copied (but this can just be written to the screen anyway).

Redundancy

Maybe this isn't the most helpful or necessary feature in the world, and maybe adding it is more complex than is worthwhile. However, I'd be happy to implement this myself and submit a PR, and a few people on Discord have expressed interest in the feature.

Philosophy

I'm not one to say but maybe this goes against the simple nature of CC. Every more advanced feature added takes it away from its little grey flying robot roots and makes it ever so slightly harder to learn about the mod for beginners.

However, I think in terms of ease of use this has a much more significant positive impact than negative, and since we already have pasting doesn't really introduce anything drastically new.

@exerro exerro added the enhancement An extension of a feature or a new feature. label Jun 14, 2021
@SquidDev SquidDev added area-Core This affects CC's core (the Lua runtime, APIs, computer internals). area-Minecraft This affects CC's Minecraft-specific content. feedback wanted Tell me what you want, what you really really want. labels Jun 15, 2021
@SquidDev
Copy link
Member

SquidDev commented Jun 21, 2021

Sorry for not looking at this sooner, I know you've put a lot of effort into writing this up!

I do really like this approach - it's definitely the most elegant solution to copying for CC I've seen. That said, I've a couple of concerns which, while I don't think are deal-breakers, are worth discussing:

  • Obviously this is in some ways a workaround for the fact that we don't want to expose a direct "copy" functionality to the user, and this does (unavoidably) leak through in the design.

    This is a general problem with CC's whole model though. As mentioned elsewhere on the issue tracker, I really want to make getting files onto/off the computer easier. Again, uploading to the computer is easy (File uploading #840), but I've not been able to find a suitable flow for downloading.

  • This is really into nitpicking territory, but I'm not sure how this plays with multishell. For instance, if two tabs call os.setCopyableText, we'll copy from the last one, not the currently visible tab.

    I guess more generally, we've got this hidden bit of UI, and ideally it'd be consistent with the in-computer UI. Obviously that's not possible here (well, not without multishell then overriding os.setCopyableText), so not really sure what to do!

@Wojbie
Copy link
Contributor

Wojbie commented Jun 22, 2021

I guess more generally, we've got this hidden bit of UI, and ideally it'd be consistent with the in-computer UI. Obviously that's not possible here (well, not without multishell then overriding os.setCopyableText), so not really sure what to do!

One solution to that issue would be putting setCopyableText into shell/multishell api instead of os and having a native setCopyableText somewhere? Then each shell/multishell tab would have to be it's own buffer and would swap what is in native buffer when tabs are swapped?

@Lupus590
Copy link
Contributor

One solution to that issue would be putting setCopyableText into shell/multishell api instead of os and having a native setCopyableText somewhere? Then each shell/multishell tab would have to be it's own buffer and would swap what is in native buffer when tabs are swapped?

How would you tell when to paste from the CC buffer or from the host OS buffer?

This is a general problem with CC's whole model though. As mentioned elsewhere on the issue tracker, I really want to make getting files onto/off the computer easier. Again, uploading to the computer is easy (#840), but I've not been able to find a suitable flow for downloading.

Thoughts on having CC basically make a FTP server on the server that players can log into and access their computers?

@SquidDev
Copy link
Member

How would you tell when to paste from the CC buffer or from the host OS buffer?

I'm assuming what Wojbie is proposing here is that shell.setCopyableText sets the per-process/tab clipboard, which then propagates up to os.setCopyableText. Then the user Ctrl-Cs this into the host OS buffer, as per the OP.

Thoughts on having CC basically make a FTP server on the server that players can log into and access their computers?

I want to make things more accessible, not less!

@exerro
Copy link
Contributor Author

exerro commented Jun 22, 2021

This is a general problem with CC's whole model though.

Honestly, a similar approach could work for files too. Ultimately, you can't directly move something from CC to a user's PC using CC code (and this shouldn't change), but offering things that the user can confirm is the next best thing imo. Whether that's clipboard text or a downloadable file is somewhat irrelevant, although the mechanism for offering and then confirming would likely be different for the two.

I'm not sure how this plays with multishell

I think @Wojbie's approach is a good way to handle this. My only concern would be people abusing/not understanding the difference between os.* and shell.*. It would be better if there was one function exposed that was overridden in tabs, but bios-level CC doesn't get a shell API and overridding os in shell tabs seems a bit hacky.

@Wojbie
Copy link
Contributor

Wojbie commented Jun 22, 2021

Honestly, a similar approach could work for files too. Ultimately, you can't directly move something from CC to a user's PC using CC code (and this shouldn't change), but offering things that the user can confirm is the next best thing imo.

#840 may interest you.

I think @Wojbie's approach is a good way to handle this. My only concern would be people abusing/not understanding the difference between os.* and shell.*. It would be better if there was one function exposed that was overridden in tabs, but bios-level CC doesn't get a shell API and overridding os in shell tabs seems a bit hacky.

A amusing way to hide it would be say that clipboard is part of terminal and hide the native function in native terminal object. Most users don't even know how it is different from normal term api and they rarely interact with it outside of redirect.

@exerro
Copy link
Contributor Author

exerro commented Jun 22, 2021

#840 looks epic and such a great idea. Good job @SquidDev! 😛
Having it in term is not too bad tbh, although it'd break a lot of existing redirect code right?

@SquidDev
Copy link
Member

SquidDev commented Jun 22, 2021

We've broken redirect code before (see blit, setPaletteColour) and it's not the end of the world. Though I don't think it fits well within term - you can't copy from a monitor! shell and os is probably fine, as long as the distinction is made clear.

@SquidDev
Copy link
Member

SquidDev commented Jun 22, 2021

Whether that's clipboard text or a downloadable file is somewhat irrelevant, although the mechanism for offering and then confirming would likely be different for the two.

Sorry to post another comment, but it occurs to me that another interaction model for both would just be to show a toast notification to currently interacting users saying "X wants to copy to the clipboard, click to do so". This has the explicit intent that it doesn't set any permanent state - it's just a prompt to the user - which makes things easier.

Obvious issue is that then you've got to pull out your mouse, toast notifications flying in and out is a little gross, and don't know if it's any nicer on the fourth-wall nature of things.

Edit: I've, uh, just gone full circle haven't I? Dammit. Ignore this!

@dmarcuse
Copy link
Contributor

dmarcuse commented Jul 31, 2021

One random idea: have a toast system that uses Ctrl + C to confirm a copy, but also confirms automatically if the user has pressed Ctrl + C in the last ~250ms or so. Programs could detect Ctrl + C being pressed through events, call os.offerCopyableText (example name), and the user that recently pressed Ctrl + C would have it automatically confirmed and copied. If other users were also viewing the UI at the time, or the call was triggered by another event, users could confirm the request by clicking the toast or pressing Ctrl + C within, say, five or ten seconds of being prompted.

One issue I can foresee with this approach is events around the confirming Ctrl + C. Obviously, an automatically confirmed copy won't involve sending any new events, but for copies which are confirmed after the toast shows up via Ctrl + C, it would probably be a good idea to block the event for the C key from actually being fired, to prevent accidentally causing the CC program to offer another copy.

Some other potential variations or additions to this idea:

  • Rather than detecting Ctrl + C with the existing key/char events, it might be better to have a new event type, like copy_request. This would make the specific key combo an implementation detail of the MC client, which could help with, say, Mac compatibility - I don't remember how the command key works with CC off the top of my head. This would also avoids having to suppress key events for the confirmation as previously described.
  • A copy_confirmed event could be useful to allow programs to automatically proceed when the user copies text.
  • It would be convenient to have a GUI to see recent copy prompts, so that you can re-copy some text if you need it again or if you missed the toast. This would be especially helpful for programs that would offer copyable text unprompted and immediately exit - e.g. pastebin put
  • If network latency is particularly bad or the CC thread is blocked, the automatic confirmation could time out. It would probably be good to make the delay configurable by the user (and also have a toggle to disable automatic confirmation entirely), or maybe have the server send some timing data behind the scenes to automatically determine an appropriate timeout?

@migeyel
Copy link

migeyel commented Mar 1, 2023

While having trouble around copying NBT hashes and large pseudorandom strings I've come back to see where this issue was and have some feedback for it.

Here's the proposal: Once the user presses the key combo, a copy event is queued. Its first argument is a function that tries to set the clipboard for that user, and returns a boolean whether it was successful or was invalidated (which happens if the user closes the GUI, or after a short timeout). Copy events issued later take precedence over earlier ones. Two users pressing the combo will issue two events, each with their own function and invalidation condition. Events get filtered through like any key event.

This has the same basic idea as above, except that there is no new os, shell or term function. It also shares the drawback that the program has a bit of control about how far in the future the clipboard can be set after the event is issued.

@exerro
Copy link
Contributor Author

exerro commented Mar 17, 2023

Two reasons I'm against using events for this:

  • No other events, afaik, pass a function which you then call to do something
  • As you mentioned, potential exploitation by calling that function later than expected

For the proposal you gave, that's very similar functionally to what's been talked about before, just with the function call/key combo swapped round. Instead of responding to a copy event retroactively, we state ahead-of-time what the user may copy. I do think a copy event could be useful for informing the program that a user did copy some text, however.

@Lemmmy
Copy link
Contributor

Lemmmy commented Mar 17, 2023

No other events, afaik, pass a function which you then call to do something

As of 1.101.0 (Nov 2022), there is now an event that does this, file_transfer

@zyxkad
Copy link
Contributor

zyxkad commented Jun 15, 2023

I would like if CC could let the user select the text, and then user just copy the text that has been shown!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-Core This affects CC's core (the Lua runtime, APIs, computer internals). area-Minecraft This affects CC's Minecraft-specific content. enhancement An extension of a feature or a new feature. feedback wanted Tell me what you want, what you really really want.
Projects
None yet
Development

No branches or pull requests

8 participants