BowPad
BowPad copied to clipboard
Clipboard Operations May Not Work When Working with Remote Desktop Client
This issue does not always occur.
- Open BowPad.
- Open a Remote Desktop Client and connect to a remote machine.
- Click the Copy button or press Ctrl+C in BowPad.
- Don't paste to local applications. Switch to the Remote Desktop Client. The clipboard is cleared, but nothing is copied.
not really a problem of BowPad. See here: https://superuser.com/questions/95609/cant-copy-and-paste-in-remote-desktop-connection-session
It is a problem of BowPad. I could copy text from other text editors, NotePad, EditPlus, etc. But from BowPad, the operation often failed.
@songbaoming Have you ever experienced this issue that BowPad's copy function could fail when Remote Desktop Client was connected?
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)
}
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.
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.
Seems it's a known problem: https://www.techulator.com/resources/5607-Copy-pasting-clipboard-not-working-Remote.aspx
Hmm, I will try that.
@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.
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
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.
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?
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?
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).
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:
The code in AkelPad has used a different way to OpenClipboard(NULL)
. Will this make difference?
~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.
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.
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.
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.
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.
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.
script should work now again.
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.
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):
- Open the clipboard
- Get selection text
- Check whether the text is zero-length, if so, get current line
- Put the text into clipboard
- If is line-select, add two line-select indicator entries too
- Add HTML code when shift is pressed
- Add BP_Lexer entry
- Close clipboard
- If it is a Cut operation, remove the selection (if line-select, remove the whole line)
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...
https://groups.google.com/g/scintilla-interest/c/BeHASfsQJ7g/m/D-wABFBkAQAJ
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.
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.