BowPad icon indicating copy to clipboard operation
BowPad copied to clipboard

Clipboard Operations May Not Work When Working with Remote Desktop Client

Open wmjordan opened this issue 6 years ago • 26 comments

This issue does not always occur.

  1. Open BowPad.
  2. Open a Remote Desktop Client and connect to a remote machine.
  3. Click the Copy button or press Ctrl+C in BowPad.
  4. Don't paste to local applications. Switch to the Remote Desktop Client. The clipboard is cleared, but nothing is copied.

wmjordan avatar Dec 27 '18 06:12 wmjordan

not really a problem of BowPad. See here: https://superuser.com/questions/95609/cant-copy-and-paste-in-remote-desktop-connection-session

stefankueng avatar Jan 09 '19 20:01 stefankueng

It is a problem of BowPad. I could copy text from other text editors, NotePad, EditPlus, etc. But from BowPad, the operation often failed.

wmjordan avatar Aug 20 '19 08:08 wmjordan

@songbaoming Have you ever experienced this issue that BowPad's copy function could fail when Remote Desktop Client was connected?

wmjordan avatar Dec 03 '19 01:12 wmjordan

I found a solution to this issue.

If the copy operation fails, the Paste button on BowPad is still enabled--meaning that the clipboard contains text--however, the text is of zero length.

If I hit the Copy button repeatedly, sometimes the copy operation might success.

Since we don't have zero-length text after a successful operation, is it possible to check and retry copying in BowPad?

for (int i = 0; i < 1000; i++)
{
   copy selection;
   if (the length of the clipboard text > 0)
       break;
   thread.sleep(10ms)
}

wmjordan avatar Oct 17 '20 00:10 wmjordan

you're loop would block for 10s in the worst case. But it seems to me that there's something wrong on your machine. Maybe a tool that monitors or otherwise interferes with the clipboard? The clipboard is a shared resource on Windows: if an application has the clipboard open, others can't use it. So some app must keep the clipboard open for too long on your machine.

stefankueng avatar Oct 17 '20 06:10 stefankueng

I've just bought a new computer and the system is a brand new one. It should not be the problem in my system. The Remote Desktop Client was the thing that keep monitoring the clipboard. Once it was closed. I could copy things from BowPad without any problem. I programmed other applications which encountered similar problem and solved it via the similar approach above. I could accept that worst case. It is much better than switching back and forth between BowPad and the RDP Client to verify whether the copy was successful or not.

wmjordan avatar Oct 17 '20 06:10 wmjordan

Seems it's a known problem: https://www.techulator.com/resources/5607-Copy-pasting-clipboard-not-working-Remote.aspx

stefankueng avatar Oct 17 '20 07:10 stefankueng

Hmm, I will try that.

wmjordan avatar Oct 17 '20 07:10 wmjordan

@songbaoming Have you ever experienced this issue that BowPad's copy function could fail when Remote Desktop Client was connected?

I don't have met this problem, and i also think it's not a problem of bowpad.

songbaoming avatar Oct 19 '20 01:10 songbaoming

Recently I used remote desktop more frequently and encountered this issue again on my new computer.

Seems it's a known problem: https://www.techulator.com/resources/5607-Copy-pasting-clipboard-not-working-Remote.aspx

It was not that type of problem. The situation in the above link was that a user who connected to a remote machine could not copy local content to the remote machine from any local application. My situation was that when the remote desktop client was opened, I could not copy content from BowPad, neither locally nor remotely. Meanwhile, the copy operation was OK in other programs, such as NotePad, Visual Studio, etc. If I pressed Ctrl+C multiple times, the content could be copied from BowPad.

It seems to me that this issue is a bit more like the following situation: https://stackoverflow.com/questions/930219/how-to-handle-a-blocked-clipboard-and-other-oddities

wmjordan avatar Nov 05 '20 00:11 wmjordan

I also discovered that when BowPad had difficulty copying content from the document window, it could successfully copy the File Path, File Name and File Directory from the context menu of a file tab--at least I had not yet experienced a failure from there.

Perhaps it is the way how to write data to the clipboard which makes the difference.

wmjordan avatar Nov 05 '20 00:11 wmjordan

It seems that this open-sourced editor AkelPad can handle clipboard when Remote Desktop clients opened. Could you try adapt its source code and see whether it works with BowPad?

wmjordan avatar Aug 05 '21 02:08 wmjordan

that source doesn't do anything different. Well actually it doesn't even retry to open the clipboard.

After implementing the retry I thought this issue was solved. So what exactly is the problem now?

stefankueng avatar Aug 05 '21 17:08 stefankueng

The issue persists. It is strange that in AkelPad, the copy operation always succeeds. But in BowPad, it still failed sometimes. The clipboard got cleared after Ctrl+C, and nothing is pasted after the subsequent Ctrl+V, on either the local computer or the remote ones).

image The above is the display of the Inside Clipboard after an unsuccessful copy by BowPad.

Whereas, a successful copy operation has display like the following in Inside Clipboard: image

The code in AkelPad has used a different way to OpenClipboard(NULL). Will this make difference?

wmjordan avatar Aug 05 '21 22:08 wmjordan

~Well, it seems that the OpenClipboard is the only difference. I will try to make the modification myself and see whether it works and be back later.~

EDIT: I checked the source code and found that the Cut and Copy commands were handled by Scintilla internally, not by BowPad. Maybe they are the missing places that we shall take care of.

wmjordan avatar Aug 06 '21 06:08 wmjordan

I compiled the latest source code, opened a remote desktop client and watched the clipboard by selecting the "Refresh on Clipboard Change" option in Inside Clipboard.

Copy operations could still fail. The same symptom shown as the above screenshot.

I observed that the table in the Inside Clipboard refreshed at least twice when copying from BowPad. For a time, I caught sight of the correct content once emerged in the table, then the table was emptied. I manually refreshed the table, and saw things like the above failed screenshot.

I observed the situation when I did that with AkelPad. No such kind of two-times refresh. The content just appeared there after the copy operation.

I tried to write a plugin to retry more times for the copy operation like the following.

function Execute()
{
    var t = BowPad.SciGetSelText();
    if (t.length == 0) {
        t = BowPad.SciGetCurLine(BowPad.SciGetCurrentPos());
    }
    BowPad.SetClipboardData(t, "");
    var retry = 1000;
    while ((t = BowPad.GetClipboardText()).length == 0 && --retry > 0) {
        /*BowPad.sleep(10);*/
        BowPad.SetClipboardData(t, "");
    }
    if (t.length == 0 && BowPad.GetClipboardText().length == 0) {
        BowPad.alert("Copy failed");
        return false;
    }
    return true;
}

I then assigned a hot key for that plugin and executed it. I found that the copy operations seemed successful, however, the SetClipboardData only set CF_UNICODETEXT, but leaving CF_TEXT, CF_OEMTEXT and other fields unchanged. I had a clipboard content like the following.

You can see that the content length of CF_UNICODETEXT is much shorter (copied from executing the above script) than the other two counterparts.

image

wmjordan avatar Aug 08 '21 09:08 wmjordan

Having observed the aforementioned behavior of the script in the last post. I assumed that the problem could lie in the function AddLexerToClipboard, since it appeared in almost every clipboard related commands. Whereas AddHtmlStringToClipboard was never called on my side.

Afterwards, I tried to bypass the AddLexerToClipboard by returning from its first line. It seemed to be working without the BP_LEXER entry in the cilpboard--this can be a bit inconvenient when we copy some stuff to a new document. At least I can copy for quite some scores of times now.

wmjordan avatar Aug 08 '21 09:08 wmjordan

unfortunately, there's no callback/signal from Scintilla in between the OpenClipboard and CloseClipboard calls, so I have to add the lexer data in another open/close cycle.

stefankueng avatar Aug 09 '21 17:08 stefankueng

After setting the GMEM_MOVEABLE flag, the AddLexerToClipboard function appears to do nothing to the clipboard. No BP_LEXER entry is found in Inside Clipboard after the copy operation.

wmjordan avatar Aug 10 '21 01:08 wmjordan

After the latest commit, it seems that the successful operation ratio is a bit higher than the one when this issue was posted. However, it still somehow fails occasionally.

And the above script always fails to put the selection to the clipboard.

wmjordan avatar Aug 11 '21 00:08 wmjordan

script should work now again.

stefankueng avatar Aug 11 '21 16:08 stefankueng

Hmm, the script is now working.

I still experience failure when copying with BowPad. The following is a new situation when I copy line by selecting nothing in BowPad and pressed Ctrl+C. When copying line, the two entry marked in the following screenshot are added into the clipboard. When failed, the text entries are all cleared, two extra Can*** entries are added (in successful copy, no such two entries), but the two line-copy-indicators are still kept. image

wmjordan avatar Aug 12 '21 00:08 wmjordan

Shall we replace the builtin Cut and Copy function with our own implementation (like the above script)? Therefore, we can open the clipboard only once and not be interfered by external programs.

Here are the steps (steps in bold is the logic to be implemented, non-bold items are already there):

  1. Open the clipboard
  2. Get selection text
  3. Check whether the text is zero-length, if so, get current line
  4. Put the text into clipboard
  5. If is line-select, add two line-select indicator entries too
  6. Add HTML code when shift is pressed
  7. Add BP_Lexer entry
  8. Close clipboard
  9. If it is a Cut operation, remove the selection (if line-select, remove the whole line)

wmjordan avatar Aug 12 '21 00:08 wmjordan

I think I know what's going on: There are tools (like the InsideClipboard one you use to debug) that monitor the clipboard for changes. For remove desktop situations, the remote desktop tool must do this itself to copy the local clipboard to the remote one and vice versa. The problem is that there's a change notification for every CloseClipboard call. So the remote desktop first copies the clipboard after Scintilla copied its stuff, then again after BP adds its stuff to it. So on the remote desktop you only get the BP part.

As for your suggestion on doing all in BP: it was done once like this. It works for simple selections, but if you have a multi-selection (hold down the Ctrl key and select different texts in different parts of the document) it gets more complicated. That multi-selection format is nowhere documented and can therefore change at any time without notice. So even if I analyze the Scintilla code and reimplement it, it wouldn't be stable.

I'll go and ask Neil, maybe there's something that can be done in Scintilla...

stefankueng avatar Aug 12 '21 16:08 stefankueng

https://groups.google.com/g/scintilla-interest/c/BeHASfsQJ7g/m/D-wABFBkAQAJ

stefankueng avatar Aug 12 '21 17:08 stefankueng

Thank you very much for kindly explaining and asking Neil.

It was strange that "So on the remote desktop you only get the BP part." was not what happened previously. If we only get the BP part, there should be the BP_Lexer entry left there. However, The previous screenshots of Inside Clipboard taken on my local machine show that somehow the clipboard is overwritten by the remote desktop client with those two extra Can*** entries and no more BP part. As for the line-selection screenshot, the clipboard is partially cleared, which is more strange.

For the multi-selection part, there are quite a few APIs in Scintilla.

First we use SCI_GETSELECTIONS to get the number of selections which is at least 1. If greater than 1, we use a for loop to get the start (SCI_GETSELECTIONNSTART(int selection)) and end (SCI_GETSELECTIONNEND(int selection)) positions for each selection.

wmjordan avatar Aug 13 '21 00:08 wmjordan

I made a "compatible copy" script to cope with this issue. This script only copies plain text from BowPad, without setting extra fields into the clipboard content. If selection length is zero, the fix for #333 (version 2.8.8) is required to copy the line into clipboard.

Copy.zip

wmjordan avatar May 25 '23 00:05 wmjordan