Bug 140813 - Use GetUpdatedClipboardFormats Vista API to minimize clipboard-related overhead
Summary: Use GetUpdatedClipboardFormats Vista API to minimize clipboard-related overhead
Status: RESOLVED FIXED
Alias: None
Product: LibreOffice
Classification: Unclassified
Component: LibreOffice (show other bugs)
Version:
(earliest affected)
unspecified
Hardware: All Windows (All)
: medium normal
Assignee: Mike Kaganski
URL:
Whiteboard: target:7.2.0 target:7.1.3
Keywords:
Depends on:
Blocks:
 
Reported: 2021-03-05 08:22 UTC by Mike Kaganski
Modified: 2021-08-27 07:29 UTC (History)
2 users (show)

See Also:
Crash report or crash signature:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mike Kaganski 2021-03-05 08:22:35 UTC
Currently LibreOffice uses a dedicated thread to respond to clipboard change notifications (see CMtaOleClipboard in vcl/win/dtrans/MtaOleClipb.cxx), which obtains an IDataObject (using OleGetClipboard) for the updated clipboard data, and stores it for possible further use. The object is wrapped into an appartment-neutral object in CWinClipboard::getContents (vcl/win/dtrans/WinClipboard.cxx). This object is later queried for available formats when deciding if Paste should be enabled, and which paste options to provide. Often, this is the only information needed, because not every data in clipboard ends up in LibreOffice.

This is (a) rather expensive (obtaining a COM object, creating an appartment-neutral wrapper over it, having to properly release it at the next clipboard update - for each clipboard event, regardless if we will use the data or not), and (b) prone to errors (see e.g. tdf#136175; also there are hangs sometimes in unit testing, caused by deadlocking of released COM object waiting for a thread that is waiting for its release).

Since Windows Vista, there's GetUpdatedClipboardFormats function [1] created to list available formats in the system clipboard without opening it, and so without race conditions [2] [3]. We could possibly reimplement the thread to only get the list of available formats using this function, and only obtain the COM object when actually pasting something. That would require that the XTransferable returned from CWinClipboard::getContents would be able to ask for the IDataObject only when needed.

[1] https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getupdatedclipboardformats
[2] https://techcommunity.microsoft.com/t5/microsoft-security-and/why-does-my-shared-clipboard-not-work-part-2/ba-p/246465
[3] https://support.citrix.com/article/CTX216506
Comment 1 Commit Notification 2021-03-06 06:13:17 UTC
Mike Kaganski committed a patch related to this issue.
It has been pushed to "master":

https://git.libreoffice.org/core/commit/7b6c0e63e64eb2ad1e83bd744a0d20f78c7a6b84

tdf#140813: Use GetUpdatedClipboardFormats to enumerate clipboard formats

It will be available in 7.2.0.

The patch should be included in the daily builds available at
https://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More
information about daily builds can be found at:
https://wiki.documentfoundation.org/Testing_Daily_Builds

Affected users are encouraged to test the fix and report feedback.
Comment 2 Timur 2021-03-06 07:40:09 UTC
I guess Win only. 
BTW, congrats for fixing the most annoying bug of clipboard paste :)
Comment 3 Mike Kaganski 2021-03-06 08:24:17 UTC
(In reply to Timur from comment #2)
> I guess Win only. 

Definitely; thanks.

> BTW, congrats for fixing the most annoying bug of clipboard paste :)

Thank you; that was mainly work of others who created a reproducer and outlined the solution :-)
Comment 4 Mike Kaganski 2021-03-25 14:22:30 UTC
Backport to 7-1 is at https://gerrit.libreoffice.org/c/core/+/112971, needed to fix the problem seen in bug 116983 comment 92.
Comment 5 Telesto 2021-03-30 12:24:36 UTC
Also thanks solving this and bug 136175. Those where nasty hard to catch bugs.. It's really a relieve knowing those are gone now :-)
Comment 6 Commit Notification 2021-03-31 03:50:38 UTC
Mike Kaganski committed a patch related to this issue.
It has been pushed to "libreoffice-7-1":

https://git.libreoffice.org/core/commit/5be35c2b1fe127f69223a92965cbbc92dab15c3b

tdf#140813: Use GetUpdatedClipboardFormats to enumerate clipboard formats

It will be available in 7.1.3.

The patch should be included in the daily builds available at
https://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More
information about daily builds can be found at:
https://wiki.documentfoundation.org/Testing_Daily_Builds

Affected users are encouraged to test the fix and report feedback.
Comment 7 Mike Kaganski 2021-03-31 13:20:15 UTC
(In reply to Telesto from comment #5)

Thank you for the reliable way to repro - that is the one most important bit that was missing from the original bug.