sakura-editor / sakura

SAKURA Editor (Japanese text editor for MS Windows)
https://sakura-editor.github.io/
Other
1.23k stars 162 forks source link

マクロの Paste() が失敗する場合がある #1970

Open yoshinrt opened 1 month ago

yoshinrt commented 1 month ago

問題内容

マクロの Paste() が失敗することがあるようです.

再現手順

SetDrawSwitch( 0 );
Cut();
Paste();
SetDrawSwitch( 1 );
ReDraw();

上記のマクロをキーに割り当て,EOF以外 の行で実行すると,Paste() の実行に失敗し警告音が鳴ります.

https://github.com/sakura-editor/sakura/blob/fe4cc6d17e0e9f0e58f13c6c3cca9147b7751e32/sakura_core/_os/CClipboard.cpp#L42-L46

で ::OpenClipboard() に失敗し,

https://github.com/sakura-editor/sakura/blob/fe4cc6d17e0e9f0e58f13c6c3cca9147b7751e32/sakura_core/view/CEditView.cpp#L2295-L2297

の if が成立してしまうようです.

再現頻度

以上から,タイミングに依存している気がします.環境によってはなかなか再現しないかもしれません.

問題のカテゴリ

環境情報

スクリーンショット

beru commented 1 month ago

試してみましたがこちらでは再現しませんでした。EOF行で実行すると(切り取りするデータが無い為に)Cut() に失敗するので警告音が鳴って Paste() が行われます。

ところでサクラエディタのコピーってレイアウト行に限定したコピーなんですね。VS Codeだとロジック行丸ごとのコピーでした。

berryzplus commented 1 month ago

サクラエディタ開発当時と現代で「当たり前」の基準が変わってますよね。

::OpenClipboard(hwnd);が成功するまで ::Sleep(0); して数回リトライすべき、の見解です。

(既にどっかに詳細書いた記憶です。)

beru commented 1 month ago

OpenClipboard は失敗する事が普通にあるんですね、知らなかったです。

https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-openclipboard を読んでみると

OpenClipboard fails if another window has the clipboard open.

と書かれてますね。。

あと検索してヒットした https://groups.google.com/g/scintilla-interest/c/HIuFrgTL8RM?pli=1 には

On Windows the OpenClipboard call, used before reading or writing the clipboard, can fail. This may occur because another application has opened the clipboard. Currently Scintilla fails the Cut/Copy/Paste/… operation when it can not open the clipboard. Normally clipboard operations are driven by the user so do not often overlap. However, sometimes another application such as a clipboard viewer or a virtual machine with a bridged clipboard may be acting on the clipboard in the background. On my main Windows box, it appears that DropBox is causing problems by opening the clipboard when it changes.

It would be possible to retry the OpenClipboard call if it fails. Other APIs, such as the .Net Clipboard.SetDataObject include retry parameters with default behaviour of retrying up to 10 times with a delay between attempts of 100 milliseconds.

というような事が書かれてました。