From e23a10e0df9c26b2da77ab4a61b5e617d58172cb Mon Sep 17 00:00:00 2001 From: moko256 Date: Fri, 13 Aug 2021 15:56:27 +0900 Subject: [PATCH 1/4] [WinUWP] Implement clipboard handler. --- .../windows/platform_handler_winuwp.cc | 52 +++++++++++++++++-- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/shell/platform/windows/platform_handler_winuwp.cc b/shell/platform/windows/platform_handler_winuwp.cc index e3ea7e5b9566a..e158c331b3e92 100644 --- a/shell/platform/windows/platform_handler_winuwp.cc +++ b/shell/platform/windows/platform_handler_winuwp.cc @@ -4,8 +4,12 @@ #include "flutter/shell/platform/windows/platform_handler_winuwp.h" -#include "flutter/shell/platform/windows/flutter_windows_view.h" +#include "third_party/cppwinrt/generated/winrt/Windows.ApplicationModel.DataTransfer.h" +#include "third_party/cppwinrt/generated/winrt/Windows.Foundation.h" +#include "third_party/cppwinrt/generated/winrt/Windows.UI.Core.h" +#include "flutter/shell/platform/windows/flutter_windows_view.h" +#include "flutter/shell/platform/windows/string_conversion.h" namespace flutter { // static @@ -24,8 +28,42 @@ PlatformHandlerWinUwp::~PlatformHandlerWinUwp() = default; void PlatformHandlerWinUwp::GetPlainText( std::unique_ptr> result, std::string_view key) { - // TODO: Implement. See https://github.com/flutter/flutter/issues/70214. - result->NotImplemented(); + auto activation_mode = + winrt::Windows::UI::Core::CoreWindow::GetForCurrentThread() + .ActivationMode(); + // We call `Clipboard::GetContent()` when the application window is in + // focus, otherwise calling this will throw an error. + if (activation_mode == winrt::Windows::UI::Core::CoreWindowActivationMode:: + ActivatedInForeground) { + auto content = + winrt::Windows::ApplicationModel::DataTransfer::Clipboard::GetContent(); + // Calling `DataPackageView::GetTextAsync()` when the clipboard has no text + // content will throw an error. + if (content.Contains(winrt::Windows::ApplicationModel::DataTransfer:: + StandardDataFormats::Text())) { + // Waiting `DataPackageView::GetTextAsync()` using `TResult.get()` on the + // platform thread will causes the application stop, so we continue + // response on this callback. + content.GetTextAsync().Completed([result = std::move(result), key]( + auto async_info, + auto _async_status) { + auto clipboard_string = async_info.GetResults(); + + rapidjson::Document document; + document.SetObject(); + rapidjson::Document::AllocatorType& allocator = document.GetAllocator(); + document.AddMember( + rapidjson::Value(key.data(), allocator), + rapidjson::Value(Utf8FromUtf16(clipboard_string), allocator), + allocator); + result->Success(document); + }); + } else { + result->Success(rapidjson::Document()); + } + } else { + result->Success(rapidjson::Document()); + } } void PlatformHandlerWinUwp::GetHasStrings( @@ -37,8 +75,12 @@ void PlatformHandlerWinUwp::GetHasStrings( void PlatformHandlerWinUwp::SetPlainText( const std::string& text, std::unique_ptr> result) { - // TODO: Implement. See https://github.com/flutter/flutter/issues/70214. - result->NotImplemented(); + winrt::Windows::ApplicationModel::DataTransfer::DataPackage content; + content.SetText(Utf16FromUtf8(text)); + winrt::Windows::ApplicationModel::DataTransfer::Clipboard::SetContent( + content); + + result->Success(); } } // namespace flutter From 6e9e43b96806cc5c2ececb04912cae9ddc196a5f Mon Sep 17 00:00:00 2001 From: moko256 Date: Fri, 27 Aug 2021 13:02:17 +0900 Subject: [PATCH 2/4] implement GetHasString for winuwp --- .../windows/platform_handler_winuwp.cc | 36 +++++++++++++++---- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/shell/platform/windows/platform_handler_winuwp.cc b/shell/platform/windows/platform_handler_winuwp.cc index e158c331b3e92..85feb383cf24b 100644 --- a/shell/platform/windows/platform_handler_winuwp.cc +++ b/shell/platform/windows/platform_handler_winuwp.cc @@ -10,6 +10,9 @@ #include "flutter/shell/platform/windows/flutter_windows_view.h" #include "flutter/shell/platform/windows/string_conversion.h" + +static constexpr char kValueKey[] = "value"; + namespace flutter { // static @@ -25,16 +28,20 @@ PlatformHandlerWinUwp::PlatformHandlerWinUwp(BinaryMessenger* messenger, PlatformHandlerWinUwp::~PlatformHandlerWinUwp() = default; -void PlatformHandlerWinUwp::GetPlainText( - std::unique_ptr> result, - std::string_view key) { +bool isWindowInForeground() { auto activation_mode = winrt::Windows::UI::Core::CoreWindow::GetForCurrentThread() .ActivationMode(); + return activation_mode == winrt::Windows::UI::Core::CoreWindowActivationMode:: + ActivatedInForeground; +} + +void PlatformHandlerWinUwp::GetPlainText( + std::unique_ptr> result, + std::string_view key) { // We call `Clipboard::GetContent()` when the application window is in // focus, otherwise calling this will throw an error. - if (activation_mode == winrt::Windows::UI::Core::CoreWindowActivationMode:: - ActivatedInForeground) { + if (isWindowInForeground()) { auto content = winrt::Windows::ApplicationModel::DataTransfer::Clipboard::GetContent(); // Calling `DataPackageView::GetTextAsync()` when the clipboard has no text @@ -68,8 +75,23 @@ void PlatformHandlerWinUwp::GetPlainText( void PlatformHandlerWinUwp::GetHasStrings( std::unique_ptr> result) { - // TODO: Implement. See https://github.com/flutter/flutter/issues/70214. - result->NotImplemented(); + bool has_string = false; + + // We call `Clipboard::GetContent()` when the application window is in + // focus, otherwise calling this will throw an error. + if (isWindowInForeground()) { + has_string = + winrt::Windows::ApplicationModel::DataTransfer::Clipboard::GetContent() + .Contains(winrt::Windows::ApplicationModel::DataTransfer:: + StandardDataFormats::Text()); + } + + rapidjson::Document document; + document.SetObject(); + rapidjson::Document::AllocatorType& allocator = document.GetAllocator(); + document.AddMember(rapidjson::Value(kValueKey, allocator), + rapidjson::Value(has_string), allocator); + result->Success(document); } void PlatformHandlerWinUwp::SetPlainText( From 26ca58d146c1d58cf2b62fe9361b3c97c984b578 Mon Sep 17 00:00:00 2001 From: moko256 Date: Fri, 10 Sep 2021 17:57:31 +0900 Subject: [PATCH 3/4] throw error if app window is not focusd when reading clipboard in winuwp --- shell/platform/windows/platform_handler_winuwp.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shell/platform/windows/platform_handler_winuwp.cc b/shell/platform/windows/platform_handler_winuwp.cc index 85feb383cf24b..39c2e77d284d1 100644 --- a/shell/platform/windows/platform_handler_winuwp.cc +++ b/shell/platform/windows/platform_handler_winuwp.cc @@ -69,7 +69,8 @@ void PlatformHandlerWinUwp::GetPlainText( result->Success(rapidjson::Document()); } } else { - result->Success(rapidjson::Document()); + result->Error(kClipboardError, + "Unable to read clipboard. The window is not focused."); } } From 4ac26a2c8493222f4a418431a9293f0da247b806 Mon Sep 17 00:00:00 2001 From: moko256 Date: Tue, 28 Sep 2021 02:19:44 +0900 Subject: [PATCH 4/4] use fast-return if condition and make conditions closer to comments --- .../windows/platform_handler_winuwp.cc | 42 ++++++++++--------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/shell/platform/windows/platform_handler_winuwp.cc b/shell/platform/windows/platform_handler_winuwp.cc index 39c2e77d284d1..f0bc19d0f1efe 100644 --- a/shell/platform/windows/platform_handler_winuwp.cc +++ b/shell/platform/windows/platform_handler_winuwp.cc @@ -41,19 +41,28 @@ void PlatformHandlerWinUwp::GetPlainText( std::string_view key) { // We call `Clipboard::GetContent()` when the application window is in // focus, otherwise calling this will throw an error. - if (isWindowInForeground()) { - auto content = - winrt::Windows::ApplicationModel::DataTransfer::Clipboard::GetContent(); - // Calling `DataPackageView::GetTextAsync()` when the clipboard has no text - // content will throw an error. - if (content.Contains(winrt::Windows::ApplicationModel::DataTransfer:: - StandardDataFormats::Text())) { - // Waiting `DataPackageView::GetTextAsync()` using `TResult.get()` on the - // platform thread will causes the application stop, so we continue - // response on this callback. - content.GetTextAsync().Completed([result = std::move(result), key]( - auto async_info, - auto _async_status) { + if (!isWindowInForeground()) { + result->Error(kClipboardError, + "Unable to read clipboard. The window is not focused."); + return; + } + + auto content = + winrt::Windows::ApplicationModel::DataTransfer::Clipboard::GetContent(); + + // Calling `DataPackageView::GetTextAsync()` when the clipboard has no text + // content will throw an error. + if (!content.Contains(winrt::Windows::ApplicationModel::DataTransfer:: + StandardDataFormats::Text())) { + result->Success(rapidjson::Document()); + return; + } + + // Waiting `DataPackageView::GetTextAsync()` using `TResult.get()` on the + // platform thread will causes the application stop, so we continue + // response on this callback. + content.GetTextAsync().Completed( + [result = std::move(result), key](auto async_info, auto _async_status) { auto clipboard_string = async_info.GetResults(); rapidjson::Document document; @@ -65,13 +74,6 @@ void PlatformHandlerWinUwp::GetPlainText( allocator); result->Success(document); }); - } else { - result->Success(rapidjson::Document()); - } - } else { - result->Error(kClipboardError, - "Unable to read clipboard. The window is not focused."); - } } void PlatformHandlerWinUwp::GetHasStrings(