Diff
Modified: trunk/Source/WebCore/ChangeLog (99923 => 99924)
--- trunk/Source/WebCore/ChangeLog 2011-11-11 02:15:44 UTC (rev 99923)
+++ trunk/Source/WebCore/ChangeLog 2011-11-11 04:12:14 UTC (rev 99924)
@@ -1,3 +1,54 @@
+2011-11-10 Daniel Cheng <[email protected]>
+
+ Atomically update the system clipboard for copy/cut events
+ https://bugs.webkit.org/show_bug.cgi?id=40515
+
+ Reviewed by David Levin.
+
+ This change consolidates the system pasteboard mutation logic into dispatchCPPEvent() rather
+ than having it scattered throughout tryDHTMLCopy/tryDHTMLCut and the various Clipboard*
+ classes. This allows us to ensure that the system pasteboard remains in a consistent state
+ even if there's an exception thrown during event handling, and it also lays the ground work
+ for allowing pages to prevent copy/cut without causing the system pasteboard to be cleared.
+
+ No new tests, since any layout test would be flaky since it would depend on and affect
+ global system state.
+
+ * editing/Editor.cpp:
+ (WebCore::Editor::tryDHTMLCopy): Move Pasteboard::clear() call to dispatchCPPEvent().
+ (WebCore::Editor::tryDHTMLCut): Ditto.
+ (WebCore::Editor::dispatchCPPEvent):
+ Only persist Clipboard mutations to the system pasteboard if the event was dispatched
+ successfully and default processing was prevented.
+ * editing/mac/EditorMac.mm:
+ (WebCore::Editor::newGeneralClipboard):
+ When creating a Clipboard for copy/cut, back it with a unique instance of NSPasteboard to
+ buffer pasteboard mutations.
+ * platform/Pasteboard.h:
+ * platform/chromium/PasteboardChromium.cpp:
+ (WebCore::Pasteboard::writeClipboard):
+ * platform/efl/PasteboardEfl.cpp:
+ (WebCore::Pasteboard::writeClipboard):
+ * platform/gtk/ClipboardGtk.cpp: Moved pasteboard writeback to PasteboardGtk.
+ (WebCore::ClipboardGtk::setData):
+ * platform/gtk/ClipboardGtk.h:
+ (WebCore::ClipboardGtk::clipboard):
+ * platform/gtk/PasteboardGtk.cpp:
+ (WebCore::Pasteboard::writeClipboard):
+ * platform/mac/PasteboardMac.mm:
+ (WebCore::Pasteboard::writeClipboard):
+ Implement logic to flush data from temporary NSPasteboard to system pasteboard.
+ * platform/gtk/ClipboardGtk.cpp: Moved pasteboard writeback to PasteboardQt.
+ (WebCore::ClipboardGtk::setData):
+ * platform/qt/PasteboardQt.cpp:
+ (WebCore::Pasteboard::writeClipboard):
+ * platform/win/PasteboardWin.cpp:
+ (WebCore::Pasteboard::writeClipboard):
+ * platform/wince/PasteboardWinCE.cpp:
+ (WebCore::Pasteboard::writeClipboard):
+ * platform/wx/PasteboardWx.cpp:
+ (WebCore::Pasteboard::writeClipboard):
+
2011-11-10 Julien Chaffraix <[email protected]>
RenderTableSection's recalcCell logic is doing too much work
Modified: trunk/Source/WebCore/editing/Editor.cpp (99923 => 99924)
--- trunk/Source/WebCore/editing/Editor.cpp 2011-11-11 02:15:44 UTC (rev 99923)
+++ trunk/Source/WebCore/editing/Editor.cpp 2011-11-11 04:12:14 UTC (rev 99924)
@@ -446,11 +446,6 @@
if (m_frame->selection()->isInPasswordField())
return false;
- if (canCopy())
- // Must be done before oncopy adds types and data to the pboard,
- // also done for security, as it erases data from the last copy/paste.
- Pasteboard::generalPasteboard()->clear();
-
return !dispatchCPPEvent(eventNames().copyEvent, ClipboardWritable);
}
@@ -459,11 +454,6 @@
if (m_frame->selection()->isInPasswordField())
return false;
- if (canCut())
- // Must be done before oncut adds types and data to the pboard,
- // also done for security, as it erases data from the last copy/paste.
- Pasteboard::generalPasteboard()->clear();
-
return !dispatchCPPEvent(eventNames().cutEvent, ClipboardWritable);
}
@@ -746,6 +736,11 @@
RefPtr<Event> evt = ClipboardEvent::create(eventType, true, true, clipboard);
target->dispatchEvent(evt, ec);
bool noDefaultProcessing = evt->defaultPrevented();
+ if (noDefaultProcessing && policy == ClipboardWritable) {
+ Pasteboard* pasteboard = Pasteboard::generalPasteboard();
+ pasteboard->clear();
+ pasteboard->writeClipboard(clipboard.get());
+ }
// invalidate clipboard here for security
clipboard->setAccessPolicy(ClipboardNumb);
Modified: trunk/Source/WebCore/editing/mac/EditorMac.mm (99923 => 99924)
--- trunk/Source/WebCore/editing/mac/EditorMac.mm 2011-11-11 02:15:44 UTC (rev 99923)
+++ trunk/Source/WebCore/editing/mac/EditorMac.mm 2011-11-11 04:12:14 UTC (rev 99924)
@@ -48,7 +48,8 @@
PassRefPtr<Clipboard> Editor::newGeneralClipboard(ClipboardAccessPolicy policy, Frame* frame)
{
- return ClipboardMac::create(Clipboard::CopyAndPaste, [NSPasteboard generalPasteboard], policy, frame);
+ return ClipboardMac::create(Clipboard::CopyAndPaste,
+ policy == ClipboardWritable ? [NSPasteboard pasteboardWithUniqueName] : [NSPasteboard generalPasteboard], policy, frame);
}
void Editor::showFontPanel()
Modified: trunk/Source/WebCore/platform/Pasteboard.h (99923 => 99924)
--- trunk/Source/WebCore/platform/Pasteboard.h 2011-11-11 02:15:44 UTC (rev 99923)
+++ trunk/Source/WebCore/platform/Pasteboard.h 2011-11-11 04:12:14 UTC (rev 99924)
@@ -73,6 +73,7 @@
extern NSString *WebURLsWithTitlesPboardType;
#endif
+class Clipboard;
class DocumentFragment;
class Frame;
class HitTestResult;
@@ -102,6 +103,7 @@
void writeFileWrapperAsRTFDAttachment(NSFileWrapper*);
String asURL(Frame*);
#endif
+ void writeClipboard(Clipboard*);
void clear();
bool canSmartReplace();
PassRefPtr<DocumentFragment> documentFragment(Frame*, PassRefPtr<Range>, bool allowPlainText, bool& chosePlainText);
Modified: trunk/Source/WebCore/platform/chromium/PasteboardChromium.cpp (99923 => 99924)
--- trunk/Source/WebCore/platform/chromium/PasteboardChromium.cpp 2011-11-11 02:15:44 UTC (rev 99923)
+++ trunk/Source/WebCore/platform/chromium/PasteboardChromium.cpp 2011-11-11 04:12:14 UTC (rev 99924)
@@ -155,6 +155,10 @@
PlatformSupport::clipboardWriteImage(bitmap, url, title);
}
+void Pasteboard::writeClipboard(Clipboard*)
+{
+}
+
bool Pasteboard::canSmartReplace()
{
return PlatformSupport::clipboardIsFormatAvailable(PasteboardPrivate::WebSmartPasteFormat, m_selectionMode ? PasteboardPrivate::SelectionBuffer : PasteboardPrivate::StandardBuffer);
Modified: trunk/Source/WebCore/platform/efl/PasteboardEfl.cpp (99923 => 99924)
--- trunk/Source/WebCore/platform/efl/PasteboardEfl.cpp 2011-11-11 02:15:44 UTC (rev 99923)
+++ trunk/Source/WebCore/platform/efl/PasteboardEfl.cpp 2011-11-11 04:12:14 UTC (rev 99924)
@@ -66,6 +66,11 @@
notImplemented();
}
+void Pasteboard::writeClipboard(Clipboard*)
+{
+ notImplemented();
+}
+
void Pasteboard::clear()
{
notImplemented();
Modified: trunk/Source/WebCore/platform/gtk/ClipboardGtk.cpp (99923 => 99924)
--- trunk/Source/WebCore/platform/gtk/ClipboardGtk.cpp 2011-11-11 02:15:44 UTC (rev 99923)
+++ trunk/Source/WebCore/platform/gtk/ClipboardGtk.cpp 2011-11-11 04:12:14 UTC (rev 99924)
@@ -181,9 +181,6 @@
success = true;
}
- if (success && m_clipboard)
- PasteboardHelper::defaultPasteboardHelper()->writeClipboardContents(m_clipboard);
-
return success;
}
Modified: trunk/Source/WebCore/platform/gtk/ClipboardGtk.h (99923 => 99924)
--- trunk/Source/WebCore/platform/gtk/ClipboardGtk.h 2011-11-11 02:15:44 UTC (rev 99923)
+++ trunk/Source/WebCore/platform/gtk/ClipboardGtk.h 2011-11-11 04:12:14 UTC (rev 99924)
@@ -73,6 +73,7 @@
virtual bool hasData();
PassRefPtr<DataObjectGtk> dataObject() { return m_dataObject; }
+ GtkClipboard* clipboard() { return m_clipboard; }
private:
ClipboardGtk(ClipboardAccessPolicy, GtkClipboard*, Frame*);
Modified: trunk/Source/WebCore/platform/gtk/PasteboardGtk.cpp (99923 => 99924)
--- trunk/Source/WebCore/platform/gtk/PasteboardGtk.cpp 2011-11-11 02:15:44 UTC (rev 99923)
+++ trunk/Source/WebCore/platform/gtk/PasteboardGtk.cpp 2011-11-11 04:12:14 UTC (rev 99924)
@@ -20,6 +20,7 @@
#include "config.h"
#include "Pasteboard.h"
+#include "ClipboardGtk.h"
#include "DataObjectGtk.h"
#include "DocumentFragment.h"
#include "Frame.h"
@@ -131,6 +132,13 @@
PasteboardHelper::defaultPasteboardHelper()->writeClipboardContents(clipboard);
}
+void Pasteboard::writeClipboard(Clipboard* clipboard)
+{
+ GtkClipboard* gtkClipboard = static_cast<ClipboardGtk*>(clipboard)->clipboard();
+ if (gtkClipboard)
+ PasteboardHelper::defaultPasteboardHelper()->writeClipboardContents(gtkClipboard);
+}
+
void Pasteboard::clear()
{
gtk_clipboard_clear(gtk_clipboard_get_for_display(gdk_display_get_default(), GDK_SELECTION_CLIPBOARD));
Modified: trunk/Source/WebCore/platform/mac/PasteboardMac.mm (99923 => 99924)
--- trunk/Source/WebCore/platform/mac/PasteboardMac.mm 2011-11-11 02:15:44 UTC (rev 99923)
+++ trunk/Source/WebCore/platform/mac/PasteboardMac.mm 2011-11-11 04:12:14 UTC (rev 99924)
@@ -27,6 +27,7 @@
#import "Pasteboard.h"
#import "CachedResource.h"
+#import "ClipboardMac.h"
#import "DOMRangeInternal.h"
#import "Document.h"
#import "DocumentFragment.h"
@@ -320,6 +321,18 @@
writeFileWrapperAsRTFDAttachment(fileWrapperForImage(cachedImage, cocoaURL));
}
+void Pasteboard::writeClipboard(Clipboard* clipboard)
+{
+ NSPasteboard* pasteboard = static_cast<ClipboardMac*>(clipboard)->pasteboard();
+ NSArray* types = [pasteboard types];
+
+ [m_pasteboard.get() addTypes:types owner:nil];
+ for (NSUInteger i = 0; i < [types count]; i++) {
+ NSString* type = [types objectAtIndex:i];
+ [m_pasteboard.get() setData:[pasteboard dataForType:type] forType:type];
+ }
+}
+
bool Pasteboard::canSmartReplace()
{
return [[m_pasteboard.get() types] containsObject:WebSmartPastePboardType];
Modified: trunk/Source/WebCore/platform/qt/ClipboardQt.cpp (99923 => 99924)
--- trunk/Source/WebCore/platform/qt/ClipboardQt.cpp 2011-11-11 02:15:44 UTC (rev 99923)
+++ trunk/Source/WebCore/platform/qt/ClipboardQt.cpp 2011-11-11 04:12:14 UTC (rev 99924)
@@ -185,10 +185,6 @@
m_writableData->setData(QString(type), array);
}
-#ifndef QT_NO_CLIPBOARD
- if (isForCopyAndPaste())
- QGuiApplication::clipboard()->setMimeData(m_writableData);
-#endif
return true;
}
Modified: trunk/Source/WebCore/platform/qt/PasteboardQt.cpp (99923 => 99924)
--- trunk/Source/WebCore/platform/qt/PasteboardQt.cpp 2011-11-11 02:15:44 UTC (rev 99923)
+++ trunk/Source/WebCore/platform/qt/PasteboardQt.cpp 2011-11-11 04:12:14 UTC (rev 99924)
@@ -28,6 +28,7 @@
#include "config.h"
#include "Pasteboard.h"
+#include "ClipboardQt.h"
#include "DocumentFragment.h"
#include "Editor.h"
#include "Frame.h"
@@ -172,6 +173,13 @@
#endif
}
+void Pasteboard::writeClipboard(Clipboard* clipboard)
+{
+#ifndef QT_NO_CLIPBOARD
+ QGuiApplication::clipboard()->setMimeData(static_cast<ClipboardQt*>(clipboard)->clipboardData());
+#endif
+}
+
/* This function is called from Editor::tryDHTMLCopy before actually set the clipboard
* It introduce a race condition with klipper, which will try to grab the clipboard
* It's not required to clear it anyway, since QClipboard take care about replacing the clipboard
Modified: trunk/Source/WebCore/platform/win/PasteboardWin.cpp (99923 => 99924)
--- trunk/Source/WebCore/platform/win/PasteboardWin.cpp 2011-11-11 02:15:44 UTC (rev 99923)
+++ trunk/Source/WebCore/platform/win/PasteboardWin.cpp 2011-11-11 04:12:14 UTC (rev 99924)
@@ -35,6 +35,7 @@
#include "HitTestResult.h"
#include "Image.h"
#include "KURL.h"
+#include "NotImplemented.h"
#include "Page.h"
#include "Range.h"
#include "RenderImage.h"
@@ -250,6 +251,11 @@
}
}
+void Pasteboard::writeClipboard(Clipboard*)
+{
+ notImplemented();
+}
+
bool Pasteboard::canSmartReplace()
{
return ::IsClipboardFormatAvailable(WebSmartPasteFormat);
Modified: trunk/Source/WebCore/platform/wince/PasteboardWinCE.cpp (99923 => 99924)
--- trunk/Source/WebCore/platform/wince/PasteboardWinCE.cpp 2011-11-11 02:15:44 UTC (rev 99923)
+++ trunk/Source/WebCore/platform/wince/PasteboardWinCE.cpp 2011-11-11 04:12:14 UTC (rev 99924)
@@ -36,6 +36,7 @@
#include "HitTestResult.h"
#include "Image.h"
#include "KURL.h"
+#include "NotImplemented.h"
#include "Page.h"
#include "Range.h"
#include "RenderImage.h"
@@ -231,6 +232,11 @@
DeleteObject(resultBitmap);
}
+void Pasteboard::writeClipboard(Clipboard*)
+{
+ notImplemented();
+}
+
bool Pasteboard::canSmartReplace()
{
return ::IsClipboardFormatAvailable(WebSmartPasteFormat);
Modified: trunk/Source/WebCore/platform/wx/PasteboardWx.cpp (99923 => 99924)
--- trunk/Source/WebCore/platform/wx/PasteboardWx.cpp 2011-11-11 02:15:44 UTC (rev 99923)
+++ trunk/Source/WebCore/platform/wx/PasteboardWx.cpp 2011-11-11 04:12:14 UTC (rev 99924)
@@ -105,6 +105,11 @@
}
}
+void Pasteboard::writeClipboard(Clipboard*)
+{
+ notImplemented();
+}
+
void Pasteboard::clear()
{
wxTheClipboard->Clear();