From bfbf63cc3293f15622d069778fd0283c6f84b12b Mon Sep 17 00:00:00 2001 From: Di Da Date: Fri, 15 Nov 2019 16:31:14 -0800 Subject: [PATCH 1/4] Support keyboardDismissMode on-drag for ScrollView --- vnext/ReactUWP/Utils/Helpers.cpp | 9 +++ vnext/ReactUWP/Utils/Helpers.h | 1 + vnext/ReactUWP/Views/ReactControl.cpp | 1 + vnext/ReactUWP/Views/SIPEventHandler.cpp | 90 ++++++++++++++++------ vnext/ReactUWP/Views/SIPEventHandler.h | 15 +++- vnext/ReactUWP/Views/ScrollViewManager.cpp | 39 +++++++++- 6 files changed, 129 insertions(+), 26 deletions(-) diff --git a/vnext/ReactUWP/Utils/Helpers.cpp b/vnext/ReactUWP/Utils/Helpers.cpp index c6919e0b697..5d62f56d090 100644 --- a/vnext/ReactUWP/Utils/Helpers.cpp +++ b/vnext/ReactUWP/Utils/Helpers.cpp @@ -62,8 +62,17 @@ bool IsAPIContractV6Available() { return IsAPIContractVxAvailable<6>(); } +bool IsAPIContractV8Available() { + return IsAPIContractVxAvailable<8>(); +} + bool IsRS4OrHigher() { return IsAPIContractV6Available(); } + +bool Is19H1OrHigher() { + return IsAPIContractV8Available(); +} + } // namespace uwp }; // namespace react diff --git a/vnext/ReactUWP/Utils/Helpers.h b/vnext/ReactUWP/Utils/Helpers.h index 50c46a234b3..77e0635ca64 100644 --- a/vnext/ReactUWP/Utils/Helpers.h +++ b/vnext/ReactUWP/Utils/Helpers.h @@ -31,5 +31,6 @@ ReactId getViewId(_In_ IReactInstance *instance, winrt::FrameworkElement const & std::int32_t CountOpenPopups(); bool IsRS4OrHigher(); +bool Is19H1OrHigher(); } // namespace uwp } // namespace react diff --git a/vnext/ReactUWP/Views/ReactControl.cpp b/vnext/ReactUWP/Views/ReactControl.cpp index f950020c90e..80754f3d4f9 100644 --- a/vnext/ReactUWP/Views/ReactControl.cpp +++ b/vnext/ReactUWP/Views/ReactControl.cpp @@ -203,6 +203,7 @@ void ReactControl::AttachRoot() noexcept { m_touchEventHandler->AddTouchHandlers(m_xamlRootView); m_previewKeyboardEventHandlerOnRoot->hook(m_xamlRootView); + m_SIPEventHandler->AttachView(m_xamlRootView, true /*fireKeyboradEvents*/); auto initialProps = m_initialProps; m_reactInstance->AttachMeasuredRootView(m_pParent, std::move(initialProps)); diff --git a/vnext/ReactUWP/Views/SIPEventHandler.cpp b/vnext/ReactUWP/Views/SIPEventHandler.cpp index f3c7ec7c4b3..6e26f4f1272 100644 --- a/vnext/ReactUWP/Views/SIPEventHandler.cpp +++ b/vnext/ReactUWP/Views/SIPEventHandler.cpp @@ -7,6 +7,7 @@ #include +#include #include #include @@ -20,38 +21,79 @@ namespace react { namespace uwp { SIPEventHandler::SIPEventHandler(const std::weak_ptr &reactInstance) - : m_wkReactInstance(reactInstance) { - auto coreInputView = winrt::CoreInputView::GetForCurrentView(); - if (coreInputView) { - m_occlusionsChanged_revoker = coreInputView.OcclusionsChanged( - winrt::auto_revoke, [=](auto &&, const winrt::CoreInputViewOcclusionsChangedEventArgs &e) { + : m_wkReactInstance(reactInstance), m_fireKeyboradEvents(false){}; + +SIPEventHandler::~SIPEventHandler() { + m_occlusionsChanged_revoker = {}; +} + +void SIPEventHandler::AttachView(XamlView xamlView, bool fireKeyboardEvents) { + m_fireKeyboradEvents = fireKeyboardEvents; + + if (Is19H1OrHigher()) { + // 19H1 and higher supports island scenarios + auto uiElement(xamlView.as()); + m_coreInputView = winrt::CoreInputView::GetForUIContext(uiElement.UIContext()); + } else { + m_coreInputView = winrt::CoreInputView::GetForCurrentView(); + } + + if (m_coreInputView) { + auto occlusions = m_coreInputView.GetCoreInputViewOcclusions(); + m_isShowing = !IsOcclusionsEmpty(occlusions); + m_occlusionsChanged_revoker = m_coreInputView.OcclusionsChanged( + winrt::auto_revoke, [this](auto &&, const winrt::CoreInputViewOcclusionsChangedEventArgs &e) { if (!e.Handled()) { - winrt::Rect finalRect = winrt::RectHelper::Empty(); - winrt::IVectorView occlusions = e.Occlusions(); - for (uint32_t i = 0; i < occlusions.Size(); i++) { - winrt::CoreInputViewOcclusion occlusion = occlusions.GetAt(i); - if (occlusion.OcclusionKind() == winrt::CoreInputViewOcclusionKind::Docked) { - finalRect = winrt::RectHelper::Union(finalRect, occlusion.OccludingRect()); + bool wasShowing = m_isShowing; + m_isShowing = !IsOcclusionsEmpty(e.Occlusions()); + if (wasShowing != m_isShowing && m_fireKeyboradEvents) { + if (!m_isShowing) { + folly::dynamic params = folly::dynamic::object("screenY", 0)("screenX", 0)("width", 0)("height", 0); + SendEvent("keyboardDidHide", std::move(params)); + } else { + folly::dynamic params = folly::dynamic::object( + "endCoordinates", + folly::dynamic::object("screenY", m_finalRect.Y)("screenX", m_finalRect.X)( + "width", m_finalRect.Width)("height", m_finalRect.Height)); + SendEvent("keyboardDidShow", std::move(params)); } } - - if (winrt::RectHelper::GetIsEmpty(finalRect)) { - folly::dynamic params = folly::dynamic::object("screenY", 0)("screenX", 0)("width", 0)("height", 0); - SendEvent("keyboardDidHide", std::move(params)); - } else { - folly::dynamic params = folly::dynamic::object( - "endCoordinates", - folly::dynamic::object("screenY", finalRect.Y)("screenX", finalRect.X)("width", finalRect.Width)( - "height", finalRect.Height)); - SendEvent("keyboardDidShow", std::move(params)); - } } }); } } -SIPEventHandler::~SIPEventHandler() { - m_occlusionsChanged_revoker = {}; +bool SIPEventHandler::TryShow() { + if (m_coreInputView == nullptr) { + return false; + } + if (!m_isShowing) { + return m_coreInputView.TryShow(); + } + return true; +} + +bool SIPEventHandler::TryHide() { + if (m_coreInputView == nullptr) { + return false; + } + if (m_isShowing) { + return m_coreInputView.TryHide(); + } + return true; +} + +bool SIPEventHandler::IsOcclusionsEmpty(winrt::IVectorView occlusions) { + m_finalRect = winrt::RectHelper::Empty(); + + for (uint32_t i = 0; i < occlusions.Size(); i++) { + winrt::CoreInputViewOcclusion occlusion = occlusions.GetAt(i); + if (occlusion.OcclusionKind() == winrt::CoreInputViewOcclusionKind::Docked) { + m_finalRect = winrt::RectHelper::Union(m_finalRect, occlusion.OccludingRect()); + } + } + + return (winrt::RectHelper::GetIsEmpty(m_finalRect)); } void SIPEventHandler::SendEvent(std::string &&eventName, folly::dynamic &¶meters) { diff --git a/vnext/ReactUWP/Views/SIPEventHandler.h b/vnext/ReactUWP/Views/SIPEventHandler.h index 142bd258f55..930f29321b7 100644 --- a/vnext/ReactUWP/Views/SIPEventHandler.h +++ b/vnext/ReactUWP/Views/SIPEventHandler.h @@ -8,7 +8,7 @@ #include namespace winrt { -using namespace Windows::Foundation; +using namespace Windows::Foundation::Collections; using namespace Windows::UI::ViewManagement::Core; } // namespace winrt @@ -20,10 +20,23 @@ class SIPEventHandler { SIPEventHandler(const std::weak_ptr &reactInstance); virtual ~SIPEventHandler(); + bool IsSIPShowing() { + return m_isShowing; + } + + void AttachView(XamlView xamlView, bool fireKeyboardEvents); + bool TryShow(); + bool TryHide(); + private: + bool IsOcclusionsEmpty(winrt::IVectorView occlusions); void SendEvent(std::string &&eventName, folly::dynamic &¶meters); std::weak_ptr m_wkReactInstance; winrt::CoreInputView::OcclusionsChanged_revoker m_occlusionsChanged_revoker; + winrt::Rect m_finalRect; + winrt::CoreInputView m_coreInputView = nullptr; + bool m_isShowing = false; + bool m_fireKeyboradEvents; }; } // namespace uwp diff --git a/vnext/ReactUWP/Views/ScrollViewManager.cpp b/vnext/ReactUWP/Views/ScrollViewManager.cpp index 80cbd684bb0..2377c0f9eb8 100644 --- a/vnext/ReactUWP/Views/ScrollViewManager.cpp +++ b/vnext/ReactUWP/Views/ScrollViewManager.cpp @@ -3,6 +3,7 @@ #include "pch.h" +#include #include #include "Impl/ScrollViewUWPImplementation.h" #include "ScrollViewManager.h" @@ -20,6 +21,7 @@ class ScrollViewShadowNode : public ShadowNodeBase { public: ScrollViewShadowNode(); + ~ScrollViewShadowNode(); void dispatchCommand(int64_t commandId, const folly::dynamic &commandArgs) override; void createView() override; void updateProperties(const folly::dynamic &&props) override; @@ -44,6 +46,10 @@ class ScrollViewShadowNode : public ShadowNodeBase { bool m_isHorizontal = false; bool m_isScrollingEnabled = true; bool m_changeViewAfterLoaded = false; + bool m_dismissKeyboardOnDrag = false; + + std::shared_ptr m_SIPEventHandler; + void RegisterSIPEventsWhenNeeded(); winrt::FrameworkElement::SizeChanged_revoker m_scrollViewerSizeChangedRevoker{}; winrt::FrameworkElement::SizeChanged_revoker m_contentSizeChangedRevoker{}; @@ -56,6 +62,10 @@ class ScrollViewShadowNode : public ShadowNodeBase { ScrollViewShadowNode::ScrollViewShadowNode() {} +ScrollViewShadowNode::~ScrollViewShadowNode() { + m_SIPEventHandler.reset(); +} + void ScrollViewShadowNode::dispatchCommand(int64_t commandId, const folly::dynamic &commandArgs) { const auto scrollViewer = GetView().as(); if (scrollViewer == nullptr) @@ -186,6 +196,12 @@ void ScrollViewShadowNode::updateProperties(const folly::dynamic &&reactDiffMap) if (valid) { ScrollViewUWPImplementation(scrollViewer).SnapToEnd(snapToEnd); } + } else if (propertyName == "keyboardDismissMode") { + m_dismissKeyboardOnDrag = false; + if (propertyValue.isString()) { + m_dismissKeyboardOnDrag = (propertyValue.getString() == "on-drag"); + RegisterSIPEventsWhenNeeded(); + } } else if (propertyName == "snapToAlignment") { const auto [valid, snapToAlignment] = getPropertyAndValidity(propertyValue, winrt::SnapPointsAlignment::Near); if (valid) { @@ -236,6 +252,13 @@ void ScrollViewShadowNode::AddHandlers(const winrt::ScrollViewer &scrollViewer) m_scrollViewerDirectManipulationStartedRevoker = scrollViewer.DirectManipulationStarted(winrt::auto_revoke, [this](const auto &sender, const auto &) { m_isScrolling = true; + + if (m_dismissKeyboardOnDrag) { + if (m_SIPEventHandler) { + m_SIPEventHandler->TryHide(); + } + } + const auto scrollViewer = sender.as(); EmitScrollEvent( scrollViewer, @@ -271,6 +294,8 @@ void ScrollViewShadowNode::AddHandlers(const winrt::ScrollViewer &scrollViewer) m_isScrollingFromInertia = false; }); m_controlLoadedRevoker = scrollViewer.Loaded(winrt::auto_revoke, [this](const auto &sender, const auto &) { + RegisterSIPEventsWhenNeeded(); + if (m_changeViewAfterLoaded) { const auto scrollViewer = sender.as(); scrollViewer.ChangeView(nullptr, nullptr, static_cast(m_zoomFactor)); @@ -279,6 +304,17 @@ void ScrollViewShadowNode::AddHandlers(const winrt::ScrollViewer &scrollViewer) }); } +void ScrollViewShadowNode::RegisterSIPEventsWhenNeeded() { + if (m_dismissKeyboardOnDrag) { + auto view = GetView(); + if (winrt::VisualTreeHelper::GetParent(view) != nullptr) { + auto wkinstance = GetViewManager()->GetReactInstance(); + m_SIPEventHandler = std::make_unique(wkinstance); + m_SIPEventHandler->AttachView(GetView(), false /*fireKeyboardEvents*/); + } + } +} // namespace uwp + void ScrollViewShadowNode::EmitScrollEvent( const winrt::ScrollViewer &scrollViewer, int64_t tag, @@ -396,7 +432,8 @@ folly::dynamic ScrollViewManager::GetNativeProps() const { props.update(folly::dynamic::object("horizontal", "boolean")("scrollEnabled", "boolean")( "showsHorizontalScrollIndicator", "boolean")("showsVerticalScrollIndicator", "boolean")( "minimumZoomScale", "float")("maximumZoomScale", "float")("zoomScale", "float")("snapToInterval", "float")( - "snapToOffsets", "array")("snapToAlignment", "number")("snapToStart", "boolean")("snapToEnd", "boolean")); + "snapToOffsets", "array")("snapToAlignment", "number")("snapToStart", "boolean")("snapToEnd", "boolean")( + "keyboardDismissMode", "string")); return props; } From f2d23efaf5418b7912542dd8f74b756c5f049bb8 Mon Sep 17 00:00:00 2001 From: Di Da Date: Fri, 15 Nov 2019 16:31:58 -0800 Subject: [PATCH 2/4] Change files --- ...e-windows-2019-11-15-16-31-57-keyboardDismissMode.json | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 change/react-native-windows-2019-11-15-16-31-57-keyboardDismissMode.json diff --git a/change/react-native-windows-2019-11-15-16-31-57-keyboardDismissMode.json b/change/react-native-windows-2019-11-15-16-31-57-keyboardDismissMode.json new file mode 100644 index 00000000000..32ebe6f5fb8 --- /dev/null +++ b/change/react-native-windows-2019-11-15-16-31-57-keyboardDismissMode.json @@ -0,0 +1,8 @@ +{ + "type": "prerelease", + "comment": "Support keyboardDismissMode on-drag for ScrollView", + "packageName": "react-native-windows", + "email": "dida@ntdev.microsoft.com", + "commit": "bfbf63cc3293f15622d069778fd0283c6f84b12b", + "date": "2019-11-16T00:31:57.734Z" +} \ No newline at end of file From a612f13a97d7f6687d15277e54b8d3c97fdd63f2 Mon Sep 17 00:00:00 2001 From: Di Da Date: Wed, 20 Nov 2019 10:43:02 -0800 Subject: [PATCH 3/4] Address PR comments and fix two crash --- vnext/ReactUWP/Utils/Helpers.cpp | 16 +++++++ vnext/ReactUWP/Utils/Helpers.h | 2 + vnext/ReactUWP/Views/KeyboardEventHandler.cpp | 10 +++-- vnext/ReactUWP/Views/SIPEventHandler.cpp | 44 +++++++++++-------- vnext/ReactUWP/Views/SIPEventHandler.h | 4 +- 5 files changed, 51 insertions(+), 25 deletions(-) diff --git a/vnext/ReactUWP/Utils/Helpers.cpp b/vnext/ReactUWP/Utils/Helpers.cpp index 5d62f56d090..cbcb19c448a 100644 --- a/vnext/ReactUWP/Utils/Helpers.cpp +++ b/vnext/ReactUWP/Utils/Helpers.cpp @@ -58,18 +58,34 @@ bool IsAPIContractVxAvailable() { return isAPIContractVxAvailable; } +bool IsAPIContractV5Available() { + return IsAPIContractVxAvailable<5>(); +} + bool IsAPIContractV6Available() { return IsAPIContractVxAvailable<6>(); } +bool IsAPIContractV7Available() { + return IsAPIContractVxAvailable<7>(); +} + bool IsAPIContractV8Available() { return IsAPIContractVxAvailable<8>(); } +bool IsRS3OrHigher() { + return IsAPIContractV5Available(); +} + bool IsRS4OrHigher() { return IsAPIContractV6Available(); } +bool IsRS5OrHigher() { + return IsAPIContractV7Available(); +} + bool Is19H1OrHigher() { return IsAPIContractV8Available(); } diff --git a/vnext/ReactUWP/Utils/Helpers.h b/vnext/ReactUWP/Utils/Helpers.h index 77e0635ca64..ad12e1a9ee6 100644 --- a/vnext/ReactUWP/Utils/Helpers.h +++ b/vnext/ReactUWP/Utils/Helpers.h @@ -30,7 +30,9 @@ inline typename T asEnum(folly::dynamic const &obj) { ReactId getViewId(_In_ IReactInstance *instance, winrt::FrameworkElement const &fe); std::int32_t CountOpenPopups(); +bool IsRS3OrHigher(); bool IsRS4OrHigher(); +bool IsRS5OrHigher(); bool Is19H1OrHigher(); } // namespace uwp } // namespace react diff --git a/vnext/ReactUWP/Views/KeyboardEventHandler.cpp b/vnext/ReactUWP/Views/KeyboardEventHandler.cpp index c385a01a550..0e9f8bcc5f2 100644 --- a/vnext/ReactUWP/Views/KeyboardEventHandler.cpp +++ b/vnext/ReactUWP/Views/KeyboardEventHandler.cpp @@ -68,11 +68,13 @@ PreviewKeyboardEventHandler::PreviewKeyboardEventHandler(KeyboardEventCallback & void PreviewKeyboardEventHandler::hook(XamlView xamlView) { auto uiElement = xamlView.as(); - if (m_keyDownCallback) - m_previewKeyDownRevoker = uiElement.PreviewKeyDown(winrt::auto_revoke, m_keyDownCallback); + if (uiElement.try_as()) { + if (m_keyDownCallback) + m_previewKeyDownRevoker = uiElement.PreviewKeyDown(winrt::auto_revoke, m_keyDownCallback); - if (m_keyUpCallback) - m_previewKeyUpRevoker = uiElement.PreviewKeyUp(winrt::auto_revoke, m_keyUpCallback); + if (m_keyUpCallback) + m_previewKeyUpRevoker = uiElement.PreviewKeyUp(winrt::auto_revoke, m_keyUpCallback); + } } void PreviewKeyboardEventHandler::unhook() { diff --git a/vnext/ReactUWP/Views/SIPEventHandler.cpp b/vnext/ReactUWP/Views/SIPEventHandler.cpp index 6e26f4f1272..06b8cab8f3b 100644 --- a/vnext/ReactUWP/Views/SIPEventHandler.cpp +++ b/vnext/ReactUWP/Views/SIPEventHandler.cpp @@ -21,15 +21,21 @@ namespace react { namespace uwp { SIPEventHandler::SIPEventHandler(const std::weak_ptr &reactInstance) - : m_wkReactInstance(reactInstance), m_fireKeyboradEvents(false){}; + : m_wkReactInstance(reactInstance), m_fireKeyboradEvents(false), m_finalRect(winrt::RectHelper::Empty()){}; SIPEventHandler::~SIPEventHandler() { m_occlusionsChanged_revoker = {}; } +// keyboardDidHide and keyboardDidShow events works on >= RS3 +// TryShow and TryHide works on >= RS5 void SIPEventHandler::AttachView(XamlView xamlView, bool fireKeyboardEvents) { m_fireKeyboradEvents = fireKeyboardEvents; + if (!IsRS3OrHigher()) { + return; // CoreInputView is only supported on >= RS3. + } + if (Is19H1OrHigher()) { // 19H1 and higher supports island scenarios auto uiElement(xamlView.as()); @@ -64,35 +70,35 @@ void SIPEventHandler::AttachView(XamlView xamlView, bool fireKeyboardEvents) { } bool SIPEventHandler::TryShow() { - if (m_coreInputView == nullptr) { - return false; - } - if (!m_isShowing) { - return m_coreInputView.TryShow(); + if (IsRS5OrHigher() && m_coreInputView) { + if (!m_isShowing) { // CoreInputView.TryShow is only avaliable after RS5 + return m_coreInputView.TryShow(); + } + return true; } - return true; + return false; } bool SIPEventHandler::TryHide() { - if (m_coreInputView == nullptr) { - return false; - } - if (m_isShowing) { - return m_coreInputView.TryHide(); + if (IsRS5OrHigher() && m_coreInputView) { + if (m_isShowing) { // CoreInputView.TryHide is only avaliable after RS5 + return m_coreInputView.TryHide(); + } + return true; } - return true; + return false; } bool SIPEventHandler::IsOcclusionsEmpty(winrt::IVectorView occlusions) { m_finalRect = winrt::RectHelper::Empty(); - - for (uint32_t i = 0; i < occlusions.Size(); i++) { - winrt::CoreInputViewOcclusion occlusion = occlusions.GetAt(i); - if (occlusion.OcclusionKind() == winrt::CoreInputViewOcclusionKind::Docked) { - m_finalRect = winrt::RectHelper::Union(m_finalRect, occlusion.OccludingRect()); + if (occlusions) { + for (uint32_t i = 0; i < occlusions.Size(); i++) { + winrt::CoreInputViewOcclusion occlusion = occlusions.GetAt(i); + if (occlusion.OcclusionKind() == winrt::CoreInputViewOcclusionKind::Docked) { + m_finalRect = winrt::RectHelper::Union(m_finalRect, occlusion.OccludingRect()); + } } } - return (winrt::RectHelper::GetIsEmpty(m_finalRect)); } diff --git a/vnext/ReactUWP/Views/SIPEventHandler.h b/vnext/ReactUWP/Views/SIPEventHandler.h index 930f29321b7..eea7ca49789 100644 --- a/vnext/ReactUWP/Views/SIPEventHandler.h +++ b/vnext/ReactUWP/Views/SIPEventHandler.h @@ -34,8 +34,8 @@ class SIPEventHandler { std::weak_ptr m_wkReactInstance; winrt::CoreInputView::OcclusionsChanged_revoker m_occlusionsChanged_revoker; winrt::Rect m_finalRect; - winrt::CoreInputView m_coreInputView = nullptr; - bool m_isShowing = false; + winrt::CoreInputView m_coreInputView{nullptr}; + bool m_isShowing{false}; bool m_fireKeyboradEvents; }; From 2cfce01593be065082972e5f3033ffb76d1f7f6b Mon Sep 17 00:00:00 2001 From: Di Da Date: Wed, 20 Nov 2019 15:16:26 -0800 Subject: [PATCH 4/4] Address PR comments --- vnext/ReactUWP/Views/SIPEventHandler.cpp | 26 ++++++++-------------- vnext/ReactUWP/Views/SIPEventHandler.h | 4 ++-- vnext/ReactUWP/Views/ScrollViewManager.cpp | 8 +++---- 3 files changed, 14 insertions(+), 24 deletions(-) diff --git a/vnext/ReactUWP/Views/SIPEventHandler.cpp b/vnext/ReactUWP/Views/SIPEventHandler.cpp index 06b8cab8f3b..68e2430781c 100644 --- a/vnext/ReactUWP/Views/SIPEventHandler.cpp +++ b/vnext/ReactUWP/Views/SIPEventHandler.cpp @@ -68,32 +68,24 @@ void SIPEventHandler::AttachView(XamlView xamlView, bool fireKeyboardEvents) { }); } } - -bool SIPEventHandler::TryShow() { - if (IsRS5OrHigher() && m_coreInputView) { - if (!m_isShowing) { // CoreInputView.TryShow is only avaliable after RS5 - return m_coreInputView.TryShow(); +/* +void SIPEventHandler::TryShow() { + if (IsRS5OrHigher() && m_coreInputView && !m_isShowing) { // CoreInputView.TryShow is only avaliable after RS5 + m_coreInputView.TryShow(); } - return true; - } - return false; } +*/ -bool SIPEventHandler::TryHide() { - if (IsRS5OrHigher() && m_coreInputView) { - if (m_isShowing) { // CoreInputView.TryHide is only avaliable after RS5 - return m_coreInputView.TryHide(); - } - return true; +void SIPEventHandler::TryHide() { + if (IsRS5OrHigher() && m_coreInputView && m_isShowing) { // CoreInputView.TryHide is only avaliable after RS5 + m_coreInputView.TryHide(); } - return false; } bool SIPEventHandler::IsOcclusionsEmpty(winrt::IVectorView occlusions) { m_finalRect = winrt::RectHelper::Empty(); if (occlusions) { - for (uint32_t i = 0; i < occlusions.Size(); i++) { - winrt::CoreInputViewOcclusion occlusion = occlusions.GetAt(i); + for (const auto &occlusion : occlusions) { if (occlusion.OcclusionKind() == winrt::CoreInputViewOcclusionKind::Docked) { m_finalRect = winrt::RectHelper::Union(m_finalRect, occlusion.OccludingRect()); } diff --git a/vnext/ReactUWP/Views/SIPEventHandler.h b/vnext/ReactUWP/Views/SIPEventHandler.h index eea7ca49789..defbd64c5b0 100644 --- a/vnext/ReactUWP/Views/SIPEventHandler.h +++ b/vnext/ReactUWP/Views/SIPEventHandler.h @@ -25,8 +25,8 @@ class SIPEventHandler { } void AttachView(XamlView xamlView, bool fireKeyboardEvents); - bool TryShow(); - bool TryHide(); + // void TryShow(); + void TryHide(); private: bool IsOcclusionsEmpty(winrt::IVectorView occlusions); diff --git a/vnext/ReactUWP/Views/ScrollViewManager.cpp b/vnext/ReactUWP/Views/ScrollViewManager.cpp index 2377c0f9eb8..2b876545a83 100644 --- a/vnext/ReactUWP/Views/ScrollViewManager.cpp +++ b/vnext/ReactUWP/Views/ScrollViewManager.cpp @@ -253,10 +253,8 @@ void ScrollViewShadowNode::AddHandlers(const winrt::ScrollViewer &scrollViewer) scrollViewer.DirectManipulationStarted(winrt::auto_revoke, [this](const auto &sender, const auto &) { m_isScrolling = true; - if (m_dismissKeyboardOnDrag) { - if (m_SIPEventHandler) { - m_SIPEventHandler->TryHide(); - } + if (m_dismissKeyboardOnDrag && m_SIPEventHandler) { + m_SIPEventHandler->TryHide(); } const auto scrollViewer = sender.as(); @@ -307,7 +305,7 @@ void ScrollViewShadowNode::AddHandlers(const winrt::ScrollViewer &scrollViewer) void ScrollViewShadowNode::RegisterSIPEventsWhenNeeded() { if (m_dismissKeyboardOnDrag) { auto view = GetView(); - if (winrt::VisualTreeHelper::GetParent(view) != nullptr) { + if (winrt::VisualTreeHelper::GetParent(view)) { auto wkinstance = GetViewManager()->GetReactInstance(); m_SIPEventHandler = std::make_unique(wkinstance); m_SIPEventHandler->AttachView(GetView(), false /*fireKeyboardEvents*/);