winrt: Fix clipboard
Native implementation was missing and so far it only used the Qt internal fallback mode. Unfortunately this does not apply to Windows Phone 8.1. Task-number: QTBUG-49766 Change-Id: I8cbbb0c843d077d7df1396d673fedeab2799b5a6 Reviewed-by: Oliver Wolff <oliver.wolff@theqtcompany.com>bb10
parent
ad16703fa8
commit
e7a06c9843
|
|
@ -0,0 +1,185 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL3$
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/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 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or later 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 2.0 requirements will be
|
||||
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qwinrtclipboard.h"
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/qfunctions_winrt.h>
|
||||
#include <QtCore/private/qeventdispatcher_winrt_p.h>
|
||||
|
||||
#include <Windows.ApplicationModel.datatransfer.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
using namespace ABI::Windows::ApplicationModel::DataTransfer;
|
||||
using namespace ABI::Windows::Foundation;
|
||||
using namespace Microsoft::WRL;
|
||||
using namespace Microsoft::WRL::Wrappers;
|
||||
|
||||
typedef IEventHandler<IInspectable *> ContentChangedHandler;
|
||||
|
||||
#define RETURN_NULLPTR_IF_FAILED(msg) RETURN_IF_FAILED(msg, return nullptr)
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QWinRTClipboard::QWinRTClipboard()
|
||||
{
|
||||
#ifndef Q_OS_WINPHONE
|
||||
QEventDispatcherWinRT::runOnXamlThread([this]() {
|
||||
HRESULT hr;
|
||||
hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_DataTransfer_Clipboard).Get(),
|
||||
&m_nativeClipBoard);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
|
||||
EventRegistrationToken tok;
|
||||
hr = m_nativeClipBoard->add_ContentChanged(Callback<ContentChangedHandler>(this, &QWinRTClipboard::onContentChanged).Get(), &tok);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
|
||||
return hr;
|
||||
});
|
||||
#endif // !Q_OS_WINPHONE
|
||||
}
|
||||
|
||||
QMimeData *QWinRTClipboard::mimeData(QClipboard::Mode mode)
|
||||
{
|
||||
if (!supportsMode(mode))
|
||||
return nullptr;
|
||||
|
||||
#ifndef Q_OS_WINPHONE
|
||||
ComPtr<IDataPackageView> view;
|
||||
HRESULT hr;
|
||||
hr = m_nativeClipBoard->GetContent(&view);
|
||||
RETURN_NULLPTR_IF_FAILED("Could not get clipboard content.");
|
||||
|
||||
ComPtr<IAsyncOperation<HSTRING>> op;
|
||||
HString result;
|
||||
// This throws a security exception (WinRT originate error / 0x40080201.
|
||||
// Unfortunately there seems to be no way to avoid this, neither
|
||||
// running on the XAML thread, nor some other way. Stack Overflow
|
||||
// confirms this problem since Windows (Phone) 8.0.
|
||||
hr = view->GetTextAsync(&op);
|
||||
RETURN_NULLPTR_IF_FAILED("Could not get clipboard text.");
|
||||
|
||||
hr = QWinRTFunctions::await(op, result.GetAddressOf());
|
||||
RETURN_NULLPTR_IF_FAILED("Could not get clipboard text content");
|
||||
|
||||
quint32 size;
|
||||
const wchar_t *textStr = result.GetRawBuffer(&size);
|
||||
QString text = QString::fromWCharArray(textStr, size);
|
||||
text.replace(QStringLiteral("\r\n"), QStringLiteral("\n"));
|
||||
m_mimeData.setText(text);
|
||||
|
||||
return &m_mimeData;
|
||||
#else // Q_OS_WINPHONE
|
||||
return QPlatformClipboard::mimeData(mode);
|
||||
#endif // Q_OS_WINPHONE
|
||||
}
|
||||
|
||||
// Inspired by QWindowsMimeText::convertFromMime
|
||||
inline QString convertToWindowsLineEnding(const QString &text)
|
||||
{
|
||||
const QChar *u = text.unicode();
|
||||
QString res;
|
||||
const int s = text.length();
|
||||
int maxsize = s + s / 40 + 3;
|
||||
res.resize(maxsize);
|
||||
int ri = 0;
|
||||
bool cr = false;
|
||||
for (int i = 0; i < s; ++i) {
|
||||
if (*u == QLatin1Char('\r'))
|
||||
cr = true;
|
||||
else {
|
||||
if (*u == QLatin1Char('\n') && !cr)
|
||||
res[ri++] = QLatin1Char('\r');
|
||||
cr = false;
|
||||
}
|
||||
res[ri++] = *u;
|
||||
if (ri+3 >= maxsize) {
|
||||
maxsize += maxsize / 4;
|
||||
res.resize(maxsize);
|
||||
}
|
||||
++u;
|
||||
}
|
||||
res.truncate(ri);
|
||||
return res;
|
||||
}
|
||||
|
||||
void QWinRTClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
|
||||
{
|
||||
if (!supportsMode(mode))
|
||||
return;
|
||||
|
||||
#ifndef Q_OS_WINPHONE
|
||||
const QString text = data->text();
|
||||
HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([this, text]() {
|
||||
HRESULT hr;
|
||||
ComPtr<IDataPackage> package;
|
||||
hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_DataTransfer_DataPackage).Get(),
|
||||
&package);
|
||||
|
||||
const QString nativeString = convertToWindowsLineEnding(text);
|
||||
HStringReference textRef(reinterpret_cast<LPCWSTR>(nativeString.utf16()), nativeString.length());
|
||||
|
||||
hr = package->SetText(textRef.Get());
|
||||
RETURN_HR_IF_FAILED("Could not set text to clipboard data package.");
|
||||
|
||||
hr = m_nativeClipBoard->SetContent(package.Get());
|
||||
RETURN_HR_IF_FAILED("Could not set clipboard content.");
|
||||
return S_OK;
|
||||
});
|
||||
RETURN_VOID_IF_FAILED("Could not set clipboard text.");
|
||||
emitChanged(mode);
|
||||
#else // Q_OS_WINPHONE
|
||||
QPlatformClipboard::setMimeData(data, mode);
|
||||
#endif // Q_OS_WINPHONE
|
||||
}
|
||||
|
||||
bool QWinRTClipboard::supportsMode(QClipboard::Mode mode) const
|
||||
{
|
||||
#ifndef Q_OS_WINPHONE
|
||||
return mode == QClipboard::Clipboard;
|
||||
#else
|
||||
return QPlatformClipboard::supportsMode(mode);
|
||||
#endif
|
||||
}
|
||||
|
||||
HRESULT QWinRTClipboard::onContentChanged(IInspectable *, IInspectable *)
|
||||
{
|
||||
emitChanged(QClipboard::Clipboard);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL3$
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/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 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or later 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 2.0 requirements will be
|
||||
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QWINRTPLATFORMCLIPBOARD_H
|
||||
#define QWINRTPLATFORMCLIPBOARD_H
|
||||
|
||||
#include <qpa/qplatformclipboard.h>
|
||||
#include <QMimeData>
|
||||
|
||||
#include <wrl.h>
|
||||
|
||||
#ifndef Q_OS_WINPHONE
|
||||
namespace ABI {
|
||||
namespace Windows {
|
||||
namespace ApplicationModel {
|
||||
namespace DataTransfer {
|
||||
struct IClipboardStatics;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // !Q_OS_WINPHONE
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QWinRTClipboard: public QPlatformClipboard
|
||||
{
|
||||
public:
|
||||
QWinRTClipboard();
|
||||
|
||||
QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE;
|
||||
void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE;
|
||||
bool supportsMode(QClipboard::Mode mode) const Q_DECL_OVERRIDE;
|
||||
|
||||
HRESULT onContentChanged(IInspectable *, IInspectable *);
|
||||
private:
|
||||
#ifndef Q_OS_WINPHONE
|
||||
Microsoft::WRL::ComPtr<ABI::Windows::ApplicationModel::DataTransfer::IClipboardStatics> m_nativeClipBoard;
|
||||
#endif
|
||||
QMimeData m_mimeData;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QWINRTPLATFORMCLIPBOARD_H
|
||||
|
|
@ -44,6 +44,7 @@
|
|||
#include "qwinrteglcontext.h"
|
||||
#include "qwinrtfontdatabase.h"
|
||||
#include "qwinrttheme.h"
|
||||
#include "qwinrtclipboard.h"
|
||||
|
||||
#include <QtGui/QOffscreenSurface>
|
||||
#include <QtGui/QOpenGLContext>
|
||||
|
|
@ -111,6 +112,7 @@ class QWinRTIntegrationPrivate
|
|||
public:
|
||||
QPlatformFontDatabase *fontDatabase;
|
||||
QPlatformServices *platformServices;
|
||||
QPlatformClipboard *clipboard;
|
||||
QWinRTScreen *mainScreen;
|
||||
QScopedPointer<QWinRTInputContext> inputContext;
|
||||
|
||||
|
|
@ -195,6 +197,7 @@ QWinRTIntegration::QWinRTIntegration() : d_ptr(new QWinRTIntegrationPrivate)
|
|||
|
||||
screenAdded(d->mainScreen);
|
||||
d->platformServices = new QWinRTServices;
|
||||
d->clipboard = new QWinRTClipboard;
|
||||
}
|
||||
|
||||
QWinRTIntegration::~QWinRTIntegration()
|
||||
|
|
@ -300,6 +303,12 @@ QPlatformServices *QWinRTIntegration::services() const
|
|||
return d->platformServices;
|
||||
}
|
||||
|
||||
QPlatformClipboard *QWinRTIntegration::clipboard() const
|
||||
{
|
||||
Q_D(const QWinRTIntegration);
|
||||
return d->clipboard;
|
||||
}
|
||||
|
||||
Qt::KeyboardModifiers QWinRTIntegration::queryKeyboardModifiers() const
|
||||
{
|
||||
Q_D(const QWinRTIntegration);
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ public:
|
|||
QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE;
|
||||
QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE;
|
||||
QPlatformServices *services() const Q_DECL_OVERRIDE;
|
||||
QPlatformClipboard *clipboard() const Q_DECL_OVERRIDE;
|
||||
Qt::KeyboardModifiers queryKeyboardModifiers() const Q_DECL_OVERRIDE;
|
||||
|
||||
QStringList themeNames() const Q_DECL_OVERRIDE;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/freetype/include
|
|||
SOURCES = \
|
||||
main.cpp \
|
||||
qwinrtbackingstore.cpp \
|
||||
qwinrtclipboard.cpp \
|
||||
qwinrtcursor.cpp \
|
||||
qwinrteglcontext.cpp \
|
||||
qwinrteventdispatcher.cpp \
|
||||
|
|
@ -33,6 +34,7 @@ SOURCES = \
|
|||
|
||||
HEADERS = \
|
||||
qwinrtbackingstore.h \
|
||||
qwinrtclipboard.h \
|
||||
qwinrtcursor.h \
|
||||
qwinrteglcontext.h \
|
||||
qwinrteventdispatcher.h \
|
||||
|
|
|
|||
Loading…
Reference in New Issue