WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
40515
Atomically update the system clipboard for copy/cut events
https://bugs.webkit.org/show_bug.cgi?id=40515
Summary
Atomically update the system clipboard for copy/cut events
Daniel Cheng
Reported
2010-06-11 20:50:51 PDT
Right now, the various Clipboard implementations contain a lot of platform-specific details. We should create a new platform object (like DragData) to abstract away the interactions with platform data.
Attachments
Patch
(15.78 KB, patch)
2010-06-11 22:29 PDT
,
Daniel Cheng
no flags
Details
Formatted Diff
Diff
Patch
(16.12 KB, patch)
2010-06-12 04:23 PDT
,
Daniel Cheng
no flags
Details
Formatted Diff
Diff
Patch
(15.64 KB, patch)
2010-06-12 04:28 PDT
,
Daniel Cheng
no flags
Details
Formatted Diff
Diff
Patch
(15.64 KB, patch)
2010-06-12 04:55 PDT
,
Daniel Cheng
no flags
Details
Formatted Diff
Diff
Patch
(12.90 KB, patch)
2011-11-02 14:27 PDT
,
Daniel Cheng
no flags
Details
Formatted Diff
Diff
Patch
(14.50 KB, patch)
2011-11-09 16:28 PST
,
Daniel Cheng
no flags
Details
Formatted Diff
Diff
Patch
(14.43 KB, patch)
2011-11-10 16:03 PST
,
Daniel Cheng
no flags
Details
Formatted Diff
Diff
Patch
(14.49 KB, patch)
2011-11-10 17:11 PST
,
Daniel Cheng
levin
: review+
Details
Formatted Diff
Diff
Show Obsolete
(7)
View All
Add attachment
proposed patch, testcase, etc.
Daniel Cheng
Comment 1
2010-06-11 22:29:39 PDT
Created
attachment 58540
[details]
Patch
WebKit Review Bot
Comment 2
2010-06-11 22:38:26 PDT
Attachment 58540
[details]
did not pass style-queue: Failed to run "['WebKitTools/Scripts/check-webkit-style', '--no-squash']" exit_code: 1 Webcore/platform/ClipboardData.h:1: One or more unexpected \r (^M) found; better to use only a \n [whitespace/carriage_return] [1] Suppressing further [whitespace/carriage_return] reports for this file. Webcore/platform/ClipboardData.cpp:1: One or more unexpected \r (^M) found; better to use only a \n [whitespace/carriage_return] [1] Suppressing further [whitespace/carriage_return] reports for this file. Total errors found: 145 in 11 files If any of these errors are false positives, please file a bug against check-webkit-style.
Early Warning System Bot
Comment 3
2010-06-11 22:43:32 PDT
Attachment 58540
[details]
did not build on qt: Build output:
http://webkit-commit-queue.appspot.com/results/3183339
WebKit Review Bot
Comment 4
2010-06-11 22:53:49 PDT
Attachment 58540
[details]
did not build on gtk: Build output:
http://webkit-commit-queue.appspot.com/results/3198315
Daniel Cheng
Comment 5
2010-06-12 04:23:23 PDT
Created
attachment 58547
[details]
Patch
Daniel Cheng
Comment 6
2010-06-12 04:28:43 PDT
Created
attachment 58548
[details]
Patch Fix bad merge.
Early Warning System Bot
Comment 7
2010-06-12 04:35:56 PDT
Attachment 58547
[details]
did not build on qt: Build output:
http://webkit-commit-queue.appspot.com/results/3200329
Early Warning System Bot
Comment 8
2010-06-12 04:40:47 PDT
Attachment 58548
[details]
did not build on qt: Build output:
http://webkit-commit-queue.appspot.com/results/3249326
Daniel Cheng
Comment 9
2010-06-12 04:55:24 PDT
Created
attachment 58549
[details]
Patch Fix build break (paths had incorrect case)
WebKit Review Bot
Comment 10
2010-06-12 05:05:36 PDT
Attachment 58547
[details]
did not build on gtk: Build output:
http://webkit-commit-queue.appspot.com/results/3186342
Daniel Cheng
Comment 11
2010-06-16 18:04:13 PDT
Darin, do you mind reviewing this patch?
https://bugs.webkit.org/show_bug.cgi?id=40455
isn't complete, but it shows how this proposed patch would be used.
Darin Adler
Comment 12
2010-06-29 15:05:07 PDT
Comment on
attachment 58549
[details]
Patch
> +class ClipboardData : public RefCounted<ClipboardData> {
This seems fine, but I'm not sure why it's an abstract base class. Generally speaking the platform directory does not use runtime factories that vend objects of abstract base classes. I have seen other libraries that use this approach, but it has runtime costs that we prefer not to pay in WebKit. The interface here looks generally OK in terms of what the functions are and the argument types, but the basic approach does not seem right. An example of how we do this without virtual functions is in the FileChooser.h source file. Not sure that needs to be a reference-counted object, but otherwise it's a reasonable example. DragData.h is another example, although a particularly messy one.
Daniel Cheng
Comment 13
2010-06-30 17:08:31 PDT
(In reply to
comment #12
)
> (From update of
attachment 58549
[details]
) > > +class ClipboardData : public RefCounted<ClipboardData> { > > This seems fine, but I'm not sure why it's an abstract base class. Generally speaking the platform directory does not use runtime factories that vend objects of abstract base classes. I have seen other libraries that use this approach, but it has runtime costs that we prefer not to pay in WebKit. > > The interface here looks generally OK in terms of what the functions are and the argument types, but the basic approach does not seem right. > > An example of how we do this without virtual functions is in the FileChooser.h source file. Not sure that needs to be a reference-counted object, but otherwise it's a reasonable example. DragData.h is another example, although a particularly messy one.
The interface is virtual because there are two implementations for a given platform: 1. One implementation that lives under platform. This provides a read-only implementation of ClipboardData which wraps accessing native copy/paste and drag/drop data. 2. Another common implementation that lives in a location TBD. It is primarily intended for writing (in the cut/copy/dragstart events), though you can read from it as well. The reason for creating two separate implementations like this is because I found the way the current Clipboard worked to be a little wonky: - When starting drags, platform implementations of Clipboard simply allow data members to be set. At some point, DragClient::startDrag is called and the implementation atomically creates a data object and sets all data that will be in that drag. - For copy/cut operations, Clipboard immediately writes back to the clipboard, so Clipboard contents won't be set atomically. Thus, we end up with Clipboard implementations that look like: if (m_isForDragging) { m_foo = bar; } else { // FIXME: Add Pasteboard support. } This is true for Windows WebKit, Chromium WebKit, and probably a number of other platforms as well. - If writing drag data and copy data are abstracted by one generic object, then Clipboard becomes much simpler. Persisting data to the clipboard might look like this instead: if (clipboard.isDirty()) { Pasteboard::clear(); Pasteboard::writeData(clipboard); } This also has the bonus side effect that preventing a copy or cut no longer clears the Pasteboard contents, which follows IE behavior.
Daniel Cheng
Comment 14
2011-11-02 14:27:01 PDT
Created
attachment 113377
[details]
Patch
Daniel Cheng
Comment 15
2011-11-03 12:02:18 PDT
Darin, do you mind taking another look at this? We'll need this change to fix
https://bugs.webkit.org/show_bug.cgi?id=34288
, so that simply preventing the default action without setting any data doesn't cause the clipboard to get cleared on copy/cut.
Daniel Cheng
Comment 16
2011-11-07 12:06:07 PST
I've completely rewritten this patch, and I think it should address previous review concerns to this patch. There is no more ClipboardData interface, so if you could take another look, that'd be great.
Darin Adler
Comment 17
2011-11-07 12:30:02 PST
Comment on
attachment 113377
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=113377&action=review
> Source/WebCore/editing/Editor.cpp:743 > + if (noDefaultProcessing && policy == ClipboardWritable) { > + Pasteboard* pasteboard = Pasteboard::generalPasteboard(); > + pasteboard->clear(); > + pasteboard->writeClipboard(clipboard.get()); > + }
If the actual pasteboard processing is done in this function, then the name dispatchCPPEvent is inappropriate. Is that something new to this patch, or has it always been true.
Daniel Cheng
Comment 18
2011-11-07 12:50:32 PST
(In reply to
comment #17
)
> (From update of
attachment 113377
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=113377&action=review
> > > Source/WebCore/editing/Editor.cpp:743 > > + if (noDefaultProcessing && policy == ClipboardWritable) { > > + Pasteboard* pasteboard = Pasteboard::generalPasteboard(); > > + pasteboard->clear(); > > + pasteboard->writeClipboard(clipboard.get()); > > + } > > If the actual pasteboard processing is done in this function, then the name dispatchCPPEvent is inappropriate. Is that something new to this patch, or has it always been true.
This has always been true, but the pasteboard mutation wasn't as obvious before--it was happening inside Clipboard::setData().
Daniel Cheng
Comment 19
2011-11-07 14:01:24 PST
(In reply to
comment #17
)
> (From update of
attachment 113377
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=113377&action=review
> > > Source/WebCore/editing/Editor.cpp:743 > > + if (noDefaultProcessing && policy == ClipboardWritable) { > > + Pasteboard* pasteboard = Pasteboard::generalPasteboard(); > > + pasteboard->clear(); > > + pasteboard->writeClipboard(clipboard.get()); > > + } > > If the actual pasteboard processing is done in this function, then the name dispatchCPPEvent is inappropriate. Is that something new to this patch, or has it always been true.
I thought about ways to split up dispatchCPPEvent to move the pasteboard processing out of dispatchCPPEvent, but I can't think of any good way without duplicating some of the boilerplate to set up the clipboard event and fire it. What makes dispatchCPPEvent an inappropriate name, and do you have suggestions on how this can be addressed?
David Levin
Comment 20
2011-11-08 13:49:49 PST
Comment on
attachment 113377
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=113377&action=review
> Source/WebCore/ChangeLog:8 > + Add a Pasteboard::writeClipboard() method which is roughly analogous to
Part of this should be the comment for dispatchCPPEvent.
> Source/WebCore/ChangeLog:12 > + Covered by existing tests.
It is only covered by existing tests if 1. It is only a refactoring (but that is not the case here as I see new function calls). 2. An existing test is broken and this fixes it, but I don't see a new baseline for a test. So what is testing these new api calls?/Why are they needed?
> Source/WebCore/ChangeLog:15 > + (WebCore::Editor::tryDHTMLCopy):
Ideally your changelog would have an explanation of what was done in each function. For example, it would say "Move clear call to dispatchCPPEvent" here. Think of this like a breadcrumb trail for the reviewer so they don't need to piece as much together.
> Source/WebCore/ChangeLog:16 > + (WebCore::Editor::tryDHTMLCut):
Here "Ditto"
>>>> Source/WebCore/editing/Editor.cpp:743 >>>> + } >>> >>> If the actual pasteboard processing is done in this function, then the name dispatchCPPEvent is inappropriate. Is that something new to this patch, or has it always been true. >> >> This has always been true, but the pasteboard mutation wasn't as obvious before--it was happening inside Clipboard::setData(). > > I thought about ways to split up dispatchCPPEvent to move the pasteboard processing out of dispatchCPPEvent, but I can't think of any good way without duplicating some of the boilerplate to set up the clipboard event and fire it. What makes dispatchCPPEvent an inappropriate name, and do you have suggestions on how this can be addressed?
It dispatches the event on line 737 but then this stuff is extra. Please describe what this function does and then we can find a name.
> Source/WebCore/editing/mac/EditorMac.mm:52 > + policy == ClipboardWritable ? [NSPasteboard pasteboardWithUniqueName] : [NSPasteboard generalPasteboard], policy, frame);
The changelog should tell me why this change is being done.
> Source/WebCore/platform/mac/PasteboardMac.mm:333 > + }
Why is this code needed now? (Hint: The ChangeLog should tell me.)
> Source/WebCore/platform/qt/PasteboardQt.cpp:179 > + static_cast<ClipboardQt*>(clipboard)->clipboardData());
No need for a carriage return here. What does this fix? (Hint: I should know due to the ChangeLog.)
> Source/WebCore/platform/wince/PasteboardWinCE.cpp:39 > +#include "NotImplemented.h"
Why include this header and not use notImplemented?
Daniel Cheng
Comment 21
2011-11-09 16:28:40 PST
Created
attachment 114391
[details]
Patch
Daniel Cheng
Comment 22
2011-11-10 16:03:24 PST
Created
attachment 114592
[details]
Patch
Daniel Cheng
Comment 23
2011-11-10 16:05:30 PST
Comment on
attachment 113377
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=113377&action=review
>> Source/WebCore/ChangeLog:8 >> + Add a Pasteboard::writeClipboard() method which is roughly analogous to > > Part of this should be the comment for dispatchCPPEvent.
Done.
>> Source/WebCore/ChangeLog:12 >> + Covered by existing tests. > > It is only covered by existing tests if > 1. It is only a refactoring (but that is not the case here as I see new function calls). > 2. An existing test is broken and this fixes it, but I don't see a new baseline for a test. > > So what is testing these new api calls?/Why are they needed?
Done.
>> Source/WebCore/ChangeLog:15 >> + (WebCore::Editor::tryDHTMLCopy): > > Ideally your changelog would have an explanation of what was done in each function. > > For example, it would say "Move clear call to dispatchCPPEvent" here. Think of this like a breadcrumb trail for the reviewer so they don't need to piece as much together.
Done.
>> Source/WebCore/ChangeLog:16 >> + (WebCore::Editor::tryDHTMLCut): > > Here "Ditto"
Done.
>>>>> Source/WebCore/editing/Editor.cpp:743
>>>> >>>> If the actual pasteboard processing is done in this function, then the name dispatchCPPEvent is inappropriate. Is that something new to this patch, or has it always been true. >>> >>> This has always been true, but the pasteboard mutation wasn't as obvious before--it was happening inside Clipboard::setData(). >> >> I thought about ways to split up dispatchCPPEvent to move the pasteboard processing out of dispatchCPPEvent, but I can't think of any good way without duplicating some of the boilerplate to set up the clipboard event and fire it. What makes dispatchCPPEvent an inappropriate name, and do you have suggestions on how this can be addressed? > > It dispatches the event on line 737 but then this stuff is extra. Please describe what this function does and then we can find a name.
Done... I think.
>> Source/WebCore/editing/mac/EditorMac.mm:52 >> + policy == ClipboardWritable ? [NSPasteboard pasteboardWithUniqueName] : [NSPasteboard generalPasteboard], policy, frame); > > The changelog should tell me why this change is being done.
Done.
>> Source/WebCore/platform/mac/PasteboardMac.mm:333 >> + } > > Why is this code needed now? (Hint: The ChangeLog should tell me.)
Done.
>> Source/WebCore/platform/qt/PasteboardQt.cpp:179 >> + static_cast<ClipboardQt*>(clipboard)->clipboardData()); > > No need for a carriage return here. > > What does this fix? (Hint: I should know due to the ChangeLog.)
Done.
>> Source/WebCore/platform/wince/PasteboardWinCE.cpp:39 >> +#include "NotImplemented.h" > > Why include this header and not use notImplemented?
Done.
David Levin
Comment 24
2011-11-10 16:51:51 PST
Comment on
attachment 114592
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=114592&action=review
Just one question before I r+.
> Source/WebCore/platform/gtk/PasteboardGtk.cpp:138 > + static_cast<ClipboardGtk*>(clipboard)->clipboard());
Why did it check m_clipboard before but now it doesn't?
Daniel Cheng
Comment 25
2011-11-10 16:58:11 PST
Comment on
attachment 114592
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=114592&action=review
>> Source/WebCore/platform/gtk/PasteboardGtk.cpp:138 >> + static_cast<ClipboardGtk*>(clipboard)->clipboard()); > > Why did it check m_clipboard before but now it doesn't?
Because m_clipboard was only accessible to ClipboardGtk. I added an accessor for it so we can use it in PasteboardGtk as well.
David Levin
Comment 26
2011-11-10 17:01:02 PST
(In reply to
comment #25
)
> (From update of
attachment 114592
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=114592&action=review
> > >> Source/WebCore/platform/gtk/PasteboardGtk.cpp:138 > >> + static_cast<ClipboardGtk*>(clipboard)->clipboard()); > > > > Why did it check m_clipboard before but now it doesn't? > > Because m_clipboard was only accessible to ClipboardGtk. I added an accessor for it so we can use it in PasteboardGtk as well.
I'll be more verbose. Prior code: if (success && m_clipboard) PasteboardHelper::defaultPasteboardHelper()->writeClipboardContents(m_clipboard); Why was the prior code checking that m_clipboard wasn't NULL but the current code uses the equivalent "static_cast<ClipboardGtk*>(clipboard)->clipboard()" without doing a NULL check: PasteboardHelper::defaultPasteboardHelper()->writeClipboardContents( static_cast<ClipboardGtk*>(clipboard)->clipboard()); If you answered this just now, I didn't understand the answer.
Daniel Cheng
Comment 27
2011-11-10 17:11:39 PST
Created
attachment 114607
[details]
Patch
Daniel Cheng
Comment 28
2011-11-10 17:12:08 PST
Comment on
attachment 114592
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=114592&action=review
>>>> Source/WebCore/platform/gtk/PasteboardGtk.cpp:138 >>>> + static_cast<ClipboardGtk*>(clipboard)->clipboard()); >>> >>> Why did it check m_clipboard before but now it doesn't? >> >> Because m_clipboard was only accessible to ClipboardGtk. I added an accessor for it so we can use it in PasteboardGtk as well. > > I'll be more verbose. > > Prior code: > if (success && m_clipboard) > PasteboardHelper::defaultPasteboardHelper()->writeClipboardContents(m_clipboard); > > Why was the prior code checking that m_clipboard wasn't NULL but the current code uses the equivalent "static_cast<ClipboardGtk*>(clipboard)->clipboard()" without doing a NULL check: > > PasteboardHelper::defaultPasteboardHelper()->writeClipboardContents( > static_cast<ClipboardGtk*>(clipboard)->clipboard()); > > If you answered this just now, I didn't understand the answer.
Good point. Fixed.
Daniel Cheng
Comment 29
2011-11-10 20:12:25 PST
Committed
r99924
: <
http://trac.webkit.org/changeset/99924
>
Ryosuke Niwa
Comment 30
2011-11-23 10:57:40 PST
Why did this test land without any tests? This patch changes the timing at which copy/cut/paste events are dispatched and therefore need to be tested.
Ryosuke Niwa
Comment 31
2011-11-23 11:03:51 PST
(In reply to
comment #30
)
> Why did this patch land without any tests? This patch changes the timing at which copy/cut/paste events are dispatched and therefore need to be tested.
On second thought, this might be okay since this change only affects copy and cut both of which can't read clipboard data
Daniel Cheng
Comment 32
2011-11-23 11:05:45 PST
(In reply to
comment #31
)
> (In reply to
comment #30
) > > Why did this patch land without any tests? This patch changes the timing at which copy/cut/paste events are dispatched and therefore need to be tested. > > On second thought, this might be okay since this change only affects copy and cut both of which can't read clipboard data
This was a mistake on my part. I thought that pasteboard tests that interacted with the system clipboard would be inherently flaky due to the global nature of the clipboard, but it appears we correctly handle that case today. I am working on followup tests and will be landing them in a separate patch.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug