client: Convert text/x-moz-urls to text/uri-list
Similar to how it's done in the XCB QPA. This format is used by both Firefox and Chrome for exchanging URLs. Change-Id: Icd4406ff6297ea2800f4e1389ffc2878ee1ccb65 Reviewed-by: David Edmundson <davidedmundson@kde.org>
This commit is contained in:
parent
349cb9eb7d
commit
9c1cd44144
@ -20,6 +20,47 @@ static QString utf8Text()
|
|||||||
return QStringLiteral("text/plain;charset=utf-8");
|
return QStringLiteral("text/plain;charset=utf-8");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QString uriList()
|
||||||
|
{
|
||||||
|
return QStringLiteral("text/uri-list");
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString mozUrl()
|
||||||
|
{
|
||||||
|
return QStringLiteral("text/x-moz-url");
|
||||||
|
}
|
||||||
|
|
||||||
|
static QByteArray convertData(const QString &originalMime, const QString &newMime, const QByteArray &data)
|
||||||
|
{
|
||||||
|
if (originalMime == newMime)
|
||||||
|
return data;
|
||||||
|
|
||||||
|
// Convert text/x-moz-url, which is an UTF-16 string of
|
||||||
|
// URL and page title pairs, all separated by line breaks, to text/uri-list.
|
||||||
|
// see also qtbase/src/plugins/platforms/xcb/qxcbmime.cpp
|
||||||
|
if (originalMime == uriList() && newMime == mozUrl()) {
|
||||||
|
if (data.size() > 1) {
|
||||||
|
const QString str = QString::fromUtf16(
|
||||||
|
reinterpret_cast<const char16_t *>(data.constData()), data.size() / 2);
|
||||||
|
if (!str.isNull()) {
|
||||||
|
QByteArray converted;
|
||||||
|
const auto urls = QStringView{str}.split(u'\n');
|
||||||
|
// Only the URL is interesting, skip the page title.
|
||||||
|
for (int i = 0; i < urls.size(); i += 2) {
|
||||||
|
const QUrl url(urls.at(i).trimmed().toString());
|
||||||
|
if (url.isValid()) {
|
||||||
|
converted += url.toEncoded();
|
||||||
|
converted += "\r\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return converted;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
QWaylandDataOffer::QWaylandDataOffer(QWaylandDisplay *display, struct ::wl_data_offer *offer)
|
QWaylandDataOffer::QWaylandDataOffer(QWaylandDisplay *display, struct ::wl_data_offer *offer)
|
||||||
: QtWayland::wl_data_offer(offer)
|
: QtWayland::wl_data_offer(offer)
|
||||||
, m_display(display)
|
, m_display(display)
|
||||||
@ -105,6 +146,9 @@ bool QWaylandMimeData::hasFormat_sys(const QString &mimeType) const
|
|||||||
if (mimeType == QStringLiteral("text/plain") && m_types.contains(utf8Text()))
|
if (mimeType == QStringLiteral("text/plain") && m_types.contains(utf8Text()))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (mimeType == uriList() && m_types.contains(mozUrl()))
|
||||||
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,6 +170,8 @@ QVariant QWaylandMimeData::retrieveData_sys(const QString &mimeType, QMetaType t
|
|||||||
if (!m_types.contains(mimeType)) {
|
if (!m_types.contains(mimeType)) {
|
||||||
if (mimeType == QStringLiteral("text/plain") && m_types.contains(utf8Text()))
|
if (mimeType == QStringLiteral("text/plain") && m_types.contains(utf8Text()))
|
||||||
mime = utf8Text();
|
mime = utf8Text();
|
||||||
|
else if (mimeType == uriList() && m_types.contains(mozUrl()))
|
||||||
|
mime = mozUrl();
|
||||||
else
|
else
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
@ -147,6 +193,9 @@ QVariant QWaylandMimeData::retrieveData_sys(const QString &mimeType, QMetaType t
|
|||||||
}
|
}
|
||||||
|
|
||||||
close(pipefd[0]);
|
close(pipefd[0]);
|
||||||
|
|
||||||
|
content = convertData(mimeType, mime, content);
|
||||||
|
|
||||||
m_data.insert(mimeType, content);
|
m_data.insert(mimeType, content);
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ private slots:
|
|||||||
void initTestCase();
|
void initTestCase();
|
||||||
void pasteAscii();
|
void pasteAscii();
|
||||||
void pasteUtf8();
|
void pasteUtf8();
|
||||||
|
void pasteMozUrl();
|
||||||
void destroysPreviousSelection();
|
void destroysPreviousSelection();
|
||||||
void destroysSelectionWithSurface();
|
void destroysSelectionWithSurface();
|
||||||
void destroysSelectionOnLeave();
|
void destroysSelectionOnLeave();
|
||||||
@ -123,6 +124,49 @@ void tst_datadevicev1::pasteUtf8()
|
|||||||
QTRY_COMPARE(window.m_text, "face with tears of joy: 😂");
|
QTRY_COMPARE(window.m_text, "face with tears of joy: 😂");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_datadevicev1::pasteMozUrl()
|
||||||
|
{
|
||||||
|
class Window : public QRasterWindow {
|
||||||
|
public:
|
||||||
|
void mousePressEvent(QMouseEvent *) override { m_urls = QGuiApplication::clipboard()->mimeData()->urls(); }
|
||||||
|
QList<QUrl> m_urls;
|
||||||
|
};
|
||||||
|
|
||||||
|
Window window;
|
||||||
|
window.resize(64, 64);
|
||||||
|
window.show();
|
||||||
|
|
||||||
|
QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial);
|
||||||
|
exec([&] {
|
||||||
|
auto *client = xdgSurface()->resource()->client();
|
||||||
|
auto *offer = dataDevice()->sendDataOffer(client, {"text/x-moz-url"});
|
||||||
|
connect(offer, &DataOffer::receive, [](QString mimeType, int fd) {
|
||||||
|
QFile file;
|
||||||
|
file.open(fd, QIODevice::WriteOnly, QFile::FileHandleFlag::AutoCloseHandle);
|
||||||
|
QCOMPARE(mimeType, "text/x-moz-url");
|
||||||
|
const QString content("https://www.qt.io/\nQt\nhttps://www.example.com/\nExample Website");
|
||||||
|
// Need UTF-16.
|
||||||
|
file.write(reinterpret_cast<const char *>(content.data()), content.size() * 2);
|
||||||
|
file.close();
|
||||||
|
});
|
||||||
|
dataDevice()->sendSelection(offer);
|
||||||
|
|
||||||
|
auto *surface = xdgSurface()->m_surface;
|
||||||
|
keyboard()->sendEnter(surface); // Need to set keyboard focus according to protocol
|
||||||
|
|
||||||
|
pointer()->sendEnter(surface, {32, 32});
|
||||||
|
pointer()->sendFrame(client);
|
||||||
|
pointer()->sendButton(client, BTN_LEFT, 1);
|
||||||
|
pointer()->sendFrame(client);
|
||||||
|
pointer()->sendButton(client, BTN_LEFT, 0);
|
||||||
|
pointer()->sendFrame(client);
|
||||||
|
});
|
||||||
|
|
||||||
|
QTRY_COMPARE(window.m_urls.count(), 2);
|
||||||
|
QCOMPARE(window.m_urls.at(0), QUrl("https://www.qt.io/"));
|
||||||
|
QCOMPARE(window.m_urls.at(1), QUrl("https://www.example.com/"));
|
||||||
|
}
|
||||||
|
|
||||||
void tst_datadevicev1::destroysPreviousSelection()
|
void tst_datadevicev1::destroysPreviousSelection()
|
||||||
{
|
{
|
||||||
QRasterWindow window;
|
QRasterWindow window;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user