Diff
Modified: trunk/Source/WebCore/ChangeLog (150099 => 150100)
--- trunk/Source/WebCore/ChangeLog 2013-05-15 03:17:43 UTC (rev 150099)
+++ trunk/Source/WebCore/ChangeLog 2013-05-15 04:27:42 UTC (rev 150100)
@@ -1,3 +1,44 @@
+2013-05-14 Darin Adler <da...@apple.com>
+
+ [Mac] Move setDragImage from ClipboardMac to PasteboardMac
+ https://bugs.webkit.org/show_bug.cgi?id=116036
+
+ Reviewed by Anders Carlsson.
+
+ * dom/Clipboard.cpp:
+ (WebCore::Clipboard::~Clipboard): Stop loading the drag image when
+ the clipboard object is deallocated. It would be better if there was
+ a more-well-defined time to stop the load.
+ (WebCore::Clipboard::setDragImage): Added. Sets up a drag image
+ based on a CachedImage. This tells the image loader to load the image
+ and updates the drag image when the image arrives. Copied from the
+ code in ClipboardMac, but refactored to use a separate loader object.
+ (WebCore::Clipboard::setDragImageElement): Added. Sets up a drag image
+ based on an element.
+ (WebCore::Clipboard::updateDragImage): Added. Common code to update
+ drag image when a new one is set or when a drag image load completes.
+ (WebCore::DragImageLoader::create): Added.
+ (WebCore::DragImageLoader::DragImageLoader): Ditto.
+ (WebCore::DragImageLoader::startLoading): Ditto.
+ (WebCore::DragImageLoader::stopLoading): Ditto.
+ (WebCore::DragImageLoader::imageChanged): Ditto.
+
+ * dom/Clipboard.h: Made setDragImage and setDragImageElement non-virtual
+ for non-legacy. Added updateDragImage and m_dragImageLoader.
+
+ * platform/Pasteboard.h: Added setDragImage function.
+
+ * platform/mac/ClipboardMac.h: Removed CachedImageClient as a base class
+ for ClipboardMac. Removed setDragImage and setDragImageElement.
+
+ * platform/mac/ClipboardMac.mm: Removed setDragImage and setDragImageElement.
+ (WebCore::ClipboardMac::~ClipboardMac): Removed code to remove self as
+ client loading the drag image. This is now in the Clipboard base class.
+
+ * platform/mac/PasteboardMac.mm:
+ (WebCore::Pasteboard::setDragImage): Added. Contains code moved here
+ from ClipboardMac.
+
2013-05-14 Ryosuke Niwa <rn...@webkit.org>
Use ElementTraversal in SelectorDataList::execute
Modified: trunk/Source/WebCore/dom/Clipboard.cpp (150099 => 150100)
--- trunk/Source/WebCore/dom/Clipboard.cpp 2013-05-15 03:17:43 UTC (rev 150099)
+++ trunk/Source/WebCore/dom/Clipboard.cpp 2013-05-15 04:27:42 UTC (rev 150100)
@@ -26,6 +26,8 @@
#include "config.h"
#include "Clipboard.h"
+#include "CachedImage.h"
+#include "CachedImageClient.h"
#include "Editor.h"
#include "FileList.h"
#include "Frame.h"
@@ -35,6 +37,23 @@
namespace WebCore {
+#if ENABLE(DRAG_SUPPORT)
+
+class DragImageLoader FINAL : private CachedImageClient {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ static PassOwnPtr<DragImageLoader> create(Clipboard*);
+ void startLoading(CachedResourceHandle<CachedImage>&);
+ void stopLoading(CachedResourceHandle<CachedImage>&);
+
+private:
+ DragImageLoader(Clipboard*);
+ virtual void imageChanged(CachedImage*, const IntRect*) OVERRIDE;
+ Clipboard* m_clipboard;
+};
+
+#endif
+
Clipboard::Clipboard(ClipboardAccessPolicy policy, ClipboardType clipboardType
#if !USE(LEGACY_STYLE_ABSTRACT_CLIPBOARD_CLASS)
, PassOwnPtr<Pasteboard> pasteboard, bool forFileDrag
@@ -54,6 +73,10 @@
Clipboard::~Clipboard()
{
+#if !USE(LEGACY_STYLE_ABSTRACT_CLIPBOARD_CLASS) && ENABLE(DRAG_SUPPORT)
+ if (m_dragImageLoader && m_dragImage)
+ m_dragImageLoader->stopLoading(m_dragImage);
+#endif
}
void Clipboard::setAccessPolicy(ClipboardAccessPolicy policy)
@@ -338,6 +361,99 @@
m_pasteboard->writeURL(url, title, frame);
}
+#if !ENABLE(DRAG_SUPPORT)
+
+void Clipboard::setDragImage(CachedImage*, const IntPoint&)
+{
+}
+
+void Clipboard::setDragImageElement(Node*, const IntPoint&)
+{
+}
+
+#else
+
+void Clipboard::setDragImage(CachedImage* image, const IntPoint& location)
+{
+ if (!canSetDragImage())
+ return;
+
+ m_dragLoc = location;
+
+ if (m_dragImageLoader && m_dragImage)
+ m_dragImageLoader->stopLoading(m_dragImage);
+ m_dragImage = image;
+ if (m_dragImage) {
+ if (!m_dragImageLoader)
+ m_dragImageLoader = DragImageLoader::create(this);
+ m_dragImageLoader->startLoading(m_dragImage);
+ }
+
+ m_dragImageElement = 0;
+
+ updateDragImage();
+}
+
+// FIXME: Should change Node to Element.
+void Clipboard::setDragImageElement(Node* element, const IntPoint& location)
+{
+ if (!canSetDragImage())
+ return;
+
+ m_dragLoc = location;
+
+ if (m_dragImageLoader && m_dragImage)
+ m_dragImageLoader->stopLoading(m_dragImage);
+ m_dragImage = 0;
+
+ m_dragImageElement = element;
+
+ updateDragImage();
+}
+
+void Clipboard::updateDragImage()
+{
+ // Don't allow setting the image if we haven't started dragging yet; we'll rely on the dragging code
+ // to install this drag image as part of getting the drag kicked off.
+ if (!dragStarted())
+ return;
+
+ IntPoint computedHotSpot;
+ DragImageRef computedImage = createDragImage(computedHotSpot);
+ if (!computedImage)
+ return;
+
+ m_pasteboard->setDragImage(computedImage, computedHotSpot);
+}
+
+PassOwnPtr<DragImageLoader> DragImageLoader::create(Clipboard* clipboard)
+{
+ return adoptPtr(new DragImageLoader(clipboard));
+}
+
+DragImageLoader::DragImageLoader(Clipboard* clipboard)
+ : m_clipboard(clipboard)
+{
+}
+
+void DragImageLoader::startLoading(CachedResourceHandle<WebCore::CachedImage>& image)
+{
+ // FIXME: Does this really trigger a load? Does it need to?
+ image->addClient(this);
+}
+
+void DragImageLoader::stopLoading(CachedResourceHandle<WebCore::CachedImage>& image)
+{
+ image->removeClient(this);
+}
+
+void DragImageLoader::imageChanged(CachedImage*, const IntRect*)
+{
+ m_clipboard->updateDragImage();
+}
+
#endif
+#endif
+
} // namespace WebCore
Modified: trunk/Source/WebCore/dom/Clipboard.h (150099 => 150100)
--- trunk/Source/WebCore/dom/Clipboard.h 2013-05-15 03:17:43 UTC (rev 150099)
+++ trunk/Source/WebCore/dom/Clipboard.h 2013-05-15 04:27:42 UTC (rev 150100)
@@ -53,6 +53,7 @@
class CachedImage;
class DataTransferItemList;
class DragData;
+ class DragImageLoader;
class FileList;
class Frame;
class Pasteboard;
@@ -89,9 +90,9 @@
IntPoint dragLocation() const { return m_dragLoc; }
CachedImage* dragImage() const { return m_dragImage.get(); }
- virtual void setDragImage(CachedImage*, const IntPoint&) = 0;
+ LEGACY_VIRTUAL void setDragImage(CachedImage*, const IntPoint&) LEGACY_PURE;
Node* dragImageElement() const { return m_dragImageElement.get(); }
- virtual void setDragImageElement(Node*, const IntPoint&) = 0;
+ LEGACY_VIRTUAL void setDragImageElement(Node*, const IntPoint&) LEGACY_PURE;
virtual DragImageRef createDragImage(IntPoint& dragLocation) const = 0;
#if ENABLE(DRAG_SUPPORT)
@@ -126,6 +127,10 @@
virtual PassRefPtr<DataTransferItemList> items() = 0;
#endif
+#if !USE(LEGACY_STYLE_ABSTRACT_CLIPBOARD_CLASS) && ENABLE(DRAG_SUPPORT)
+ void updateDragImage();
+#endif
+
protected:
#if !USE(LEGACY_STYLE_ABSTRACT_CLIPBOARD_CLASS)
Clipboard(ClipboardAccessPolicy, ClipboardType, PassOwnPtr<Pasteboard>, bool forFileDrag);
@@ -155,7 +160,10 @@
private:
OwnPtr<Pasteboard> m_pasteboard;
bool m_forFileDrag;
+#if ENABLE(DRAG_SUPPORT)
+ OwnPtr<DragImageLoader> m_dragImageLoader;
#endif
+#endif
};
DragOperation convertDropZoneOperationToDragOperation(const String& dragOperation);
Modified: trunk/Source/WebCore/platform/Pasteboard.h (150099 => 150100)
--- trunk/Source/WebCore/platform/Pasteboard.h 2013-05-15 03:17:43 UTC (rev 150099)
+++ trunk/Source/WebCore/platform/Pasteboard.h 2013-05-15 04:27:42 UTC (rev 150100)
@@ -26,18 +26,14 @@
#ifndef Pasteboard_h
#define Pasteboard_h
-#include <wtf/Forward.h>
+#include "DragImage.h"
#include <wtf/ListHashSet.h>
#include <wtf/Noncopyable.h>
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
-#if PLATFORM(MAC)
-#include <wtf/RetainPtr.h>
-#endif
-
#if PLATFORM(GTK)
-// FIXME: Why does this include need to be in the header?
+// FIXME: Why does this include need to be in this header?
#include <PasteboardHelper.h>
#endif
@@ -120,6 +116,10 @@
bool canSmartReplace();
+#if ENABLE(DRAG_SUPPORT)
+ void setDragImage(DragImageRef, const IntPoint& hotSpot);
+#endif
+
// FIXME: Having these functions here is a layering violation.
// These functions need to move to the editing directory even if they have platform-specific aspects.
PassRefPtr<DocumentFragment> documentFragment(Frame*, PassRefPtr<Range>, bool allowPlainText, bool& chosePlainText);
Modified: trunk/Source/WebCore/platform/mac/ClipboardMac.h (150099 => 150100)
--- trunk/Source/WebCore/platform/mac/ClipboardMac.h 2013-05-15 03:17:43 UTC (rev 150099)
+++ trunk/Source/WebCore/platform/mac/ClipboardMac.h 2013-05-15 04:27:42 UTC (rev 150100)
@@ -37,7 +37,7 @@
class Frame;
class FileList;
-class ClipboardMac : public Clipboard, public CachedImageClient {
+class ClipboardMac : public Clipboard {
WTF_MAKE_FAST_ALLOCATED;
public:
enum ClipboardContents {
@@ -53,9 +53,6 @@
virtual ~ClipboardMac();
- void setDragImage(CachedImage*, const IntPoint&);
- void setDragImageElement(Node *, const IntPoint&);
-
virtual DragImageRef createDragImage(IntPoint& dragLoc) const;
#if ENABLE(DRAG_SUPPORT)
virtual void declareAndWriteDragImage(Element*, const KURL&, const String& title, Frame*);
@@ -68,8 +65,6 @@
private:
ClipboardMac(ClipboardType, const String& pasteboardName, ClipboardAccessPolicy, ClipboardContents, Frame*);
- void setDragImage(CachedImage*, Node*, const IntPoint&);
-
String m_pasteboardName;
int m_changeCount;
Frame* m_frame; // used on the source side to generate dragging images
Modified: trunk/Source/WebCore/platform/mac/ClipboardMac.mm (150099 => 150100)
--- trunk/Source/WebCore/platform/mac/ClipboardMac.mm 2013-05-15 03:17:43 UTC (rev 150099)
+++ trunk/Source/WebCore/platform/mac/ClipboardMac.mm 2013-05-15 04:27:42 UTC (rev 150100)
@@ -65,56 +65,8 @@
ClipboardMac::~ClipboardMac()
{
- if (m_dragImage)
- m_dragImage->removeClient(this);
}
-// The rest of these getters don't really have any impact on security, so for now make no checks
-
-void ClipboardMac::setDragImage(CachedImage* img, const IntPoint &loc)
-{
- setDragImage(img, 0, loc);
-}
-
-void ClipboardMac::setDragImageElement(Node *node, const IntPoint &loc)
-{
- setDragImage(0, node, loc);
-}
-
-void ClipboardMac::setDragImage(CachedImage* image, Node *node, const IntPoint &loc)
-{
- if (canSetDragImage()) {
- if (m_dragImage)
- m_dragImage->removeClient(this);
- m_dragImage = image;
- if (m_dragImage)
- m_dragImage->addClient(this);
-
- m_dragLoc = loc;
- m_dragImageElement = node;
-
- if (dragStarted() && m_changeCount == platformStrategies()->pasteboardStrategy()->changeCount(m_pasteboardName)) {
- NSPoint cocoaLoc;
- NSImage* cocoaImage = dragNSImage(cocoaLoc);
- if (cocoaImage) {
- // Dashboard wants to be able to set the drag image during dragging, but Cocoa does not allow this.
- // Instead we must drop down to the CoreGraphics API.
- wkSetDragImage(cocoaImage, cocoaLoc);
-
- // Hack: We must post an event to wake up the NSDragManager, which is sitting in a nextEvent call
- // up the stack from us because the CoreFoundation drag manager does not use the run loop by itself.
- // This is the most innocuous event to use, per Kristen Forster.
- NSEvent* ev = [NSEvent mouseEventWithType:NSMouseMoved location:NSZeroPoint
- modifierFlags:0 timestamp:0 windowNumber:0 context:nil eventNumber:0 clickCount:0 pressure:0];
- [NSApp postEvent:ev atStart:YES];
- }
- }
- // Else either 1) we haven't started dragging yet, so we rely on the part to install this drag image
- // as part of getting the drag kicked off, or 2) Someone kept a ref to the clipboard and is trying to
- // set the image way too late.
- }
-}
-
#if ENABLE(DRAG_SUPPORT)
void ClipboardMac::declareAndWriteDragImage(Element* element, const KURL& url, const String& title, Frame* frame)
{
Modified: trunk/Source/WebCore/platform/mac/PasteboardMac.mm (150099 => 150100)
--- trunk/Source/WebCore/platform/mac/PasteboardMac.mm 2013-05-15 03:17:43 UTC (rev 150099)
+++ trunk/Source/WebCore/platform/mac/PasteboardMac.mm 2013-05-15 04:27:42 UTC (rev 150100)
@@ -813,4 +813,22 @@
return paths;
}
+void Pasteboard::setDragImage(DragImageRef image, const IntPoint& location)
+{
+ // Don't allow setting the drag image if someone kept a pasteboard and is trying to set the image too late.
+ if (m_changeCount != platformStrategies()->pasteboardStrategy()->changeCount(m_pasteboardName))
+ return;
+
+ // Dashboard wants to be able to set the drag image during dragging, but Cocoa does not allow this.
+ // Instead we must drop down to the CoreGraphics API.
+ wkSetDragImage(image.get(), location);
+
+ // Hack: We must post an event to wake up the NSDragManager, which is sitting in a nextEvent call
+ // up the stack from us because the CoreFoundation drag manager does not use the run loop by itself.
+ // This is the most innocuous event to use, per Kristen Forster.
+ NSEvent* event = [NSEvent mouseEventWithType:NSMouseMoved location:NSZeroPoint
+ modifierFlags:0 timestamp:0 windowNumber:0 context:nil eventNumber:0 clickCount:0 pressure:0];
+ [NSApp postEvent:event atStart:YES];
}
+
+}