Title: [261554] trunk/Source
Revision
261554
Author
[email protected]
Date
2020-05-12 08:20:30 -0700 (Tue, 12 May 2020)

Log Message

[GTK] Rework clipboard handling in preparation for GTK4
https://bugs.webkit.org/show_bug.cgi?id=211511

Reviewed by Adrian Perez de Castro.

Source/WebCore:

Remove PlatformPasteboard implementation that has been replaced by Clipboard class in the WebKit
layer. When Pasteboard class is created for copy and paste operations, it no longer has a SelectionData member,
it just uses the new methods in the pasteboard strategy to communicate with the clipboard. WebContentReader has
now an implementation for GTK and it's used when reading from the clipboard, the same way it's done in other ports.

* SourcesGTK.txt:
* editing/WebContentReader.h:
* editing/gtk/EditorGtk.cpp:
(WebCore::Editor::pasteWithPasteboard): Use webContentFromPasteboard().
(WebCore::Editor::webContentFromPasteboard): Use WebContentReader.
* editing/gtk/WebContentReaderGtk.cpp: Added.
(WebCore::WebContentReader::readFilePath):
(WebCore::WebContentReader::readFilePaths):
(WebCore::WebContentReader::readHTML):
(WebCore::WebContentReader::readPlainText):
(WebCore::WebContentReader::readImage):
(WebCore::WebContentReader::readURL):
(WebCore::WebContentMarkupReader::readHTML):
* platform/Pasteboard.h:
(WebCore::PasteboardWebContentReader::readDataBuffer):
* platform/PasteboardStrategy.h:
* platform/gtk/PasteboardGtk.cpp:
(WebCore::Pasteboard::Pasteboard):
(WebCore::Pasteboard::selectionData const):
(WebCore::Pasteboard::writeString):
(WebCore::Pasteboard::writePlainText):
(WebCore::Pasteboard::write):
(WebCore::Pasteboard::clear):
(WebCore::Pasteboard::canSmartReplace):
(WebCore::Pasteboard::read):
(WebCore::Pasteboard::hasData):
(WebCore::Pasteboard::typesForLegacyUnsafeBindings):
(WebCore::Pasteboard::readString):
(WebCore::Pasteboard::fileContentState):
* platform/gtk/PasteboardHelper.cpp:
* platform/gtk/PasteboardHelper.h:
* platform/gtk/PlatformPasteboardGtk.cpp: Removed.
* platform/gtk/SelectionData.cpp:
(WebCore::SelectionData::setURL): Do not override the text and markup if it has already been set.

Source/WebKit:

Use async APIs to avoid blocking the UI process during the communication with the clipboard. In GTK4 only async
APIs are available. Add Clipboard class to handle the communication with the clipboard with the GTK
implementation in ClipboardGtk3 and ClipboardGtk4 files.

* Shared/gtk/WebSelectionData.cpp:
(WebKit::WebSelectionData::WebSelectionData): Add constructor receivnig an rvalue reference.
* Shared/gtk/WebSelectionData.h:
* SourcesGTK.txt:
* UIProcess/WebPasteboardProxy.h:
* UIProcess/WebPasteboardProxy.messages.in:
* UIProcess/gtk/Clipboard.cpp: Added.
(WebKit::clipboard):
(WebKit::primary):
(WebKit::Clipboard::get):
* UIProcess/gtk/Clipboard.h: Added.
* UIProcess/gtk/ClipboardGtk3.cpp: Added.
(WebKit::Clipboard::Clipboard):
(WebKit::isPrimaryClipboard):
(WebKit::Clipboard::type const):
(WebKit::FormatsAsyncData::FormatsAsyncData):
(WebKit::Clipboard::formats):
(WebKit::ReadTextAsyncData::ReadTextAsyncData):
(WebKit::Clipboard::readText):
(WebKit::ReadFilePathsAsyncData::ReadFilePathsAsyncData):
(WebKit::Clipboard::readFilePaths):
(WebKit::ReadBufferAsyncData::ReadBufferAsyncData):
(WebKit::Clipboard::readBuffer):
(WebKit::Clipboard::write):
(WebKit::Clipboard::clear):
* UIProcess/gtk/ClipboardGtk4.cpp: Added.
(WebKit::Clipboard::Clipboard):
(WebKit::Clipboard::type const):
(WebKit::Clipboard::formats):
(WebKit::Clipboard::readText):
(WebKit::Clipboard::readFilePaths):
(WebKit::Clipboard::readBuffer):
(WebKit::Clipboard::write):
(WebKit::Clipboard::clear):
* UIProcess/gtk/WebPasteboardProxyGtk.cpp:
(WebKit::WebPasteboardProxy::getTypes):
(WebKit::WebPasteboardProxy::readText):
(WebKit::WebPasteboardProxy::readFilePaths):
(WebKit::WebPasteboardProxy::readBuffer):
(WebKit::WebPasteboardProxy::writeToClipboard):
(WebKit::WebPasteboardProxy::clearClipboard):
* WebProcess/WebCoreSupport/WebPlatformStrategies.cpp:
(WebKit::WebPlatformStrategies::types):
(WebKit::WebPlatformStrategies::readTextFromClipboard):
(WebKit::WebPlatformStrategies::readFilePathsFromClipboard):
(WebKit::WebPlatformStrategies::readBufferFromClipboard):
(WebKit::WebPlatformStrategies::writeToClipboard):
(WebKit::WebPlatformStrategies::clearClipboard):
* WebProcess/WebCoreSupport/WebPlatformStrategies.h:

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (261553 => 261554)


--- trunk/Source/WebCore/ChangeLog	2020-05-12 11:45:25 UTC (rev 261553)
+++ trunk/Source/WebCore/ChangeLog	2020-05-12 15:20:30 UTC (rev 261554)
@@ -1,3 +1,50 @@
+2020-05-12  Carlos Garcia Campos  <[email protected]>
+
+        [GTK] Rework clipboard handling in preparation for GTK4
+        https://bugs.webkit.org/show_bug.cgi?id=211511
+
+        Reviewed by Adrian Perez de Castro.
+
+        Remove PlatformPasteboard implementation that has been replaced by Clipboard class in the WebKit
+        layer. When Pasteboard class is created for copy and paste operations, it no longer has a SelectionData member,
+        it just uses the new methods in the pasteboard strategy to communicate with the clipboard. WebContentReader has
+        now an implementation for GTK and it's used when reading from the clipboard, the same way it's done in other ports.
+
+        * SourcesGTK.txt:
+        * editing/WebContentReader.h:
+        * editing/gtk/EditorGtk.cpp:
+        (WebCore::Editor::pasteWithPasteboard): Use webContentFromPasteboard().
+        (WebCore::Editor::webContentFromPasteboard): Use WebContentReader.
+        * editing/gtk/WebContentReaderGtk.cpp: Added.
+        (WebCore::WebContentReader::readFilePath):
+        (WebCore::WebContentReader::readFilePaths):
+        (WebCore::WebContentReader::readHTML):
+        (WebCore::WebContentReader::readPlainText):
+        (WebCore::WebContentReader::readImage):
+        (WebCore::WebContentReader::readURL):
+        (WebCore::WebContentMarkupReader::readHTML):
+        * platform/Pasteboard.h:
+        (WebCore::PasteboardWebContentReader::readDataBuffer):
+        * platform/PasteboardStrategy.h:
+        * platform/gtk/PasteboardGtk.cpp:
+        (WebCore::Pasteboard::Pasteboard):
+        (WebCore::Pasteboard::selectionData const):
+        (WebCore::Pasteboard::writeString):
+        (WebCore::Pasteboard::writePlainText):
+        (WebCore::Pasteboard::write):
+        (WebCore::Pasteboard::clear):
+        (WebCore::Pasteboard::canSmartReplace):
+        (WebCore::Pasteboard::read):
+        (WebCore::Pasteboard::hasData):
+        (WebCore::Pasteboard::typesForLegacyUnsafeBindings):
+        (WebCore::Pasteboard::readString):
+        (WebCore::Pasteboard::fileContentState):
+        * platform/gtk/PasteboardHelper.cpp:
+        * platform/gtk/PasteboardHelper.h:
+        * platform/gtk/PlatformPasteboardGtk.cpp: Removed.
+        * platform/gtk/SelectionData.cpp:
+        (WebCore::SelectionData::setURL): Do not override the text and markup if it has already been set.
+
 2020-05-12  Youenn Fablet  <[email protected]>
 
         Introduce a RealtimeMediaSource video sample observer

Modified: trunk/Source/WebCore/SourcesGTK.txt (261553 => 261554)


--- trunk/Source/WebCore/SourcesGTK.txt	2020-05-12 11:45:25 UTC (rev 261553)
+++ trunk/Source/WebCore/SourcesGTK.txt	2020-05-12 15:20:30 UTC (rev 261554)
@@ -42,6 +42,7 @@
 editing/atk/FrameSelectionAtk.cpp
 
 editing/gtk/EditorGtk.cpp
+editing/gtk/WebContentReaderGtk.cpp
 
 loader/soup/ResourceLoaderSoup.cpp
 
@@ -108,7 +109,6 @@
 platform/gtk/PasteboardGtk.cpp
 platform/gtk/PasteboardHelper.cpp
 platform/gtk/PlatformKeyboardEventGtk.cpp
-platform/gtk/PlatformPasteboardGtk.cpp
 platform/gtk/PlatformScreenGtk.cpp
 platform/gtk/PlatformWheelEventGtk.cpp
 platform/gtk/RenderThemeGadget.cpp

Modified: trunk/Source/WebCore/editing/WebContentReader.cpp (261553 => 261554)


--- trunk/Source/WebCore/editing/WebContentReader.cpp	2020-05-12 11:45:25 UTC (rev 261553)
+++ trunk/Source/WebCore/editing/WebContentReader.cpp	2020-05-12 15:20:30 UTC (rev 261554)
@@ -50,5 +50,18 @@
     return contentOrigin.isNull() ? MSOListQuirks::CheckIfNeeded : MSOListQuirks::Disabled;
 }
 
+#if PLATFORM(COCOA) || PLATFORM(GTK)
+bool WebContentReader::readFilePaths(const Vector<String>& paths)
+{
+    if (paths.isEmpty() || !frame.document())
+        return false;
+
+    for (auto& path : paths)
+        readFilePath(path);
+
+    return true;
 }
+#endif
 
+}
+

Modified: trunk/Source/WebCore/editing/WebContentReader.h (261553 => 261554)


--- trunk/Source/WebCore/editing/WebContentReader.h	2020-05-12 11:45:25 UTC (rev 261553)
+++ trunk/Source/WebCore/editing/WebContentReader.h	2020-05-12 15:20:30 UTC (rev 261554)
@@ -68,18 +68,21 @@
     void addFragment(Ref<DocumentFragment>&&);
 
 private:
-#if PLATFORM(COCOA)
-    bool readWebArchive(SharedBuffer&) override;
+#if PLATFORM(COCOA) || PLATFORM(GTK)
     bool readFilePath(const String&, PresentationSize preferredPresentationSize = { }, const String& contentType = { }) override;
     bool readFilePaths(const Vector<String>&) override;
     bool readHTML(const String&) override;
-    bool readRTFD(SharedBuffer&) override;
-    bool readRTF(SharedBuffer&) override;
     bool readImage(Ref<SharedBuffer>&&, const String& type, PresentationSize preferredPresentationSize = { }) override;
     bool readURL(const URL&, const String& title) override;
-    bool readDataBuffer(SharedBuffer&, const String& type, const String& name, PresentationSize preferredPresentationSize = { }) override;
     bool readPlainText(const String&) override;
 #endif
+
+#if PLATFORM(COCOA)
+    bool readWebArchive(SharedBuffer&) override;
+    bool readRTFD(SharedBuffer&) override;
+    bool readRTF(SharedBuffer&) override;
+    bool readDataBuffer(SharedBuffer&, const String& type, const String& name, PresentationSize preferredPresentationSize = { }) override;
+#endif
 };
 
 class WebContentMarkupReader final : public FrameWebContentReader {
@@ -92,18 +95,21 @@
     }
 
 private:
-#if PLATFORM(COCOA)
-    bool readWebArchive(SharedBuffer&) override;
+#if PLATFORM(COCOA) || PLATFORM(GTK)
     bool readFilePath(const String&, PresentationSize = { }, const String& = { }) override { return false; }
     bool readFilePaths(const Vector<String>&) override { return false; }
     bool readHTML(const String&) override;
-    bool readRTFD(SharedBuffer&) override;
-    bool readRTF(SharedBuffer&) override;
     bool readImage(Ref<SharedBuffer>&&, const String&, PresentationSize = { }) override { return false; }
     bool readURL(const URL&, const String&) override { return false; }
-    bool readDataBuffer(SharedBuffer&, const String&, const String&, PresentationSize = { }) override { return false; }
     bool readPlainText(const String&) override { return false; }
 #endif
+
+#if PLATFORM(COCOA)
+    bool readWebArchive(SharedBuffer&) override;
+    bool readRTFD(SharedBuffer&) override;
+    bool readRTF(SharedBuffer&) override;
+    bool readDataBuffer(SharedBuffer&, const String&, const String&, PresentationSize = { }) override { return false; }
+#endif
 };
 
 #if PLATFORM(COCOA) && defined(__OBJC__)

Modified: trunk/Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm (261553 => 261554)


--- trunk/Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm	2020-05-12 11:45:25 UTC (rev 261553)
+++ trunk/Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm	2020-05-12 15:20:30 UTC (rev 261554)
@@ -798,17 +798,6 @@
     return true;
 }
 
-bool WebContentReader::readFilePaths(const Vector<String>& paths)
-{
-    if (paths.isEmpty() || !frame.document())
-        return false;
-
-    for (auto& path : paths)
-        readFilePath(path);
-
-    return true;
-}
-
 bool WebContentReader::readURL(const URL& url, const String& title)
 {
     if (url.isEmpty())

Modified: trunk/Source/WebCore/editing/gtk/EditorGtk.cpp (261553 => 261554)


--- trunk/Source/WebCore/editing/gtk/EditorGtk.cpp	2020-05-12 11:45:25 UTC (rev 261553)
+++ trunk/Source/WebCore/editing/gtk/EditorGtk.cpp	2020-05-12 15:20:30 UTC (rev 261554)
@@ -27,9 +27,7 @@
 #include "config.h"
 #include "Editor.h"
 
-#include "Blob.h"
 #include "CachedImage.h"
-#include "DOMURL.h"
 #include "DocumentFragment.h"
 #include "Frame.h"
 #include "HTMLEmbedElement.h"
@@ -44,49 +42,12 @@
 #include "SVGImageElement.h"
 #include "SelectionData.h"
 #include "Settings.h"
+#include "WebContentReader.h"
 #include "XLinkNames.h"
 #include "markup.h"
-#include <cairo.h>
 
 namespace WebCore {
 
-static RefPtr<DocumentFragment> createFragmentFromPasteboardData(Pasteboard& pasteboard, Frame& frame, const SimpleRange& range, bool allowPlainText, bool& chosePlainText)
-{
-    chosePlainText = false;
-
-    if (!pasteboard.hasData())
-        return nullptr;
-
-    const auto& selection = pasteboard.selectionData();
-    if (selection.hasImage()) {
-        Vector<uint8_t> buffer;
-        auto status = cairo_surface_write_to_png_stream(selection.image()->nativeImage().get(), [](void* output, const unsigned char* data, unsigned size) {
-            if (!reinterpret_cast<Vector<uint8_t>*>(output)->tryAppend(data, size))
-                return CAIRO_STATUS_WRITE_ERROR;
-            return CAIRO_STATUS_SUCCESS;
-        }, &buffer);
-        if (status == CAIRO_STATUS_SUCCESS) {
-            auto blob = Blob::create(WTFMove(buffer), "image/png");
-            if (!frame.document())
-                return nullptr;
-            return createFragmentForImageAndURL(*frame.document(), DOMURL::createObjectURL(*frame.document(), blob), { });
-        }
-    }
-
-    if (selection.hasMarkup() && frame.document())
-        return createFragmentFromMarkup(*frame.document(), selection.markup(), emptyString(), DisallowScriptingAndPluginContent);
-
-    if (!allowPlainText)
-        return nullptr;
-
-    if (selection.hasText()) {
-        chosePlainText = true;
-        return createFragmentFromText(createLiveRange(range), selection.text());
-    }
-
-    return nullptr;
-}
-
 void Editor::pasteWithPasteboard(Pasteboard* pasteboard, OptionSet<PasteOption> options)
 {
     RefPtr<Range> range = selectedRange();
@@ -94,7 +55,7 @@
         return;
 
     bool chosePlainText;
-    RefPtr<DocumentFragment> fragment = createFragmentFromPasteboardData(*pasteboard, *m_document.frame(), *range, options.contains(PasteOption::AllowPlainText), chosePlainText);
+    RefPtr<DocumentFragment> fragment = webContentFromPasteboard(*pasteboard, *range, options.contains(PasteOption::AllowPlainText), chosePlainText);
 
     if (fragment && options.contains(PasteOption::AsQuotation))
         quoteFragmentForPasting(*fragment);
@@ -154,7 +115,10 @@
 
 RefPtr<DocumentFragment> Editor::webContentFromPasteboard(Pasteboard& pasteboard, const SimpleRange& context, bool allowPlainText, bool& chosePlainText)
 {
-    return createFragmentFromPasteboardData(pasteboard, *m_document.frame(), context, allowPlainText, chosePlainText);
+    WebContentReader reader(*m_document.frame(), context, allowPlainText);
+    pasteboard.read(reader);
+    chosePlainText = reader.madeFragmentFromPlainText;
+    return WTFMove(reader.fragment);
 }
 
 } // namespace WebCore

Added: trunk/Source/WebCore/editing/gtk/WebContentReaderGtk.cpp (0 => 261554)


--- trunk/Source/WebCore/editing/gtk/WebContentReaderGtk.cpp	                        (rev 0)
+++ trunk/Source/WebCore/editing/gtk/WebContentReaderGtk.cpp	2020-05-12 15:20:30 UTC (rev 261554)
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2020 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebContentReader.h"
+
+#include "BlobURL.h"
+#include "DOMURL.h"
+#include "Document.h"
+#include "DocumentFragment.h"
+#include "Editor.h"
+#include "Frame.h"
+#include "Page.h"
+#include "Settings.h"
+#include "markup.h"
+#include <wtf/URL.h>
+
+namespace WebCore {
+
+bool WebContentReader::readFilePath(const String& path, PresentationSize, const String&)
+{
+    if (path.isEmpty() || !frame.document())
+        return false;
+
+    auto markup = urlToMarkup(URL({ }, path), path);
+    addFragment(createFragmentFromMarkup(*frame.document(), markup, "file://", DisallowScriptingAndPluginContent));
+
+    return true;
+}
+
+bool WebContentReader::readHTML(const String& string)
+{
+    if (frame.settings().preferMIMETypeForImages() || !frame.document())
+        return false;
+
+    addFragment(createFragmentFromMarkup(*frame.document(), string, emptyString(), DisallowScriptingAndPluginContent));
+    return true;
+}
+
+bool WebContentReader::readPlainText(const String& text)
+{
+    if (!allowPlainText)
+        return false;
+
+    addFragment(createFragmentFromText(createLiveRange(context), text));
+
+    madeFragmentFromPlainText = true;
+    return true;
+}
+
+bool WebContentReader::readImage(Ref<SharedBuffer>&& buffer, const String& type, PresentationSize preferredPresentationSize)
+{
+    ASSERT(frame.document());
+    auto& document = *frame.document();
+    addFragment(createFragmentForImageAndURL(document, DOMURL::createObjectURL(document, Blob::create(buffer.get(), type)), preferredPresentationSize));
+
+    return fragment;
+}
+
+bool WebContentReader::readURL(const URL&, const String&)
+{
+    return false;
+}
+
+bool WebContentMarkupReader::readHTML(const String&)
+{
+    return false;
+}
+
+} // namespace WebCore

Modified: trunk/Source/WebCore/platform/Pasteboard.h (261553 => 261554)


--- trunk/Source/WebCore/platform/Pasteboard.h	2020-05-12 11:45:25 UTC (rev 261553)
+++ trunk/Source/WebCore/platform/Pasteboard.h	2020-05-12 15:20:30 UTC (rev 261554)
@@ -136,18 +136,21 @@
 
     virtual ~PasteboardWebContentReader() = default;
 
-#if PLATFORM(COCOA)
-    virtual bool readWebArchive(SharedBuffer&) = 0;
+#if PLATFORM(COCOA) || PLATFORM(GTK)
     virtual bool readFilePath(const String&, PresentationSize preferredPresentationSize = { }, const String& contentType = { }) = 0;
     virtual bool readFilePaths(const Vector<String>&) = 0;
     virtual bool readHTML(const String&) = 0;
-    virtual bool readRTFD(SharedBuffer&) = 0;
-    virtual bool readRTF(SharedBuffer&) = 0;
     virtual bool readImage(Ref<SharedBuffer>&&, const String& type, PresentationSize preferredPresentationSize = { }) = 0;
     virtual bool readURL(const URL&, const String& title) = 0;
-    virtual bool readDataBuffer(SharedBuffer&, const String& type, const String& name, PresentationSize preferredPresentationSize = { }) = 0;
     virtual bool readPlainText(const String&) = 0;
 #endif
+
+#if PLATFORM(COCOA)
+    virtual bool readWebArchive(SharedBuffer&) = 0;
+    virtual bool readRTFD(SharedBuffer&) = 0;
+    virtual bool readRTF(SharedBuffer&) = 0;
+    virtual bool readDataBuffer(SharedBuffer&, const String& type, const String& name, PresentationSize preferredPresentationSize = { }) = 0;
+#endif
 };
 
 struct PasteboardPlainText {
@@ -313,9 +316,7 @@
 #endif
 
 #if PLATFORM(GTK)
-    void writeToClipboard();
-    void readFromClipboard();
-    Ref<SelectionData> m_selectionData;
+    RefPtr<SelectionData> m_selectionData;
     String m_name;
 #endif
 

Modified: trunk/Source/WebCore/platform/PasteboardStrategy.h (261553 => 261554)


--- trunk/Source/WebCore/platform/PasteboardStrategy.h	2020-05-12 11:45:25 UTC (rev 261553)
+++ trunk/Source/WebCore/platform/PasteboardStrategy.h	2020-05-12 15:20:30 UTC (rev 261554)
@@ -81,8 +81,13 @@
     virtual bool containsStringSafeForDOMToReadForType(const String&, const String& pasteboardName) = 0;
 
 #if PLATFORM(GTK)
+    virtual Vector<String> types(const String& pasteboardName) = 0;
+    virtual String readTextFromClipboard(const String& pasteboardName) = 0;
+    virtual Vector<String> readFilePathsFromClipboard(const String& pasteboardName) = 0;
+    virtual RefPtr<SharedBuffer> readBufferFromClipboard(const String& pasteboardName, const String& pasteboardType);
+    virtual void writeToClipboard(const String& pasteboardName, SelectionData&&) = 0;
     virtual void writeToClipboard(const String& pasteboardName, const SelectionData&) = 0;
-    virtual Ref<SelectionData> readFromClipboard(const String& pasteboardName) = 0;
+    virtual void clearClipboard(const String& pasteboardName) = 0;
 #endif // PLATFORM(GTK)
 
 #if USE(LIBWPE)

Modified: trunk/Source/WebCore/platform/gtk/PasteboardGtk.cpp (261553 => 261554)


--- trunk/Source/WebCore/platform/gtk/PasteboardGtk.cpp	2020-05-12 11:45:25 UTC (rev 261553)
+++ trunk/Source/WebCore/platform/gtk/PasteboardGtk.cpp	2020-05-12 15:20:30 UTC (rev 261554)
@@ -23,10 +23,12 @@
 #include "Color.h"
 #include "DragData.h"
 #include "Image.h"
+#include "MIMETypeRegistry.h"
 #include "NotImplemented.h"
 #include "PasteboardStrategy.h"
 #include "PlatformStrategies.h"
 #include "SelectionData.h"
+#include "SharedBuffer.h"
 #include <wtf/NeverDestroyed.h>
 #include <wtf/Optional.h>
 #include <wtf/URL.h>
@@ -66,26 +68,22 @@
 #endif
 
 Pasteboard::Pasteboard(SelectionData& selectionData)
-    : m_selectionData(selectionData)
+    : m_selectionData(&selectionData)
 {
 }
 
 Pasteboard::Pasteboard(const String& name)
-    : m_selectionData(SelectionData::create())
-    , m_name(name)
+    : m_name(name)
 {
 }
 
-Pasteboard::Pasteboard()
-    : m_selectionData(SelectionData::create())
-{
-}
-
+Pasteboard::Pasteboard() = default;
 Pasteboard::~Pasteboard() = default;
 
 const SelectionData& Pasteboard::selectionData() const
 {
-    return m_selectionData.get();
+    ASSERT(m_selectionData);
+    return *m_selectionData.get();
 }
 
 static ClipboardDataType selectionDataTypeFromHTMLClipboardType(const String& type)
@@ -103,23 +101,9 @@
     return ClipboardDataTypeUnknown;
 }
 
-void Pasteboard::writeToClipboard()
-{
-    if (m_name.isNull())
-        return;
-
-    platformStrategies()->pasteboardStrategy()->writeToClipboard(m_name, m_selectionData);
-}
-
-void Pasteboard::readFromClipboard()
-{
-    if (m_name.isNull())
-        return;
-    m_selectionData = platformStrategies()->pasteboardStrategy()->readFromClipboard(m_name);
-}
-
 void Pasteboard::writeString(const String& type, const String& data)
 {
+    ASSERT(m_selectionData);
     switch (selectionDataTypeFromHTMLClipboardType(type)) {
     case ClipboardDataTypeURIList:
     case ClipboardDataTypeURL:
@@ -137,26 +121,33 @@
     case ClipboardDataTypeImage:
         break;
     }
-    writeToClipboard();
 }
 
 void Pasteboard::writePlainText(const String& text, SmartReplaceOption smartReplaceOption)
 {
-    m_selectionData->clearAll();
-    m_selectionData->setText(text);
-    m_selectionData->setCanSmartReplace(smartReplaceOption == CanSmartReplace);
-
-    writeToClipboard();
+    if (m_selectionData) {
+        m_selectionData->clearAll();
+        m_selectionData->setText(text);
+        m_selectionData->setCanSmartReplace(smartReplaceOption == CanSmartReplace);
+    } else {
+        SelectionData data;
+        data.setText(text);
+        data.setCanSmartReplace(smartReplaceOption == CanSmartReplace);
+        platformStrategies()->pasteboardStrategy()->writeToClipboard(m_name, WTFMove(data));
+    }
 }
 
 void Pasteboard::write(const PasteboardURL& pasteboardURL)
 {
     ASSERT(!pasteboardURL.url.isEmpty());
-
-    m_selectionData->clearAll();
-    m_selectionData->setURL(pasteboardURL.url, pasteboardURL.title);
-
-    writeToClipboard();
+    if (m_selectionData) {
+        m_selectionData->clearAll();
+        m_selectionData->setURL(pasteboardURL.url, pasteboardURL.title);
+    } else {
+        SelectionData data;
+        data.setURL(pasteboardURL.url, pasteboardURL.title);
+        platformStrategies()->pasteboardStrategy()->writeToClipboard(m_name, WTFMove(data));
+    }
 }
 
 void Pasteboard::writeTrustworthyWebURLsPboardType(const PasteboardURL&)
@@ -166,38 +157,57 @@
 
 void Pasteboard::write(const PasteboardImage& pasteboardImage)
 {
-    m_selectionData->clearAll();
-    if (!pasteboardImage.url.url.isEmpty()) {
-        m_selectionData->setURL(pasteboardImage.url.url, pasteboardImage.url.title);
-        m_selectionData->setMarkup(pasteboardImage.url.markup);
+    if (m_selectionData) {
+        m_selectionData->clearAll();
+        if (!pasteboardImage.url.url.isEmpty()) {
+            m_selectionData->setURL(pasteboardImage.url.url, pasteboardImage.url.title);
+            m_selectionData->setMarkup(pasteboardImage.url.markup);
+        }
+        m_selectionData->setImage(pasteboardImage.image.get());
+    } else {
+        SelectionData data;
+        if (!pasteboardImage.url.url.isEmpty()) {
+            data.setURL(pasteboardImage.url.url, pasteboardImage.url.title);
+            data.setMarkup(pasteboardImage.url.markup);
+        }
+        data.setImage(pasteboardImage.image.get());
+        platformStrategies()->pasteboardStrategy()->writeToClipboard(m_name, WTFMove(data));
     }
-    m_selectionData->setImage(pasteboardImage.image.get());
-
-    writeToClipboard();
 }
 
 void Pasteboard::write(const PasteboardWebContent& pasteboardContent)
 {
-    m_selectionData->clearAll();
-    m_selectionData->setText(pasteboardContent.text);
-    m_selectionData->setMarkup(pasteboardContent.markup);
-    m_selectionData->setCanSmartReplace(pasteboardContent.canSmartCopyOrDelete);
-
-    writeToClipboard();
+    if (m_selectionData) {
+        m_selectionData->clearAll();
+        m_selectionData->setText(pasteboardContent.text);
+        m_selectionData->setMarkup(pasteboardContent.markup);
+        m_selectionData->setCanSmartReplace(pasteboardContent.canSmartCopyOrDelete);
+    } else {
+        SelectionData data;
+        data.setText(pasteboardContent.text);
+        data.setMarkup(pasteboardContent.markup);
+        data.setCanSmartReplace(pasteboardContent.canSmartCopyOrDelete);
+        platformStrategies()->pasteboardStrategy()->writeToClipboard(m_name, WTFMove(data));
+    }
 }
 
 void Pasteboard::clear()
 {
+    if (!m_selectionData) {
+        platformStrategies()->pasteboardStrategy()->clearClipboard(m_name);
+        return;
+    }
+
     // We do not clear filenames. According to the spec: "The clearData() method
     // does not affect whether any files were included in the drag, so the types
     // attribute's list might still not be empty after calling clearData() (it would
     // still contain the "Files" string if any files were included in the drag)."
     m_selectionData->clearAllExceptFilenames();
-    writeToClipboard();
 }
 
 void Pasteboard::clear(const String& type)
 {
+    ASSERT(m_selectionData);
     switch (selectionDataTypeFromHTMLClipboardType(type)) {
     case ClipboardDataTypeURIList:
     case ClipboardDataTypeURL:
@@ -216,14 +226,13 @@
         m_selectionData->clearAll();
         break;
     }
-
-    writeToClipboard();
 }
 
 bool Pasteboard::canSmartReplace()
 {
-    readFromClipboard();
-    return m_selectionData->canSmartReplace();
+    if (m_selectionData)
+        return m_selectionData->canSmartReplace();
+    return platformStrategies()->pasteboardStrategy()->types(m_name).contains("application/vnd.webkitgtk.smartpaste"_s);
 }
 
 #if ENABLE(DRAG_SUPPORT)
@@ -234,25 +243,71 @@
 
 void Pasteboard::read(PasteboardPlainText& text, PlainTextURLReadingPolicy, Optional<size_t>)
 {
-    readFromClipboard();
-    text.text = m_selectionData->text();
+    text.text = platformStrategies()->pasteboardStrategy()->readTextFromClipboard(m_name);
 }
 
-void Pasteboard::read(PasteboardWebContentReader&, WebContentReadingPolicy, Optional<size_t>)
+void Pasteboard::read(PasteboardWebContentReader& reader, WebContentReadingPolicy policy, Optional<size_t>)
 {
+    if (m_selectionData) {
+        if (m_selectionData->hasMarkup() && reader.readHTML(m_selectionData->markup()))
+            return;
+
+        if (policy == WebContentReadingPolicy::OnlyRichTextTypes)
+            return;
+
+        if (m_selectionData->hasFilenames() && reader.readFilePaths(m_selectionData->filenames()))
+            return;
+
+        if (m_selectionData->hasText() && reader.readPlainText(m_selectionData->text()))
+            return;
+
+        return;
+    }
+
+    auto types = platformStrategies()->pasteboardStrategy()->types(m_name);
+    if (types.contains("text/html"_s)) {
+        auto buffer = platformStrategies()->pasteboardStrategy()->readBufferFromClipboard(m_name, "text/html"_s);
+        if (buffer && reader.readHTML(String::fromUTF8(buffer->data(), buffer->size())))
+            return;
+    }
+
+    if (policy == WebContentReadingPolicy::OnlyRichTextTypes)
+        return;
+
+    static const ASCIILiteral imageTypes[] = { "image/png"_s, "image/jpeg"_s, "image/gif"_s, "image/bmp"_s, "image/vnd.microsoft.icon"_s, "image/x-icon"_s };
+    for (const auto& imageType : imageTypes) {
+        if (types.contains(imageType)) {
+            auto buffer = platformStrategies()->pasteboardStrategy()->readBufferFromClipboard(m_name, imageType);
+            if (!buffer->isEmpty() && reader.readImage(buffer.releaseNonNull(), imageType))
+                return;
+        }
+    }
+
+    if (types.contains("text/uri-list"_s)) {
+        auto filePaths = platformStrategies()->pasteboardStrategy()->readFilePathsFromClipboard(m_name);
+        if (reader.readFilePaths(filePaths))
+            return;
+    }
+
+    if (types.contains("text/plain"_s) || types.contains("text/plain;charset=utf-8"_s)) {
+        auto text = platformStrategies()->pasteboardStrategy()->readTextFromClipboard(m_name);
+        if (!text.isNull() && reader.readPlainText(text))
+            return;
+    }
 }
 
 void Pasteboard::read(PasteboardFileReader& reader)
 {
-    readFromClipboard();
-    for (auto& filename : m_selectionData->filenames())
-        reader.readFilename(filename);
+    auto filePaths = platformStrategies()->pasteboardStrategy()->readFilePathsFromClipboard(m_name);
+    for (const auto& filePath : filePaths)
+        reader.readFilename(filePath);
 }
 
 bool Pasteboard::hasData()
 {
-    readFromClipboard();
-    return m_selectionData->hasText() || m_selectionData->hasMarkup() || m_selectionData->hasURIList() || m_selectionData->hasImage() || m_selectionData->hasUnknownTypeData();
+    if (m_selectionData)
+        return m_selectionData->hasText() || m_selectionData->hasMarkup() || m_selectionData->hasURIList() || m_selectionData->hasImage() || m_selectionData->hasUnknownTypeData();
+    return !platformStrategies()->pasteboardStrategy()->types(m_name).isEmpty();
 }
 
 Vector<String> Pasteboard::typesSafeForBindings(const String&)
@@ -263,7 +318,8 @@
 
 Vector<String> Pasteboard::typesForLegacyUnsafeBindings()
 {
-    readFromClipboard();
+    if (!m_selectionData)
+        return platformStrategies()->pasteboardStrategy()->types(m_name);
 
     Vector<String> types;
     if (m_selectionData->hasText()) {
@@ -294,8 +350,14 @@
 
 String Pasteboard::readString(const String& type)
 {
-    readFromClipboard();
+    if (!m_selectionData) {
+        if (type.startsWith("text/plain"))
+            return platformStrategies()->pasteboardStrategy()->readTextFromClipboard(m_name);
 
+        auto buffer = platformStrategies()->pasteboardStrategy()->readBufferFromClipboard(m_name, type);
+        return buffer ? String::fromUTF8(buffer->data(), buffer->size()) : String();
+    }
+
     switch (selectionDataTypeFromHTMLClipboardType(type)) {
     case ClipboardDataTypeURIList:
         return m_selectionData->uriList();
@@ -311,7 +373,7 @@
         break;
     }
 
-    return String();
+    return { };
 }
 
 String Pasteboard::readStringInCustomData(const String&)
@@ -322,8 +384,17 @@
 
 Pasteboard::FileContentState Pasteboard::fileContentState()
 {
-    readFromClipboard();
-    return m_selectionData->filenames().isEmpty() ? FileContentState::NoFileOrImageData : FileContentState::MayContainFilePaths;
+    if (m_selectionData)
+        return m_selectionData->filenames().isEmpty() ? FileContentState::NoFileOrImageData : FileContentState::MayContainFilePaths;
+
+    auto types = platformStrategies()->pasteboardStrategy()->types(m_name);
+    if (types.contains("text/uri-list"_s))
+        return FileContentState::MayContainFilePaths;
+
+    auto result = types.findMatching([](const String& type) {
+        return MIMETypeRegistry::isSupportedImageMIMEType(type);
+    });
+    return result == notFound ? FileContentState::NoFileOrImageData : FileContentState::MayContainFilePaths;
 }
 
 void Pasteboard::writeMarkup(const String&)

Modified: trunk/Source/WebCore/platform/gtk/PasteboardHelper.cpp (261553 => 261554)


--- trunk/Source/WebCore/platform/gtk/PasteboardHelper.cpp	2020-05-12 11:45:25 UTC (rev 261553)
+++ trunk/Source/WebCore/platform/gtk/PasteboardHelper.cpp	2020-05-12 15:20:30 UTC (rev 261554)
@@ -28,7 +28,6 @@
 #include "BitmapImage.h"
 #include "SelectionData.h"
 #include <gtk/gtk.h>
-#include <wtf/SetForScope.h>
 #include <wtf/glib/GUniquePtr.h>
 #include <wtf/text/CString.h>
 
@@ -96,41 +95,6 @@
     return String::fromUTF8(markupString.get());
 }
 
-void PasteboardHelper::getClipboardContents(GtkClipboard* clipboard, SelectionData& selection)
-{
-    if (gtk_clipboard_wait_is_text_available(clipboard)) {
-        GUniquePtr<gchar> textData(gtk_clipboard_wait_for_text(clipboard));
-        if (textData)
-            selection.setText(String::fromUTF8(textData.get()));
-    }
-
-    if (gtk_clipboard_wait_is_target_available(clipboard, markupAtom)) {
-        if (GtkSelectionData* data = "" markupAtom)) {
-            String markup(selectionDataToUTF8String(data));
-            removeMarkupPrefix(markup);
-            selection.setMarkup(markup);
-            gtk_selection_data_free(data);
-        }
-    }
-
-    if (gtk_clipboard_wait_is_target_available(clipboard, uriListAtom)) {
-        if (GtkSelectionData* data = "" uriListAtom)) {
-            selection.setURIList(selectionDataToUTF8String(data));
-            gtk_selection_data_free(data);
-        }
-    }
-
-    if (gtk_clipboard_wait_is_image_available(clipboard)) {
-        if (GRefPtr<GdkPixbuf> pixbuf = adoptGRef(gtk_clipboard_wait_for_image(clipboard))) {
-            RefPtr<cairo_surface_t> surface = adoptRef(gdk_cairo_surface_create_from_pixbuf(pixbuf.get(), 1, nullptr));
-            Ref<Image> image = BitmapImage::create(WTFMove(surface));
-            selection.setImage(image.ptr());
-        }
-    }
-
-    selection.setCanSmartReplace(gtk_clipboard_wait_is_target_available(clipboard, smartPasteAtom));
-}
-
 GRefPtr<GtkTargetList> PasteboardHelper::targetListForSelectionData(const SelectionData& selection)
 {
     GRefPtr<GtkTargetList> list = adoptGRef(gtk_target_list_new(nullptr, 0));
@@ -265,57 +229,6 @@
     return dropAtoms;
 }
 
-static SelectionData* settingClipboardSelection;
-
-struct ClipboardSetData {
-    WTF_MAKE_STRUCT_FAST_ALLOCATED;
-    ClipboardSetData(SelectionData& selection, WTF::Function<void()>&& selectionClearedCallback)
-        : selectionData(selection)
-        , selectionClearedCallback(WTFMove(selectionClearedCallback))
-    {
-    }
-
-    ~ClipboardSetData() = default;
-
-    Ref<SelectionData> selectionData;
-    WTF::Function<void()> selectionClearedCallback;
-};
-
-static void getClipboardContentsCallback(GtkClipboard*, GtkSelectionData *selectionData, guint info, gpointer userData)
-{
-    auto* data = ""
-    PasteboardHelper::singleton().fillSelectionData(data->selectionData, info, selectionData);
-}
-
-static void clearClipboardContentsCallback(GtkClipboard*, gpointer userData)
-{
-    std::unique_ptr<ClipboardSetData> data(static_cast<ClipboardSetData*>(userData));
-    if (data->selectionClearedCallback)
-        data->selectionClearedCallback();
-}
-
-void PasteboardHelper::writeClipboardContents(GtkClipboard* clipboard, const SelectionData& selection, WTF::Function<void()>&& primarySelectionCleared)
-{
-    GRefPtr<GtkTargetList> list = targetListForSelectionData(selection);
-
-    int numberOfTargets;
-    GtkTargetEntry* table = gtk_target_table_new_from_list(list.get(), &numberOfTargets);
-
-    if (numberOfTargets > 0 && table) {
-        SetForScope<SelectionData*> change(settingClipboardSelection, const_cast<SelectionData*>(&selection));
-        auto data = "" WTFMove(primarySelectionCleared));
-        if (gtk_clipboard_set_with_data(clipboard, table, numberOfTargets, getClipboardContentsCallback, clearClipboardContentsCallback, data.get())) {
-            gtk_clipboard_set_can_store(clipboard, nullptr, 0);
-            // When gtk_clipboard_set_with_data() succeeds clearClipboardContentsCallback takes the ownership of data, so we leak it here.
-            data.release();
-        }
-    } else
-        gtk_clipboard_clear(clipboard);
-
-    if (table)
-        gtk_target_table_free(table, numberOfTargets);
-}
-
 } // namespace WebCore
 
 #endif // !USE(GTK4)

Modified: trunk/Source/WebCore/platform/gtk/PasteboardHelper.h (261553 => 261554)


--- trunk/Source/WebCore/platform/gtk/PasteboardHelper.h	2020-05-12 11:45:25 UTC (rev 261553)
+++ trunk/Source/WebCore/platform/gtk/PasteboardHelper.h	2020-05-12 15:20:30 UTC (rev 261554)
@@ -40,15 +40,11 @@
 public:
     static PasteboardHelper& singleton();
 
-    enum SmartPasteInclusion { IncludeSmartPaste, DoNotIncludeSmartPaste };
-
     GtkTargetList* targetList() const;
     GRefPtr<GtkTargetList> targetListForSelectionData(const SelectionData&);
     void fillSelectionData(const SelectionData&, unsigned, GtkSelectionData*);
     void fillSelectionData(GtkSelectionData*, unsigned, SelectionData&);
     Vector<GdkAtom> dropAtomsForContext(GtkWidget*, GdkDragContext*);
-    void writeClipboardContents(GtkClipboard*, const SelectionData&, WTF::Function<void()>&& primarySelectionCleared = nullptr);
-    void getClipboardContents(GtkClipboard*, SelectionData&);
 
     enum PasteboardTargetType { TargetTypeMarkup, TargetTypeText, TargetTypeImage, TargetTypeURIList, TargetTypeNetscapeURL, TargetTypeSmartPaste, TargetTypeUnknown };
 

Deleted: trunk/Source/WebCore/platform/gtk/PlatformPasteboardGtk.cpp (261553 => 261554)


--- trunk/Source/WebCore/platform/gtk/PlatformPasteboardGtk.cpp	2020-05-12 11:45:25 UTC (rev 261553)
+++ trunk/Source/WebCore/platform/gtk/PlatformPasteboardGtk.cpp	2020-05-12 15:20:30 UTC (rev 261554)
@@ -1,74 +0,0 @@
-/*
- *  Copyright (C) 2016 Red Hat Inc.
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include "config.h"
-#include "PlatformPasteboard.h"
-
-#include "Color.h"
-#include "PasteboardHelper.h"
-#include "SelectionData.h"
-#include "SharedBuffer.h"
-#include <gtk/gtk.h>
-#include <wtf/URL.h>
-
-namespace WebCore {
-
-#if USE(GTK4)
-PlatformPasteboard::PlatformPasteboard(const String&)
-{
-}
-#else
-PlatformPasteboard::PlatformPasteboard(const String& pasteboardName)
-    : m_clipboard(gtk_clipboard_get(gdk_atom_intern(pasteboardName.utf8().data(), TRUE)))
-{
-    ASSERT(m_clipboard);
-}
-#endif
-
-void PlatformPasteboard::writeToClipboard(const SelectionData& selection, WTF::Function<void()>&& primarySelectionCleared)
-{
-#if !USE(GTK4)
-    PasteboardHelper::singleton().writeClipboardContents(m_clipboard, selection, gtk_clipboard_get(GDK_SELECTION_PRIMARY) == m_clipboard ? WTFMove(primarySelectionCleared) : nullptr);
-#endif
-}
-
-Ref<SelectionData> PlatformPasteboard::readFromClipboard()
-{
-    Ref<SelectionData> selection(SelectionData::create());
-#if !USE(GTK4)
-    PasteboardHelper::singleton().getClipboardContents(m_clipboard, selection.get());
-#endif
-    return selection;
-}
-
-Vector<String> PlatformPasteboard::typesSafeForDOMToReadAndWrite(const String&) const
-{
-    return { };
-}
-
-int64_t PlatformPasteboard::write(const PasteboardCustomData&)
-{
-    return 0;
-}
-
-int64_t PlatformPasteboard::write(const Vector<PasteboardCustomData>&)
-{
-    return 0;
-}
-
-}

Modified: trunk/Source/WebCore/platform/gtk/SelectionData.cpp (261553 => 261554)


--- trunk/Source/WebCore/platform/gtk/SelectionData.cpp	2020-05-12 11:45:25 UTC (rev 261553)
+++ trunk/Source/WebCore/platform/gtk/SelectionData.cpp	2020-05-12 15:20:30 UTC (rev 261554)
@@ -53,7 +53,7 @@
     // will get an empty string. This is in line with the HTML5 spec (see
     // "The DragEvent and DataTransfer interfaces"). Also extract all filenames
     // from the URI list.
-    bool setURL = false;
+    bool setURL = hasURL();
     for (auto& line : uriListString.split('\n')) {
         line = line.stripWhiteSpace();
         if (line.isEmpty())
@@ -79,9 +79,15 @@
 void SelectionData::setURL(const URL& url, const String& label)
 {
     m_url = url;
-    m_uriList = url;
-    setText(url.string());
+    if (m_uriList.isEmpty())
+        m_uriList = url;
 
+    if (!hasText())
+        setText(url.string());
+
+    if (hasMarkup())
+        return;
+
     String actualLabel(label);
     if (actualLabel.isEmpty())
         actualLabel = url;

Modified: trunk/Source/WebKit/ChangeLog (261553 => 261554)


--- trunk/Source/WebKit/ChangeLog	2020-05-12 11:45:25 UTC (rev 261553)
+++ trunk/Source/WebKit/ChangeLog	2020-05-12 15:20:30 UTC (rev 261554)
@@ -1,3 +1,64 @@
+2020-05-12  Carlos Garcia Campos  <[email protected]>
+
+        [GTK] Rework clipboard handling in preparation for GTK4
+        https://bugs.webkit.org/show_bug.cgi?id=211511
+
+        Reviewed by Adrian Perez de Castro.
+
+        Use async APIs to avoid blocking the UI process during the communication with the clipboard. In GTK4 only async
+        APIs are available. Add Clipboard class to handle the communication with the clipboard with the GTK
+        implementation in ClipboardGtk3 and ClipboardGtk4 files.
+
+        * Shared/gtk/WebSelectionData.cpp:
+        (WebKit::WebSelectionData::WebSelectionData): Add constructor receivnig an rvalue reference.
+        * Shared/gtk/WebSelectionData.h:
+        * SourcesGTK.txt:
+        * UIProcess/WebPasteboardProxy.h:
+        * UIProcess/WebPasteboardProxy.messages.in:
+        * UIProcess/gtk/Clipboard.cpp: Added.
+        (WebKit::clipboard):
+        (WebKit::primary):
+        (WebKit::Clipboard::get):
+        * UIProcess/gtk/Clipboard.h: Added.
+        * UIProcess/gtk/ClipboardGtk3.cpp: Added.
+        (WebKit::Clipboard::Clipboard):
+        (WebKit::isPrimaryClipboard):
+        (WebKit::Clipboard::type const):
+        (WebKit::FormatsAsyncData::FormatsAsyncData):
+        (WebKit::Clipboard::formats):
+        (WebKit::ReadTextAsyncData::ReadTextAsyncData):
+        (WebKit::Clipboard::readText):
+        (WebKit::ReadFilePathsAsyncData::ReadFilePathsAsyncData):
+        (WebKit::Clipboard::readFilePaths):
+        (WebKit::ReadBufferAsyncData::ReadBufferAsyncData):
+        (WebKit::Clipboard::readBuffer):
+        (WebKit::Clipboard::write):
+        (WebKit::Clipboard::clear):
+        * UIProcess/gtk/ClipboardGtk4.cpp: Added.
+        (WebKit::Clipboard::Clipboard):
+        (WebKit::Clipboard::type const):
+        (WebKit::Clipboard::formats):
+        (WebKit::Clipboard::readText):
+        (WebKit::Clipboard::readFilePaths):
+        (WebKit::Clipboard::readBuffer):
+        (WebKit::Clipboard::write):
+        (WebKit::Clipboard::clear):
+        * UIProcess/gtk/WebPasteboardProxyGtk.cpp:
+        (WebKit::WebPasteboardProxy::getTypes):
+        (WebKit::WebPasteboardProxy::readText):
+        (WebKit::WebPasteboardProxy::readFilePaths):
+        (WebKit::WebPasteboardProxy::readBuffer):
+        (WebKit::WebPasteboardProxy::writeToClipboard):
+        (WebKit::WebPasteboardProxy::clearClipboard):
+        * WebProcess/WebCoreSupport/WebPlatformStrategies.cpp:
+        (WebKit::WebPlatformStrategies::types):
+        (WebKit::WebPlatformStrategies::readTextFromClipboard):
+        (WebKit::WebPlatformStrategies::readFilePathsFromClipboard):
+        (WebKit::WebPlatformStrategies::readBufferFromClipboard):
+        (WebKit::WebPlatformStrategies::writeToClipboard):
+        (WebKit::WebPlatformStrategies::clearClipboard):
+        * WebProcess/WebCoreSupport/WebPlatformStrategies.h:
+
 2020-05-12  Youenn Fablet  <[email protected]>
 
         Introduce a RealtimeMediaSource video sample observer

Modified: trunk/Source/WebKit/Shared/gtk/WebSelectionData.cpp (261553 => 261554)


--- trunk/Source/WebKit/Shared/gtk/WebSelectionData.cpp	2020-05-12 11:45:25 UTC (rev 261553)
+++ trunk/Source/WebKit/Shared/gtk/WebSelectionData.cpp	2020-05-12 15:20:30 UTC (rev 261554)
@@ -41,6 +41,11 @@
 {
 }
 
+WebSelectionData::WebSelectionData(WebCore::SelectionData&& data)
+    : selectionData(data)
+{
+}
+
 void WebSelectionData::encode(IPC::Encoder& encoder) const
 {
     encoder << selectionData.get();

Modified: trunk/Source/WebKit/Shared/gtk/WebSelectionData.h (261553 => 261554)


--- trunk/Source/WebKit/Shared/gtk/WebSelectionData.h	2020-05-12 11:45:25 UTC (rev 261553)
+++ trunk/Source/WebKit/Shared/gtk/WebSelectionData.h	2020-05-12 15:20:30 UTC (rev 261554)
@@ -31,6 +31,7 @@
     WebSelectionData();
     explicit WebSelectionData(const WebCore::SelectionData&);
     explicit WebSelectionData(Ref<WebCore::SelectionData>&&);
+    explicit WebSelectionData(WebCore::SelectionData&&);
 
     Ref<WebCore::SelectionData> selectionData;
 

Modified: trunk/Source/WebKit/SourcesGTK.txt (261553 => 261554)


--- trunk/Source/WebKit/SourcesGTK.txt	2020-05-12 11:45:25 UTC (rev 261553)
+++ trunk/Source/WebKit/SourcesGTK.txt	2020-05-12 15:20:30 UTC (rev 261554)
@@ -253,6 +253,9 @@
 UIProcess/gtk/AcceleratedBackingStore.cpp @no-unify
 UIProcess/gtk/AcceleratedBackingStoreWayland.cpp @no-unify
 UIProcess/gtk/AcceleratedBackingStoreX11.cpp @no-unify
+UIProcess/gtk/Clipboard.cpp
+UIProcess/gtk/ClipboardGtk3.cpp @no-unify
+UIProcess/gtk/ClipboardGtk4.cpp @no-unify
 UIProcess/gtk/DragAndDropHandler.cpp
 UIProcess/gtk/GestureController.cpp
 UIProcess/gtk/HardwareAccelerationManager.cpp

Modified: trunk/Source/WebKit/UIProcess/WebPasteboardProxy.h (261553 => 261554)


--- trunk/Source/WebKit/UIProcess/WebPasteboardProxy.h	2020-05-12 11:45:25 UTC (rev 261553)
+++ trunk/Source/WebKit/UIProcess/WebPasteboardProxy.h	2020-05-12 15:20:30 UTC (rev 261554)
@@ -34,6 +34,10 @@
 #include <wtf/HashSet.h>
 #include <wtf/WeakHashSet.h>
 
+namespace IPC {
+class SharedBufferDataReference;
+}
+
 namespace WebCore {
 class Color;
 class PasteboardCustomData;
@@ -66,6 +70,7 @@
 
 #if PLATFORM(GTK)
     void setPrimarySelectionOwner(WebFrameProxy*);
+    WebFrameProxy* primarySelectionOwner() const { return m_primarySelectionOwner; }
     void didDestroyFrame(WebFrameProxy*);
 #endif
 
@@ -118,11 +123,14 @@
     void urlStringSuitableForLoading(IPC::Connection&, const String& pasteboardName, CompletionHandler<void(String&& url, String&& title)>&&);
 
 #if PLATFORM(GTK)
-    void writeToClipboard(const String& pasteboardName, const WebSelectionData&);
-    void readFromClipboard(const String& pasteboardName, CompletionHandler<void(WebSelectionData&&)>&&);
+    void getTypes(const String& pasteboardName, CompletionHandler<void(Vector<String>&&)>&&);
+    void readText(const String& pasteboardName, CompletionHandler<void(String&&)>&&);
+    void readFilePaths(const String& pasteboardName, CompletionHandler<void(Vector<String>&&)>&&);
+    void readBuffer(const String& pasteboardName, const String& pasteboardType, CompletionHandler<void(IPC::SharedBufferDataReference&&)>&&);
+    void writeToClipboard(const String& pasteboardName, WebSelectionData&&);
+    void clearClipboard(const String& pasteboardName);
 
     WebFrameProxy* m_primarySelectionOwner { nullptr };
-    WebFrameProxy* m_frameWritingToClipboard { nullptr };
 #endif // PLATFORM(GTK)
 
 #if USE(LIBWPE)

Modified: trunk/Source/WebKit/UIProcess/WebPasteboardProxy.messages.in (261553 => 261554)


--- trunk/Source/WebKit/UIProcess/WebPasteboardProxy.messages.in	2020-05-12 11:45:25 UTC (rev 261553)
+++ trunk/Source/WebKit/UIProcess/WebPasteboardProxy.messages.in	2020-05-12 15:20:30 UTC (rev 261554)
@@ -61,8 +61,12 @@
 #endif
 
 #if PLATFORM(GTK)
+    GetTypes(String pasteboardName) -> (Vector<String> types) Synchronous
+    ReadText(String pasteboardName) -> (String text) Synchronous
+    ReadFilePaths(String pasteboardName) -> (Vector<String> types) Synchronous
+    ReadBuffer(String pasteboardName, String pasteboardType) -> (IPC::SharedBufferDataReference data) Synchronous
     WriteToClipboard(String pasteboardName, struct WebKit::WebSelectionData pasteboardContent)
-    ReadFromClipboard(String pasteboardName) -> (struct WebKit::WebSelectionData pasteboardContent) Synchronous
+    ClearClipboard(String pasteboardName)
 #endif
 
 #if USE(LIBWPE)

Added: trunk/Source/WebKit/UIProcess/gtk/Clipboard.cpp (0 => 261554)


--- trunk/Source/WebKit/UIProcess/gtk/Clipboard.cpp	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/gtk/Clipboard.cpp	2020-05-12 15:20:30 UTC (rev 261554)
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2020 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Clipboard.h"
+
+namespace WebKit {
+
+static Clipboard& clipboard()
+{
+    static std::once_flag onceFlag;
+    static LazyNeverDestroyed<Clipboard> object;
+
+    std::call_once(onceFlag, [] {
+        object.construct(Clipboard::Type::Clipboard);
+    });
+
+    return object;
+}
+
+static Clipboard& primary()
+{
+    static std::once_flag onceFlag;
+    static LazyNeverDestroyed<Clipboard> object;
+
+    std::call_once(onceFlag, [] {
+        object.construct(Clipboard::Type::Primary);
+    });
+
+    return object;
+}
+
+Clipboard& Clipboard::get(const String& name)
+{
+    if (name == "CLIPBOARD")
+        return clipboard();
+
+    if (name == "PRIMARY")
+        return primary();
+
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WebKit

Added: trunk/Source/WebKit/UIProcess/gtk/Clipboard.h (0 => 261554)


--- trunk/Source/WebKit/UIProcess/gtk/Clipboard.h	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/gtk/Clipboard.h	2020-05-12 15:20:30 UTC (rev 261554)
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2020 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/CompletionHandler.h>
+#include <wtf/Forward.h>
+
+#if !USE(GTK4)
+typedef struct _GtkClipboard GtkClipboard;
+#endif
+
+namespace WebCore {
+class SelectionData;
+class SharedBuffer;
+}
+
+namespace WebKit {
+
+class WebFrameProxy;
+
+class Clipboard {
+    WTF_MAKE_NONCOPYABLE(Clipboard); WTF_MAKE_FAST_ALLOCATED;
+public:
+    static Clipboard& get(const String& name);
+
+    enum class Type { Clipboard, Primary };
+    explicit Clipboard(Type);
+
+    Type type() const;
+    void formats(CompletionHandler<void(Vector<String>&&)>&&);
+    void readText(CompletionHandler<void(String&&)>&&);
+    void readFilePaths(CompletionHandler<void(Vector<String>&&)>&&);
+    void readBuffer(const char*, CompletionHandler<void(Ref<WebCore::SharedBuffer>&&)>&&);
+    void write(Ref<WebCore::SelectionData>&&);
+    void clear();
+
+private:
+#if !USE(GTK4)
+    GtkClipboard* m_clipboard { nullptr };
+    WebFrameProxy* m_frameWritingToClipboard { nullptr };
+#endif
+};
+
+} // namespace WebKit

Added: trunk/Source/WebKit/UIProcess/gtk/ClipboardGtk3.cpp (0 => 261554)


--- trunk/Source/WebKit/UIProcess/gtk/ClipboardGtk3.cpp	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/gtk/ClipboardGtk3.cpp	2020-05-12 15:20:30 UTC (rev 261554)
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2020 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Clipboard.h"
+
+#if !USE(GTK4)
+
+#include "WebPasteboardProxy.h"
+#include <WebCore/GRefPtrGtk.h>
+#include <WebCore/SelectionData.h>
+#include <WebCore/SharedBuffer.h>
+#include <gtk/gtk.h>
+#include <wtf/SetForScope.h>
+
+namespace WebKit {
+
+Clipboard::Clipboard(Type type)
+    : m_clipboard(gtk_clipboard_get_for_display(gdk_display_get_default(), type == Type::Clipboard ? GDK_SELECTION_CLIPBOARD : GDK_SELECTION_PRIMARY))
+{
+}
+
+static bool isPrimaryClipboard(GtkClipboard* clipboard)
+{
+    return clipboard == gtk_clipboard_get_for_display(gdk_display_get_default(), GDK_SELECTION_PRIMARY);
+}
+
+Clipboard::Type Clipboard::type() const
+{
+    return isPrimaryClipboard(m_clipboard) ? Type::Primary : Type::Clipboard;
+}
+
+struct FormatsAsyncData {
+    WTF_MAKE_STRUCT_FAST_ALLOCATED;
+
+    explicit FormatsAsyncData(CompletionHandler<void(Vector<String>&&)>&& handler)
+        : completionHandler(WTFMove(handler))
+    {
+    }
+
+    CompletionHandler<void(Vector<String>&&)> completionHandler;
+};
+
+void Clipboard::formats(CompletionHandler<void(Vector<String>&&)>&& completionHandler)
+{
+    gtk_clipboard_request_targets(m_clipboard, [](GtkClipboard* clipboard, GdkAtom* atoms, gint atomsCount, gpointer userData) {
+        std::unique_ptr<FormatsAsyncData> data(static_cast<FormatsAsyncData*>(userData));
+
+        Vector<String> result;
+        for (int i = 0; i < atomsCount; ++i) {
+            GUniquePtr<char> atom(gdk_atom_name(atoms[i]));
+            result.append(String::fromUTF8(atom.get()));
+        }
+        data->completionHandler(WTFMove(result));
+    }, new FormatsAsyncData(WTFMove(completionHandler)));
+}
+
+struct ReadTextAsyncData {
+    WTF_MAKE_STRUCT_FAST_ALLOCATED;
+
+    explicit ReadTextAsyncData(CompletionHandler<void(String&&)>&& handler)
+        : completionHandler(WTFMove(handler))
+    {
+    }
+
+    CompletionHandler<void(String&&)> completionHandler;
+};
+
+void Clipboard::readText(CompletionHandler<void(String&&)>&& completionHandler)
+{
+    gtk_clipboard_request_text(m_clipboard, [](GtkClipboard*, const char* text, gpointer userData) {
+        std::unique_ptr<ReadTextAsyncData> data(static_cast<ReadTextAsyncData*>(userData));
+        data->completionHandler(String::fromUTF8(text));
+    }, new ReadTextAsyncData(WTFMove(completionHandler)));
+}
+
+struct ReadFilePathsAsyncData {
+    WTF_MAKE_STRUCT_FAST_ALLOCATED;
+
+    explicit ReadFilePathsAsyncData(CompletionHandler<void(Vector<String>&&)>&& handler)
+        : completionHandler(WTFMove(handler))
+    {
+    }
+
+    CompletionHandler<void(Vector<String>&&)> completionHandler;
+};
+
+void Clipboard::readFilePaths(CompletionHandler<void(Vector<String>&&)>&& completionHandler)
+{
+    gtk_clipboard_request_uris(m_clipboard, [](GtkClipboard*, char** uris, gpointer userData) {
+        std::unique_ptr<ReadFilePathsAsyncData> data(static_cast<ReadFilePathsAsyncData*>(userData));
+        Vector<String> result;
+        for (unsigned i = 0; uris && uris[i]; ++i) {
+            GUniquePtr<gchar> filename(g_filename_from_uri(uris[i], nullptr, nullptr));
+            if (filename)
+                result.append(String::fromUTF8(filename.get()));
+        }
+        data->completionHandler(WTFMove(result));
+    }, new ReadFilePathsAsyncData(WTFMove(completionHandler)));
+}
+
+struct ReadBufferAsyncData {
+    WTF_MAKE_STRUCT_FAST_ALLOCATED;
+
+    explicit ReadBufferAsyncData(CompletionHandler<void(Ref<WebCore::SharedBuffer>&&)>&& handler)
+        : completionHandler(WTFMove(handler))
+    {
+    }
+
+    CompletionHandler<void(Ref<WebCore::SharedBuffer>&&)> completionHandler;
+};
+
+void Clipboard::readBuffer(const char* format, CompletionHandler<void(Ref<WebCore::SharedBuffer>&&)>&& completionHandler)
+{
+    gtk_clipboard_request_contents(m_clipboard, gdk_atom_intern(format, TRUE), [](GtkClipboard*, GtkSelectionData* selection, gpointer userData) {
+        std::unique_ptr<ReadBufferAsyncData> data(static_cast<ReadBufferAsyncData*>(userData));
+        int contentsLength;
+        const auto* contents = gtk_selection_data_get_data_with_length(selection, &contentsLength);
+        data->completionHandler(WebCore::SharedBuffer::create(contents, contentsLength > 0 ? static_cast<size_t>(contentsLength) : 0));
+    }, new ReadBufferAsyncData(WTFMove(completionHandler)));
+}
+
+struct WriteAsyncData {
+    WTF_MAKE_STRUCT_FAST_ALLOCATED;
+
+    WriteAsyncData(Ref<WebCore::SelectionData>&& selection, Clipboard& clipboard)
+        : selectionData(WTFMove(selection))
+        , clipboard(clipboard)
+    {
+    }
+
+    Ref<WebCore::SelectionData> selectionData;
+    Clipboard& clipboard;
+};
+
+enum ClipboardTargetType { Markup, Text, Image, SmartPaste };
+
+void Clipboard::write(Ref<WebCore::SelectionData>&& selectionData)
+{
+    SetForScope<WebFrameProxy*> frameWritingToClipboard(m_frameWritingToClipboard, WebPasteboardProxy::singleton().primarySelectionOwner());
+
+    GRefPtr<GtkTargetList> list = adoptGRef(gtk_target_list_new(nullptr, 0));
+    if (selectionData->hasMarkup())
+        gtk_target_list_add(list.get(), gdk_atom_intern_static_string("text/html"), 0, ClipboardTargetType::Markup);
+    if (selectionData->hasImage())
+        gtk_target_list_add_image_targets(list.get(), ClipboardTargetType::Image, TRUE);
+    if (selectionData->hasText())
+        gtk_target_list_add_text_targets(list.get(), ClipboardTargetType::Text);
+    if (selectionData->canSmartReplace())
+        gtk_target_list_add(list.get(), gdk_atom_intern_static_string("application/vnd.webkitgtk.smartpaste"), 0, ClipboardTargetType::SmartPaste);
+
+    int numberOfTargets;
+    GtkTargetEntry* table = gtk_target_table_new_from_list(list.get(), &numberOfTargets);
+    if (!numberOfTargets) {
+        gtk_clipboard_clear(m_clipboard);
+        return;
+    }
+
+    auto data = "" *this);
+    gboolean succeeded = gtk_clipboard_set_with_data(m_clipboard, table, numberOfTargets,
+        [](GtkClipboard*, GtkSelectionData* selection, guint info, gpointer userData) {
+            auto& data = ""
+            auto& selectionData = data.selectionData.get();
+            switch (info) {
+            case ClipboardTargetType::Markup: {
+                CString markup = selectionData.markup().utf8();
+                gtk_selection_data_set(selection, gdk_atom_intern_static_string("text/html"), 8, reinterpret_cast<const guchar*>(markup.data()), markup.length());
+                break;
+            }
+            case ClipboardTargetType::Text:
+                gtk_selection_data_set_text(selection, selectionData.text().utf8().data(), -1);
+                break;
+            case ClipboardTargetType::Image: {
+                if (selectionData.hasImage()) {
+                    GRefPtr<GdkPixbuf> pixbuf = adoptGRef(selectionData.image()->getGdkPixbuf());
+                    gtk_selection_data_set_pixbuf(selection, pixbuf.get());
+                }
+                break;
+            }
+            case ClipboardTargetType::SmartPaste:
+                gtk_selection_data_set_text(selection, "", -1);
+                break;
+            }
+        },
+        [](GtkClipboard* clipboard, gpointer userData) {
+            std::unique_ptr<WriteAsyncData> data(static_cast<WriteAsyncData*>(userData));
+            if (isPrimaryClipboard(clipboard) && WebPasteboardProxy::singleton().primarySelectionOwner() != data->clipboard.m_frameWritingToClipboard)
+                WebPasteboardProxy::singleton().setPrimarySelectionOwner(nullptr);
+        }, data.get());
+
+    if (succeeded) {
+        // In case of success the clipboard owns data, so we release it here.
+        data.release();
+
+        gtk_clipboard_set_can_store(m_clipboard, nullptr, 0);
+    }
+    gtk_target_table_free(table, numberOfTargets);
+}
+
+void Clipboard::clear()
+{
+    gtk_clipboard_clear(m_clipboard);
+}
+
+} // namespace WebKit
+
+#endif

Added: trunk/Source/WebKit/UIProcess/gtk/ClipboardGtk4.cpp (0 => 261554)


--- trunk/Source/WebKit/UIProcess/gtk/ClipboardGtk4.cpp	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/gtk/ClipboardGtk4.cpp	2020-05-12 15:20:30 UTC (rev 261554)
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2020 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Clipboard.h"
+
+#if USE(GTK4)
+
+#include <WebCore/SelectionData.h>
+#include <WebCore/SharedBuffer.h>
+
+namespace WebKit {
+
+Clipboard::Clipboard(Type)
+{
+}
+
+Clipboard::Type Clipboard::type() const
+{
+    return Type::Clipboard;
+}
+
+void Clipboard::formats(CompletionHandler<void(Vector<String>&&)>&& completionHandler)
+{
+    completionHandler({ });
+}
+
+void Clipboard::readText(CompletionHandler<void(String&&)>&& completionHandler)
+{
+    completionHandler({ });
+}
+
+void Clipboard::readFilePaths(CompletionHandler<void(Vector<String>&&)>&& completionHandler)
+{
+    completionHandler({ });
+}
+
+void Clipboard::readBuffer(const char* format, CompletionHandler<void(Ref<WebCore::SharedBuffer>&&)>&& completionHandler)
+{
+    completionHandler(WebCore::SharedBuffer::create());
+}
+
+void Clipboard::write(const WebCore::SelectionData&)
+{
+}
+
+void Clipboard::clear()
+{
+}
+
+} // namespace WebKit
+
+#endif

Modified: trunk/Source/WebKit/UIProcess/gtk/WebPasteboardProxyGtk.cpp (261553 => 261554)


--- trunk/Source/WebKit/UIProcess/gtk/WebPasteboardProxyGtk.cpp	2020-05-12 11:45:25 UTC (rev 261553)
+++ trunk/Source/WebKit/UIProcess/gtk/WebPasteboardProxyGtk.cpp	2020-05-12 15:20:30 UTC (rev 261554)
@@ -26,29 +26,47 @@
 #include "config.h"
 #include "WebPasteboardProxy.h"
 
+#include "Clipboard.h"
+#include "SharedBufferDataReference.h"
 #include "WebFrameProxy.h"
 #include "WebSelectionData.h"
 #include <WebCore/PlatformPasteboard.h>
+#include <WebCore/SharedBuffer.h>
 #include <wtf/SetForScope.h>
 
 namespace WebKit {
 using namespace WebCore;
 
-void WebPasteboardProxy::writeToClipboard(const String& pasteboardName, const WebSelectionData& selection)
+void WebPasteboardProxy::getTypes(const String& pasteboardName, CompletionHandler<void(Vector<String>&&)>&& completionHandler)
 {
-    SetForScope<WebFrameProxy*> frameWritingToClipboard(m_frameWritingToClipboard, m_primarySelectionOwner);
-    PlatformPasteboard(pasteboardName).writeToClipboard(selection.selectionData, [this] {
-        if (m_frameWritingToClipboard == m_primarySelectionOwner)
-            return;
-        setPrimarySelectionOwner(nullptr);
-    });
+    Clipboard::get(pasteboardName).formats(WTFMove(completionHandler));
 }
 
-void WebPasteboardProxy::readFromClipboard(const String& pasteboardName, CompletionHandler<void(WebSelectionData&&)>&& completionHandler)
+void WebPasteboardProxy::readText(const String& pasteboardName, CompletionHandler<void(String&&)>&& completionHandler)
 {
-    completionHandler(WebSelectionData(PlatformPasteboard(pasteboardName).readFromClipboard()));
+    Clipboard::get(pasteboardName).readText(WTFMove(completionHandler));
 }
 
+void WebPasteboardProxy::readFilePaths(const String& pasteboardName, CompletionHandler<void(Vector<String>&&)>&& completionHandler)
+{
+    Clipboard::get(pasteboardName).readFilePaths(WTFMove(completionHandler));
+}
+
+void WebPasteboardProxy::readBuffer(const String& pasteboardName, const String& pasteboardType, CompletionHandler<void(IPC::SharedBufferDataReference&&)>&& completionHandler)
+{
+    Clipboard::get(pasteboardName).readBuffer(pasteboardType.utf8().data(), WTFMove(completionHandler));
+}
+
+void WebPasteboardProxy::writeToClipboard(const String& pasteboardName, WebSelectionData&& selection)
+{
+    Clipboard::get(pasteboardName).write(WTFMove(selection.selectionData));
+}
+
+void WebPasteboardProxy::clearClipboard(const String& pasteboardName)
+{
+    Clipboard::get(pasteboardName).clear();
+}
+
 void WebPasteboardProxy::setPrimarySelectionOwner(WebFrameProxy* frame)
 {
     if (m_primarySelectionOwner == frame)

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp (261553 => 261554)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp	2020-05-12 11:45:25 UTC (rev 261553)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp	2020-05-12 15:20:30 UTC (rev 261554)
@@ -293,6 +293,40 @@
 #if PLATFORM(GTK)
 // PasteboardStrategy
 
+Vector<String> WebPlatformStrategies::types(const String& pasteboardName)
+{
+    Vector<String> result;
+    WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::GetTypes(pasteboardName), Messages::WebPasteboardProxy::GetTypes::Reply(result), 0);
+    return result;
+}
+
+String WebPlatformStrategies::readTextFromClipboard(const String& pasteboardName)
+{
+    String result;
+    WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::ReadText(pasteboardName), Messages::WebPasteboardProxy::ReadText::Reply(result), 0);
+    return result;
+}
+
+Vector<String> WebPlatformStrategies::readFilePathsFromClipboard(const String& pasteboardName)
+{
+    Vector<String> result;
+    WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::ReadFilePaths(pasteboardName), Messages::WebPasteboardProxy::ReadFilePaths::Reply(result), 0);
+    return result;
+}
+
+RefPtr<SharedBuffer> WebPlatformStrategies::readBufferFromClipboard(const String& pasteboardName, const String& pasteboardType)
+{
+
+    IPC::SharedBufferDataReference data;
+    WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::ReadBuffer(pasteboardName, pasteboardType), Messages::WebPasteboardProxy::ReadBuffer::Reply(data), 0);
+    return data.buffer();
+}
+
+void WebPlatformStrategies::writeToClipboard(const String& pasteboardName, SelectionData&& selectionData)
+{
+    WebProcess::singleton().parentProcessConnection()->send(Messages::WebPasteboardProxy::WriteToClipboard(pasteboardName, WebSelectionData(selectionData)), 0);
+}
+
 void WebPlatformStrategies::writeToClipboard(const String& pasteboardName, const SelectionData& selection)
 {
     WebSelectionData selectionData(selection);
@@ -299,11 +333,9 @@
     WebProcess::singleton().parentProcessConnection()->send(Messages::WebPasteboardProxy::WriteToClipboard(pasteboardName, selectionData), 0);
 }
 
-Ref<SelectionData> WebPlatformStrategies::readFromClipboard(const String& pasteboardName)
+void WebPlatformStrategies::clearClipboard(const String& pasteboardName)
 {
-    WebSelectionData selection;
-    WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::ReadFromClipboard(pasteboardName), Messages::WebPasteboardProxy::ReadFromClipboard::Reply(selection), 0);
-    return WTFMove(selection.selectionData);
+    WebProcess::singleton().parentProcessConnection()->send(Messages::WebPasteboardProxy::ClearClipboard(pasteboardName), 0);
 }
 
 #endif // PLATFORM(GTK)

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.h (261553 => 261554)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.h	2020-05-12 11:45:25 UTC (rev 261553)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.h	2020-05-12 15:20:30 UTC (rev 261554)
@@ -75,8 +75,13 @@
     String urlStringSuitableForLoading(const String& pasteboardName, String& title) override;
 #endif
 #if PLATFORM(GTK)
+    Vector<String> types(const String& pasteboardName) override;
+    String readTextFromClipboard(const String& pasteboardName) override;
+    Vector<String> readFilePathsFromClipboard(const String& pasteboardName) override;
+    RefPtr<SharedBuffer> readBufferFromClipboard(const String& pasteboardName, const String& pasteboardType) override;
     void writeToClipboard(const String& pasteboardName, const WebCore::SelectionData&) override;
-    Ref<WebCore::SelectionData> readFromClipboard(const String& pasteboardName) override;
+    void writeToClipboard(const String& pasteboardName, WebCore::SelectionData&&) override;
+    void clearClipboard(const String& pasteboardName) override;
 #endif
 #if USE(LIBWPE)
     void getTypes(Vector<String>& types) override;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to