diff --git a/shell/platform/windows/platform_handler_winuwp.cc b/shell/platform/windows/platform_handler_winuwp.cc index e3ea7e5b9566a..f0bc19d0f1efe 100644 --- a/shell/platform/windows/platform_handler_winuwp.cc +++ b/shell/platform/windows/platform_handler_winuwp.cc @@ -4,7 +4,14 @@ #include "flutter/shell/platform/windows/platform_handler_winuwp.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" + +static constexpr char kValueKey[] = "value"; namespace flutter { @@ -21,24 +28,84 @@ PlatformHandlerWinUwp::PlatformHandlerWinUwp(BinaryMessenger* messenger, PlatformHandlerWinUwp::~PlatformHandlerWinUwp() = default; +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) { - // TODO: Implement. See https://github.com/flutter/flutter/issues/70214. - result->NotImplemented(); + // We call `Clipboard::GetContent()` when the application window is in + // focus, otherwise calling this will throw an error. + 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; + 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); + }); } 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( 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