When ole has set the clipboard data, the clipboard manager may preempt this data (by sending a WM_RENDERFORMAT message). At this point the clipboard ownership may be occupied by the clipboard manager; resulting in a failure to flush the ole clipboard.
Signed-off-by: Haoyang Chen chenhaoyang@uniontech.com --- dlls/ole32/clipboard.c | 2 ++ dlls/ole32/tests/clipboard.c | 10 ++++++++++ 2 files changed, 12 insertions(+)
diff --git a/dlls/ole32/clipboard.c b/dlls/ole32/clipboard.c index e61b3076883..ebc498d52e7 100644 --- a/dlls/ole32/clipboard.c +++ b/dlls/ole32/clipboard.c @@ -2261,6 +2261,7 @@ HRESULT WINAPI OleFlushClipboard(void) HRESULT hr; ole_clipbrd *clipbrd; HWND wnd; + MSG msg;
TRACE("()\n");
@@ -2273,6 +2274,7 @@ HRESULT WINAPI OleFlushClipboard(void) */ if (!clipbrd->src_data) return S_OK;
+ PeekMessageW(&msg, wnd, WM_RENDERFORMAT, WM_RENDERFORMAT, PM_REMOVE); if (!OpenClipboard(wnd)) return CLIPBRD_E_CANT_OPEN;
SendMessageW(wnd, WM_RENDERALLFORMATS, 0, 0); diff --git a/dlls/ole32/tests/clipboard.c b/dlls/ole32/tests/clipboard.c index fd8f287680b..47700e7f3fd 100644 --- a/dlls/ole32/tests/clipboard.c +++ b/dlls/ole32/tests/clipboard.c @@ -1085,6 +1085,7 @@ static void test_set_clipboard_DRAWCLIPBOARD(void) HWND viewer; int ret; HANDLE thread; + int i;
hr = DataObjectImpl_CreateText("data", &data); ok(hr == S_OK, "Failed to create data object: 0x%08x\n", hr); @@ -1120,6 +1121,15 @@ static void test_set_clipboard_DRAWCLIPBOARD(void) ret = SendMessageA( viewer, WM_USER, 0, 0 ); ok( ret == 2, "%u WM_DRAWCLIPBOARD received\n", ret );
+ Sleep(500); + + for (i = 0; i < 10; i++) + { + hr = OleFlushClipboard(); + if (hr == S_OK) break; + Sleep(100); + } + ok(hr == S_OK, "got %08x\n", hr); clip_data = NULL; hr = OleFlushClipboard(); ok(hr == S_OK, "failed to flush clipboard, hr = 0x%08x\n", hr);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=90907
Your paranoid android.
=== debiant2 (32 bit WoW report) ===
ole32: clipboard.c:1053: Test failed: OleIsCurrentClipboard returned 0 clipboard.c:1053: Test failed: OleIsCurrentClipboard returned 1
Please ignore it, it needs more testing.
在 2021/5/20 下午3:07, Haoyang Chen 写道:
When ole has set the clipboard data, the clipboard manager may preempt this data (by sending a WM_RENDERFORMAT message). At this point the clipboard ownership may be occupied by the clipboard manager; resulting in a failure to flush the ole clipboard.
Signed-off-by: Haoyang Chen chenhaoyang@uniontech.com
dlls/ole32/clipboard.c | 2 ++ dlls/ole32/tests/clipboard.c | 10 ++++++++++ 2 files changed, 12 insertions(+)
diff --git a/dlls/ole32/clipboard.c b/dlls/ole32/clipboard.c index e61b3076883..ebc498d52e7 100644 --- a/dlls/ole32/clipboard.c +++ b/dlls/ole32/clipboard.c @@ -2261,6 +2261,7 @@ HRESULT WINAPI OleFlushClipboard(void) HRESULT hr; ole_clipbrd *clipbrd; HWND wnd;
MSG msg;
TRACE("()\n");
@@ -2273,6 +2274,7 @@ HRESULT WINAPI OleFlushClipboard(void) */ if (!clipbrd->src_data) return S_OK;
PeekMessageW(&msg, wnd, WM_RENDERFORMAT, WM_RENDERFORMAT, PM_REMOVE); if (!OpenClipboard(wnd)) return CLIPBRD_E_CANT_OPEN;
SendMessageW(wnd, WM_RENDERALLFORMATS, 0, 0);
diff --git a/dlls/ole32/tests/clipboard.c b/dlls/ole32/tests/clipboard.c index fd8f287680b..47700e7f3fd 100644 --- a/dlls/ole32/tests/clipboard.c +++ b/dlls/ole32/tests/clipboard.c @@ -1085,6 +1085,7 @@ static void test_set_clipboard_DRAWCLIPBOARD(void) HWND viewer; int ret; HANDLE thread;
int i;
hr = DataObjectImpl_CreateText("data", &data); ok(hr == S_OK, "Failed to create data object: 0x%08x\n", hr);
@@ -1120,6 +1121,15 @@ static void test_set_clipboard_DRAWCLIPBOARD(void) ret = SendMessageA( viewer, WM_USER, 0, 0 ); ok( ret == 2, "%u WM_DRAWCLIPBOARD received\n", ret );
- Sleep(500);
- for (i = 0; i < 10; i++)
- {
hr = OleFlushClipboard();
if (hr == S_OK) break;
Sleep(100);
- }
- ok(hr == S_OK, "got %08x\n", hr); clip_data = NULL; hr = OleFlushClipboard(); ok(hr == S_OK, "failed to flush clipboard, hr = 0x%08x\n", hr);
On Thu, 20 May 2021, Haoyang Chen wrote:
When ole has set the clipboard data, the clipboard manager may preempt this data (by sending a WM_RENDERFORMAT message). At this point the clipboard ownership may be occupied by the clipboard manager; resulting in a failure to flush the ole clipboard.
That's interesting. Could this explain all the ERROR_ACCESS_DENIED / CLIPBRD_E_CANT_OPEN errors we're getting, in ole32:clipboard and user32:clipboard?
But why do these happen mostly on cw-rx460? And why would tinkering with the Radeon driver settings make a difference despite no setting being a clear culprit? [1]
https://test.winehq.org/data/patterns.html#ole32:clipboard https://test.winehq.org/data/patterns.html#user32:clipboard
But even if it only leads to a way to avoid rare errors like this one (not on cx-rx460) that would be good: https://test.winehq.org/data/d7fecebe93938bf1ef2349ac74413e28d6b8e153/win180...
[1] For instance, starting from a situation where user32:clipboard fails systematically, it goes like this: - Reboot -> user32:clipboard still fails systematically - Turn off some setting -> no change (iirc) - Reboot -> failure rate falls to ~ 1/30 Okay, that means changing a feature only makes a difference after a reboot. - Turn feature back on -> still good, as expected - Reboot -> still good!!!