summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJocelyn Turcotte <jocelyn.turcotte@digia.com>2014-02-18 14:04:56 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-03-04 11:47:30 +0100
commite85a581c518f11fcf9080ba356a4538a23f04212 (patch)
treeba19f912ea13e6b83782e4fd8731aa1f7f5fd149
parent970ccc7f1e7890f4ac49b761678274823576aca5 (diff)
Add Qt clipboard integration
The GTK clipboard integration isn't working for us and we need a way to get clipboard requests from the renderer into the system clipboard. This patch adds a Qt implementation to let Qt handle the platform abstraction, even though the Chromium clipboard direct integration could work on some platforms. Change-Id: Ie7af5c6b4c662fc8f4109b2e85e9f594d6d90b0d Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
-rw-r--r--patches/chromium/0018-Update-clipboard.h-to-allow-building-clipboard_qt.cp.patch44
m---------src/3rdparty0
-rw-r--r--src/core/clipboard_qt.cpp374
-rw-r--r--src/core/clipboard_qt.h64
-rw-r--r--src/core/core_gyp_generator.pro2
-rw-r--r--src/core/qtwebengine_extras.gypi3
6 files changed, 487 insertions, 0 deletions
diff --git a/patches/chromium/0018-Update-clipboard.h-to-allow-building-clipboard_qt.cp.patch b/patches/chromium/0018-Update-clipboard.h-to-allow-building-clipboard_qt.cp.patch
new file mode 100644
index 000000000..d8e6c5c90
--- /dev/null
+++ b/patches/chromium/0018-Update-clipboard.h-to-allow-building-clipboard_qt.cp.patch
@@ -0,0 +1,44 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
+Date: Tue, 18 Feb 2014 14:49:48 +0100
+Subject: Update clipboard.h to allow building clipboard_qt.cpp on all
+ platforms
+
+Change-Id: Ife754b2fcb1c1a535565facdbab615c07b8c4935
+Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
+---
+ ui/base/clipboard/clipboard.h | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/ui/base/clipboard/clipboard.h b/ui/base/clipboard/clipboard.h
+index 94cd664..4e4791d 100644
+--- a/ui/base/clipboard/clipboard.h
++++ b/ui/base/clipboard/clipboard.h
+@@ -87,6 +87,7 @@ class UI_EXPORT Clipboard : NON_EXPORTED_BASE(public base::ThreadChecker) {
+ bool operator<(const FormatType& other) const;
+ #endif
+
++#if !defined(TOOLKIT_QT)
+ #if defined(OS_WIN)
+ const FORMATETC& ToFormatEtc() const { return data_; }
+ #elif defined(OS_MACOSX)
+@@ -96,6 +97,7 @@ class UI_EXPORT Clipboard : NON_EXPORTED_BASE(public base::ThreadChecker) {
+ #elif defined(USE_AURA)
+ const std::string& ToString() const { return data_; }
+ #endif
++#endif // TOOLKIT_QT
+
+ private:
+ friend class Clipboard;
+@@ -110,7 +112,10 @@ class UI_EXPORT Clipboard : NON_EXPORTED_BASE(public base::ThreadChecker) {
+ //
+ // Note that in some cases, the accessor for the wrapped descriptor may be
+ // public, as these format types can be used by drag and drop code as well.
+-#if defined(OS_WIN)
++#if defined(TOOLKIT_QT)
++ explicit FormatType(const std::string& native_format);
++ std::string data_;
++#elif defined(OS_WIN)
+ explicit FormatType(UINT native_format);
+ FormatType(UINT native_format, LONG index);
+ UINT ToUINT() const { return data_.cfFormat; }
diff --git a/src/3rdparty b/src/3rdparty
-Subproject 002eaa024104d6135d82d921ca4a5b4b673a9d8
+Subproject 9001f7258c97c6fe61d6362aa3431af7128f921
diff --git a/src/core/clipboard_qt.cpp b/src/core/clipboard_qt.cpp
new file mode 100644
index 000000000..6d2d28359
--- /dev/null
+++ b/src/core/clipboard_qt.cpp
@@ -0,0 +1,374 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "clipboard_qt.h"
+#include "ui/base/clipboard/clipboard.h"
+
+#include "type_conversion.h"
+
+#include "base/logging.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/base/clipboard/custom_data_helper.h"
+
+#include <QGuiApplication>
+#include <QImage>
+#include <QMimeData>
+
+Q_GLOBAL_STATIC(ClipboardChangeObserver, clipboardChangeObserver)
+
+ClipboardChangeObserver::ClipboardChangeObserver()
+{
+ connect(QGuiApplication::clipboard(), SIGNAL(changed(QClipboard::Mode)), SLOT(trackChange(QClipboard::Mode)));
+}
+
+void ClipboardChangeObserver::trackChange(QClipboard::Mode mode)
+{
+ ++sequenceNumber[mode];
+}
+
+namespace ui {
+
+namespace {
+
+const char kMimeTypeBitmap[] = "image/bmp";
+const char kMimeTypeMozillaURL[] = "text/x-moz-url";
+const char kMimeTypeWebCustomDataCopy[] = "chromium/x-web-custom-data";
+const char kMimeTypePepperCustomData[] = "chromium/x-pepper-custom-data";
+const char kMimeTypeWebkitSmartPaste[] = "chromium/x-webkit-paste";
+
+QScopedPointer<QMimeData> uncommittedData;
+QMimeData *getUncommittedData()
+{
+ if (!uncommittedData)
+ uncommittedData.reset(new QMimeData);
+ return uncommittedData.data();
+}
+
+} // namespace
+
+Clipboard::FormatType::FormatType()
+{
+}
+
+Clipboard::FormatType::FormatType(const std::string& format_string)
+ : data_(format_string)
+{
+}
+
+Clipboard::FormatType::~FormatType()
+{
+}
+
+std::string Clipboard::FormatType::Serialize() const
+{
+ return data_;
+}
+
+Clipboard::FormatType Clipboard::FormatType::Deserialize(const std::string& serialization)
+{
+ return FormatType(serialization);
+}
+
+bool Clipboard::FormatType::Equals(const FormatType& other) const
+{
+ return data_ == other.data_;
+}
+
+Clipboard::Clipboard()
+{
+}
+
+Clipboard::~Clipboard()
+{
+}
+
+void Clipboard::WriteObjects(Buffer buffer, const ObjectMap& objects)
+{
+ DCHECK(CalledOnValidThread());
+
+ for (ObjectMap::const_iterator iter = objects.begin(); iter != objects.end(); ++iter)
+ DispatchObject(static_cast<ObjectType>(iter->first), iter->second);
+
+ // Commit the accumulated data.
+ if (uncommittedData)
+ QGuiApplication::clipboard()->setMimeData(uncommittedData.take(), buffer == BUFFER_STANDARD ? QClipboard::Clipboard : QClipboard::Selection);
+
+ if (buffer == BUFFER_STANDARD) {
+ ObjectMap::const_iterator text_iter = objects.find(CBF_TEXT);
+ if (text_iter != objects.end()) {
+ // Copy text and SourceTag to the selection clipboard.
+ ObjectMap::const_iterator next_iter = text_iter;
+ WriteObjects(BUFFER_SELECTION, ObjectMap(text_iter, ++next_iter));
+ }
+ }
+}
+
+void Clipboard::WriteText(const char* text_data, size_t text_len)
+{
+ getUncommittedData()->setText(QString::fromUtf8(text_data, text_len));
+}
+
+void Clipboard::WriteHTML(const char* markup_data, size_t markup_len, const char* url_data, size_t url_len)
+{
+ getUncommittedData()->setHtml(QString::fromUtf8(markup_data, markup_len));
+}
+
+void Clipboard::WriteRTF(const char* rtf_data, size_t data_len)
+{
+ getUncommittedData()->setData(QString::fromLatin1(kMimeTypeRTF), QByteArray(rtf_data, data_len));
+}
+
+void Clipboard::WriteWebSmartPaste()
+{
+ getUncommittedData()->setData(QString::fromLatin1(kMimeTypeWebkitSmartPaste), QByteArray());
+}
+
+void Clipboard::WriteBitmap(const char* pixel_data, const char* size_data)
+{
+ const gfx::Size* size = reinterpret_cast<const gfx::Size*>(size_data);
+ QImage image(reinterpret_cast<const uchar *>(pixel_data), size->width(), size->height(), QImage::Format_ARGB32);
+ getUncommittedData()->setImageData(image.copy());
+}
+
+void Clipboard::WriteBookmark(const char* title_data, size_t title_len, const char* url_data, size_t url_len)
+{
+ // FIXME: Untested, seems to be used only for drag-n-drop.
+ // Write as a mozilla url (UTF16: URL, newline, title).
+ QString url = QString::fromUtf8(url_data, url_len);
+ QString title = QString::fromUtf8(title_data, title_len);
+
+ QByteArray data;
+ data.append(reinterpret_cast<const char*>(url.utf16()), url.size() * 2);
+ data.append('\n');
+ data.append(reinterpret_cast<const char*>(title.utf16()), title.size() * 2);
+ getUncommittedData()->setData(QString::fromLatin1(kMimeTypeMozillaURL), data);
+}
+
+void Clipboard::WriteData(const FormatType& format, const char* data_data, size_t data_len)
+{
+ getUncommittedData()->setData(QString::fromStdString(format.data_), QByteArray(data_data, data_len));
+}
+
+bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format, Clipboard::Buffer buffer) const
+{
+ const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(buffer == BUFFER_STANDARD ? QClipboard::Clipboard : QClipboard::Selection);
+ return mimeData->hasFormat(QString::fromStdString(format.data_));
+}
+
+void Clipboard::Clear(Clipboard::Buffer buffer)
+{
+ QGuiApplication::clipboard()->clear(buffer == BUFFER_STANDARD ? QClipboard::Clipboard : QClipboard::Selection);
+}
+
+void Clipboard::ReadAvailableTypes(Clipboard::Buffer buffer, std::vector<string16>* types, bool* contains_filenames) const
+{
+ if (!types || !contains_filenames) {
+ NOTREACHED();
+ return;
+ }
+
+ types->clear();
+ const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(buffer == BUFFER_STANDARD ? QClipboard::Clipboard : QClipboard::Selection);
+ Q_FOREACH (const QString &mimeType, mimeData->formats())
+ types->push_back(toString16(mimeType));
+ *contains_filenames = false;
+
+ const QByteArray customData = mimeData->data(QString::fromLatin1(kMimeTypeWebCustomDataCopy));
+ ReadCustomDataTypes(customData.constData(), customData.size(), types);
+}
+
+
+void Clipboard::ReadText(Clipboard::Buffer buffer, string16* result) const
+{
+ const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(buffer == BUFFER_STANDARD ? QClipboard::Clipboard : QClipboard::Selection);
+ *result = toString16(mimeData->text());
+}
+
+void Clipboard::ReadAsciiText(Clipboard::Buffer buffer, std::string* result) const
+{
+ const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(buffer == BUFFER_STANDARD ? QClipboard::Clipboard : QClipboard::Selection);
+ *result = mimeData->text().toStdString();
+}
+
+void Clipboard::ReadHTML(Clipboard::Buffer buffer, string16* markup, std::string* src_url, uint32* fragment_start, uint32* fragment_end) const
+{
+ markup->clear();
+ if (src_url)
+ src_url->clear();
+ *fragment_start = 0;
+ *fragment_end = 0;
+
+ const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(buffer == BUFFER_STANDARD ? QClipboard::Clipboard : QClipboard::Selection);
+ *markup = toString16(mimeData->html());
+ *fragment_end = static_cast<uint32>(markup->length());
+}
+
+void Clipboard::ReadRTF(Buffer buffer, std::string* result) const
+{
+ const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(buffer == BUFFER_STANDARD ? QClipboard::Clipboard : QClipboard::Selection);
+ const QByteArray byteArray = mimeData->data(QString::fromLatin1(kMimeTypeRTF));
+ *result = std::string(byteArray.constData(), byteArray.length());
+}
+
+SkBitmap Clipboard::ReadImage(Buffer buffer) const
+{
+ // FIXME: Untested, pasting image data seems to only be supported through
+ // FileReader.readAsDataURL in JavaScript and this isn't working down the pipe for some reason.
+ const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(buffer == BUFFER_STANDARD ? QClipboard::Clipboard : QClipboard::Selection);
+ QImage image = qvariant_cast<QImage>(mimeData->imageData());
+
+ Q_ASSERT(image.format() == QImage::Format_ARGB32);
+ SkBitmap bitmap;
+ bitmap.setConfig(SkBitmap::kARGB_8888_Config, image.width(), image.height());
+ bitmap.setPixels(const_cast<uchar*>(image.constBits()));
+
+ // Return a deep copy of the pixel data.
+ SkBitmap copy;
+ bitmap.copyTo(&copy, SkBitmap::kARGB_8888_Config);
+ return copy;
+}
+
+void Clipboard::ReadCustomData(Buffer buffer, const string16& type, string16* result) const
+{
+ const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(buffer == BUFFER_STANDARD ? QClipboard::Clipboard : QClipboard::Selection);
+ const QByteArray customData = mimeData->data(QString::fromLatin1(kMimeTypeWebCustomDataCopy));
+ ReadCustomDataForType(customData.constData(), customData.size(), type, result);
+}
+
+void Clipboard::ReadBookmark(string16* title, std::string* url) const
+{
+ NOTIMPLEMENTED();
+}
+
+void Clipboard::ReadData(const FormatType& format, std::string* result) const
+{
+ const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData();
+ const QByteArray byteArray = mimeData->data(QString::fromStdString(format.data_));
+ *result = std::string(byteArray.constData(), byteArray.length());
+}
+
+uint64 Clipboard::GetSequenceNumber(Buffer buffer)
+{
+ return clipboardChangeObserver()->getSequenceNumber(buffer == BUFFER_STANDARD ? QClipboard::Clipboard : QClipboard::Selection);
+}
+
+Clipboard::FormatType Clipboard::GetFormatType(const std::string& format_string)
+{
+ return FormatType::Deserialize(format_string);
+}
+
+const Clipboard::FormatType& Clipboard::GetPlainTextFormatType()
+{
+ CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeText));
+ return type;
+}
+
+const Clipboard::FormatType& Clipboard::GetPlainTextWFormatType()
+{
+ return GetPlainTextFormatType();
+}
+
+const Clipboard::FormatType& Clipboard::GetUrlFormatType()
+{
+ return GetPlainTextFormatType();
+}
+
+const Clipboard::FormatType& Clipboard::GetUrlWFormatType()
+{
+ return GetPlainTextWFormatType();
+}
+
+const Clipboard::FormatType& Clipboard::GetHtmlFormatType()
+{
+ CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeHTML));
+ return type;
+}
+
+const Clipboard::FormatType& Clipboard::GetRtfFormatType()
+{
+ CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeRTF));
+ return type;
+}
+
+const Clipboard::FormatType& Clipboard::GetBitmapFormatType()
+{
+ CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeBitmap));
+ return type;
+}
+
+const Clipboard::FormatType& Clipboard::GetWebKitSmartPasteFormatType()
+{
+ CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeWebkitSmartPaste));
+ return type;
+}
+
+const Clipboard::FormatType& Clipboard::GetWebCustomDataFormatType()
+{
+ CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeWebCustomDataCopy));
+ return type;
+}
+
+const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType()
+{
+ CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypePepperCustomData));
+ return type;
+}
+
+#if defined(TOOLKIT_GTK)
+void Clipboard::SetGtkClipboard(Buffer buffer)
+{
+}
+
+void Clipboard::InsertMapping(const char* key, char* data, size_t data_len)
+{
+}
+
+GtkClipboard* Clipboard::LookupBackingClipboard(Buffer clipboard) const
+{
+ return NULL;
+}
+#endif
+
+} // namespace ui
diff --git a/src/core/clipboard_qt.h b/src/core/clipboard_qt.h
new file mode 100644
index 000000000..62a921d7a
--- /dev/null
+++ b/src/core/clipboard_qt.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CLIPBOARD_QT_H
+#define CLIPBOARD_QT_H
+
+#include <QClipboard>
+#include <QMap>
+#include <QObject>
+
+class ClipboardChangeObserver : public QObject {
+ Q_OBJECT
+public:
+ ClipboardChangeObserver();
+ quint64 getSequenceNumber(QClipboard::Mode mode) {
+ return sequenceNumber.value(mode);
+ }
+
+private Q_SLOTS:
+ void trackChange(QClipboard::Mode mode);
+
+private:
+ QMap<QClipboard::Mode, quint64> sequenceNumber;
+};
+
+#endif
diff --git a/src/core/core_gyp_generator.pro b/src/core/core_gyp_generator.pro
index 7b0e36e0e..a75eb733a 100644
--- a/src/core/core_gyp_generator.pro
+++ b/src/core/core_gyp_generator.pro
@@ -36,6 +36,7 @@ SOURCES = \
browser_context_qt.cpp \
chromium_gpu_helper.cpp \
chromium_overrides.cpp \
+ clipboard_qt.cpp \
common/qt_messages.cpp \
content_client_qt.cpp \
content_browser_client_qt.cpp \
@@ -70,6 +71,7 @@ HEADERS = \
backing_store_qt.h \
browser_context_qt.h \
chromium_overrides.h \
+ clipboard_qt.h \
common/qt_messages.h \
content_client_qt.h \
content_browser_client_qt.h \
diff --git a/src/core/qtwebengine_extras.gypi b/src/core/qtwebengine_extras.gypi
index 7eefe2062..53affa463 100644
--- a/src/core/qtwebengine_extras.gypi
+++ b/src/core/qtwebengine_extras.gypi
@@ -6,6 +6,9 @@
'target_defaults': {
# patterns used to exclude chromium files from the build when we have a drop-in replacement
'sources/': [
+ ['exclude', 'base/clipboard/clipboard_gtk.cc$'],
+ ['exclude', 'base/clipboard/clipboard_mac.mm$'],
+ ['exclude', 'base/clipboard/clipboard_win.cc$'],
['exclude', 'base/resource/resource_bundle_gtk.cc$'],
['exclude', 'base/resource/resource_bundle_mac.mm$'],
['exclude', 'base/resource/resource_bundle_win.cc$'],