diff options
author | Peter Varga <pvarga@inf.u-szeged.hu> | 2017-04-27 11:23:55 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-02-25 10:43:19 +0100 |
commit | 90a9390416d1e4f8409e939e83e005119fdfe1a3 (patch) | |
tree | babe471c0f4225d84191508fa447ce46a9b5d3e5 | |
parent | 7fbf778631c9e0cc310106c6d2b35c811edcb8ec (diff) | |
download | qtwebengine-chromium-90a9390416d1e4f8409e939e83e005119fdfe1a3.tar.gz |
Update TextSelection for non-user initiated events
This makes Chromium Content API to be able to notify about text
selection changes triggered by non-user events (eg. JavaScript, IME,
autofill).
Based on:
https://codereview.chromium.org/2903833002
Corresponding Chromium bug report:
https://bugs.chromium.org/p/chromium/issues/detail?id=671986
Change-Id: I86a7f203d789853199469b301facd06fe5ba54bd
Task-number: QTBUG-53134
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
30 files changed, 145 insertions, 67 deletions
diff --git a/chromium/content/browser/renderer_host/render_frame_host_impl.cc b/chromium/content/browser/renderer_host/render_frame_host_impl.cc index e074c1317d9..1005687a68a 100644 --- a/chromium/content/browser/renderer_host/render_frame_host_impl.cc +++ b/chromium/content/browser/renderer_host/render_frame_host_impl.cc @@ -6138,9 +6138,10 @@ void RenderFrameHostImpl::FocusedElementChanged( void RenderFrameHostImpl::TextSelectionChanged(const std::u16string& text, uint32_t offset, - const gfx::Range& range) { + const gfx::Range& range, + bool user_initiated) { has_selection_ = !text.empty(); - GetRenderWidgetHost()->SelectionChanged(text, offset, range); + GetRenderWidgetHost()->SelectionChanged(text, offset, range, user_initiated); } void RenderFrameHostImpl::DidReceiveUserActivation() { diff --git a/chromium/content/browser/renderer_host/render_frame_host_impl.h b/chromium/content/browser/renderer_host/render_frame_host_impl.h index dde52d4207f..662f6cdac81 100644 --- a/chromium/content/browser/renderer_host/render_frame_host_impl.h +++ b/chromium/content/browser/renderer_host/render_frame_host_impl.h @@ -2078,7 +2078,8 @@ class CONTENT_EXPORT RenderFrameHostImpl blink::mojom::FocusType focus_type) override; void TextSelectionChanged(const std::u16string& text, uint32_t offset, - const gfx::Range& range) override; + const gfx::Range& range, + bool user_initiated) override; void ShowPopupMenu( mojo::PendingRemote<blink::mojom::PopupMenuClient> popup_client, const gfx::Rect& bounds, diff --git a/chromium/content/browser/renderer_host/render_widget_host_impl.cc b/chromium/content/browser/renderer_host/render_widget_host_impl.cc index 367c1795213..140f05001ec 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_impl.cc +++ b/chromium/content/browser/renderer_host/render_widget_host_impl.cc @@ -2181,9 +2181,12 @@ void RenderWidgetHostImpl::GetSnapshotFromBrowser( void RenderWidgetHostImpl::SelectionChanged(const std::u16string& text, uint32_t offset, - const gfx::Range& range) { - if (view_) - view_->SelectionChanged(text, static_cast<size_t>(offset), range); + const gfx::Range& range, + bool user_initiated) { + if (view_) { + view_->SelectionChanged(text, static_cast<size_t>(offset), range, + user_initiated); + } } void RenderWidgetHostImpl::SelectionBoundsChanged( diff --git a/chromium/content/browser/renderer_host/render_widget_host_impl.h b/chromium/content/browser/renderer_host/render_widget_host_impl.h index da4223e064f..cfc49170b71 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_impl.h +++ b/chromium/content/browser/renderer_host/render_widget_host_impl.h @@ -714,7 +714,8 @@ class CONTENT_EXPORT RenderWidgetHostImpl // Called from a RenderFrameHost when the text selection has changed. void SelectionChanged(const std::u16string& text, uint32_t offset, - const gfx::Range& range); + const gfx::Range& range, + bool user_initiated); size_t in_flight_event_count() const { return in_flight_event_count_; } diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_aura.cc b/chromium/content/browser/renderer_host/render_widget_host_view_aura.cc index 9bbfba2c8a3..743014e51f2 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/chromium/content/browser/renderer_host/render_widget_host_view_aura.cc @@ -2740,7 +2740,8 @@ void RenderWidgetHostViewAura::OnTextSelectionChanged( ui::ClipboardBuffer::kSelection)) { const TextInputManager::TextSelection* selection = GetTextInputManager()->GetTextSelection(focused_view); - if (selection->selected_text().length()) { + if (selection->selected_text().length() + && selection->user_initiated()) { // Set the ClipboardBuffer::kSelection to the ui::Clipboard. ui::ScopedClipboardWriter clipboard_writer( ui::ClipboardBuffer::kSelection); diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_base.cc b/chromium/content/browser/renderer_host/render_widget_host_view_base.cc index 0399fd10fff..8c59a7d1204 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_view_base.cc +++ b/chromium/content/browser/renderer_host/render_widget_host_view_base.cc @@ -174,9 +174,11 @@ RenderWidgetHostViewBase* RenderWidgetHostViewBase::GetRootView() { void RenderWidgetHostViewBase::SelectionChanged(const std::u16string& text, size_t offset, - const gfx::Range& range) { + const gfx::Range& range, + bool user_initiated) { if (GetTextInputManager()) - GetTextInputManager()->SelectionChanged(this, text, offset, range); + GetTextInputManager()->SelectionChanged(this, text, offset, range, + user_initiated); } gfx::Size RenderWidgetHostViewBase::GetRequestedRendererSize() { diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_base.h b/chromium/content/browser/renderer_host/render_widget_host_view_base.h index 7759ce1982e..897bcfa08df 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_view_base.h +++ b/chromium/content/browser/renderer_host/render_widget_host_view_base.h @@ -191,7 +191,8 @@ class CONTENT_EXPORT RenderWidgetHostViewBase : public RenderWidgetHostView { // Notifies the View that the renderer text selection has changed. virtual void SelectionChanged(const std::u16string& text, size_t offset, - const gfx::Range& range); + const gfx::Range& range, + bool user_initiated); // The requested size of the renderer. May differ from GetViewBounds().size() // when the view requires additional throttling. diff --git a/chromium/content/browser/renderer_host/text_input_manager.cc b/chromium/content/browser/renderer_host/text_input_manager.cc index aad1e66b6fd..cb6e35d1111 100644 --- a/chromium/content/browser/renderer_host/text_input_manager.cc +++ b/chromium/content/browser/renderer_host/text_input_manager.cc @@ -366,9 +366,10 @@ void TextInputManager::ImeCompositionRangeChanged( void TextInputManager::SelectionChanged(RenderWidgetHostViewBase* view, const std::u16string& text, size_t offset, - const gfx::Range& range) { + const gfx::Range& range, + bool user_initiated) { DCHECK(IsRegistered(view)); - text_selection_map_[view].SetSelection(text, offset, range); + text_selection_map_[view].SetSelection(text, offset, range, user_initiated); for (auto& observer : observer_list_) observer.OnTextSelectionChanged(this, view); } @@ -460,11 +461,13 @@ TextInputManager::TextSelection::~TextSelection() = default; void TextInputManager::TextSelection::SetSelection(const std::u16string& text, size_t offset, - const gfx::Range& range) { + const gfx::Range& range, + bool user_initiated) { text_ = text; range_.set_start(range.start()); range_.set_end(range.end()); offset_ = offset; + user_initiated_ = user_initiated; // Update the selected text. selected_text_.clear(); diff --git a/chromium/content/browser/renderer_host/text_input_manager.h b/chromium/content/browser/renderer_host/text_input_manager.h index 83825478d72..6bc25d79472 100644 --- a/chromium/content/browser/renderer_host/text_input_manager.h +++ b/chromium/content/browser/renderer_host/text_input_manager.h @@ -111,12 +111,14 @@ class CONTENT_EXPORT TextInputManager { void SetSelection(const std::u16string& text, size_t offset, - const gfx::Range& range); + const gfx::Range& range, + bool user_initiated); const std::u16string& selected_text() const { return selected_text_; } size_t offset() const { return offset_; } const gfx::Range& range() const { return range_; } const std::u16string& text() const { return text_; } + bool user_initiated() const { return user_initiated_; } private: // The offset of the text stored in |text| relative to the start of the web @@ -135,6 +137,10 @@ class CONTENT_EXPORT TextInputManager { // Part of the text on the page which includes the highlighted text plus // possibly several characters before and after it. std::u16string text_; + + // True if text selection is triggered by user input. + bool user_initiated_ = false; + }; explicit TextInputManager(bool should_do_learning); @@ -228,7 +234,8 @@ class CONTENT_EXPORT TextInputManager { void SelectionChanged(RenderWidgetHostViewBase* view, const std::u16string& text, size_t offset, - const gfx::Range& range); + const gfx::Range& range, + bool user_initiated); // Registers the given |view| for tracking its TextInputState. This is called // by any view which has updates in its TextInputState (whether tab's RWHV or diff --git a/chromium/content/public/renderer/render_frame.h b/chromium/content/public/renderer/render_frame.h index 7395d54aef7..c2b1568f148 100644 --- a/chromium/content/public/renderer/render_frame.h +++ b/chromium/content/public/renderer/render_frame.h @@ -222,7 +222,8 @@ class CONTENT_EXPORT RenderFrame : public IPC::Listener, // Notifies the browser of text selection changes made. virtual void SetSelectedText(const std::u16string& selection_text, size_t offset, - const gfx::Range& range) = 0; + const gfx::Range& range, + bool user_initiated) = 0; // Adds |message| to the DevTools console. virtual void AddMessageToConsole(blink::mojom::ConsoleMessageLevel level, diff --git a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc index ec8f6dd50d7..722c0cd0176 100644 --- a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc +++ b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc @@ -1287,7 +1287,7 @@ void PepperPluginInstanceImpl::SetSelectedText( selected_text_ = selected_text; gfx::Range range(0, selected_text.length()); - render_frame_->SetSelectedText(selected_text, 0, range); + render_frame_->SetSelectedText(selected_text, 0, range, true); } void PepperPluginInstanceImpl::SetLinkUnderCursor(const std::string& url) { diff --git a/chromium/content/renderer/render_frame_impl.cc b/chromium/content/renderer/render_frame_impl.cc index 89c2b46cfae..7a6a68dc4a1 100644 --- a/chromium/content/renderer/render_frame_impl.cc +++ b/chromium/content/renderer/render_frame_impl.cc @@ -2092,7 +2092,8 @@ void RenderFrameImpl::PepperSelectionChanged( // We have no reason to believe the locally cached last synced selection is // invalid so we do not need to force the update if it matches our last synced // value. - SyncSelectionIfRequired(blink::SyncCondition::kNotForced, false); + SyncSelectionIfRequired(blink::SyncCondition::kNotForced, false /* is_empty_selection */, + true /* user_initiated */); } #endif // BUILDFLAG(ENABLE_PLUGINS) @@ -2485,9 +2486,11 @@ void RenderFrameImpl::PluginDidStopLoading() { void RenderFrameImpl::SetSelectedText(const std::u16string& selection_text, size_t offset, - const gfx::Range& range) { + const gfx::Range& range, + bool user_initiated) { GetWebFrame()->TextSelectionChanged(WebString::FromUTF16(selection_text), - static_cast<uint32_t>(offset), range); + static_cast<uint32_t>(offset), range, + user_initiated); } void RenderFrameImpl::AddMessageToConsole( @@ -4263,10 +4266,20 @@ void RenderFrameImpl::AbortClientNavigation() { void RenderFrameImpl::DidChangeSelection(bool is_empty_selection, blink::SyncCondition force_sync) { - if (!GetLocalRootWebFrameWidget()->HandlingInputEvent() && - !GetLocalRootWebFrameWidget()->HandlingSelectRange()) - return; + bool user_initiated = + GetLocalRootWebFrameWidget()->HandlingInputEvent() || + GetLocalRootWebFrameWidget()->HandlingSelectRange(); + + if (!user_initiated) { + // Do not update text input state unnecessarily when text selection remains + // empty. + if (is_empty_selection && selection_text_.empty()) + return; + // Ignore selection change of text replacement triggered by IME composition. + if (GetLocalRootWebFrameWidget()->ImeCompositionReplacement()) + return; + } // UpdateTextInputState should be called before SyncSelectionIfRequired. // UpdateTextInputState may send TextInputStateChanged to notify the focus @@ -4274,7 +4287,7 @@ void RenderFrameImpl::DidChangeSelection(bool is_empty_selection, // to notify the selection was changed. Focus change should be notified // before selection change. GetLocalRootWebFrameWidget()->UpdateTextInputState(); - SyncSelectionIfRequired(force_sync, is_empty_selection); + SyncSelectionIfRequired(force_sync, is_empty_selection, user_initiated); } void RenderFrameImpl::OnMainFrameIntersectionChanged( @@ -5641,10 +5654,12 @@ void RenderFrameImpl::UpdateEncoding(WebFrame* frame, GetFrameHost()->UpdateEncoding(encoding_name); } -void RenderFrameImpl::SyncSelectionIfRequired(blink::SyncCondition force_sync, bool is_empty_selection) { +void RenderFrameImpl::SyncSelectionIfRequired(blink::SyncCondition force_sync, + bool is_empty_selection, + bool user_initiated) { std::u16string text; size_t offset = 0; - gfx::Range range; + gfx::Range range = gfx::Range::InvalidRange(); #if BUILDFLAG(ENABLE_PLUGINS) if (focused_pepper_plugin_) { focused_pepper_plugin_->GetSurroundingText(&text, &range); @@ -5655,31 +5670,37 @@ void RenderFrameImpl::SyncSelectionIfRequired(blink::SyncCondition force_sync, b if (!is_empty_selection) { WebRange selection = frame_->GetInputMethodController()->GetSelectionOffsets(); - if (selection.IsNull()) - return; - - range = gfx::Range(selection.StartOffset(), selection.EndOffset()); - if (frame_->GetInputMethodController()->TextInputType() != - blink::kWebTextInputTypeNone) { - // If current focused element is editable, we will send 100 more chars - // before and after selection. It is for input method surrounding text - // feature. - if (selection.StartOffset() > kExtraCharsBeforeAndAfterSelection) - offset = selection.StartOffset() - kExtraCharsBeforeAndAfterSelection; - else - offset = 0; - size_t length = - selection.EndOffset() - offset + kExtraCharsBeforeAndAfterSelection; - text = frame_->RangeAsText(WebRange(offset, length)).Utf16(); - } else { - offset = selection.StartOffset(); - text = frame_->SelectionAsText().Utf16(); - // http://crbug.com/101435 - // In some case, frame->selectionAsText() returned text's length is not - // equal to the length returned from frame_->GetSelectionOffsets(). So we - // have to set the range according to text.length(). - range.set_end(range.start() + text.length()); + // When clearing text selection from JavaScript the selection range + // might be null but the selected text still have to be updated. + // Do not cancel sync selection if the clear was not user initiated. + if (!selection.IsNull()) { + range = gfx::Range(selection.StartOffset(), selection.EndOffset()); + + if (frame_->GetInputMethodController()->TextInputType() != + blink::kWebTextInputTypeNone) { + // If current focused element is editable, we will send 100 more chars + // before and after selection. It is for input method surrounding text + // feature. + if (selection.StartOffset() > kExtraCharsBeforeAndAfterSelection) + offset = selection.StartOffset() - kExtraCharsBeforeAndAfterSelection; + else + offset = 0; + size_t length = + selection.EndOffset() - offset + kExtraCharsBeforeAndAfterSelection; + text = frame_->RangeAsText(WebRange(offset, length)).Utf16(); + } else { + offset = selection.StartOffset(); + text = frame_->SelectionAsText().Utf16(); + // http://crbug.com/101435 + // In some case, frame->selectionAsText() returned text's length is not + // equal to the length returned from + // GetWebWidget()->caretOrSelectionRange(). + // So we have to set the range according to text.length(). + range.set_end(range.start() + text.length()); + } + } else if (user_initiated) { + return; } } @@ -5695,7 +5716,7 @@ void RenderFrameImpl::SyncSelectionIfRequired(blink::SyncCondition force_sync, b selection_text_ = text; selection_text_offset_ = offset; selection_range_ = range; - SetSelectedText(text, offset, range); + SetSelectedText(text, offset, range, user_initiated); } GetLocalRootWebFrameWidget()->UpdateSelectionBounds(); } diff --git a/chromium/content/renderer/render_frame_impl.h b/chromium/content/renderer/render_frame_impl.h index 7e006ca25de..e23816278d3 100644 --- a/chromium/content/renderer/render_frame_impl.h +++ b/chromium/content/renderer/render_frame_impl.h @@ -368,7 +368,8 @@ class CONTENT_EXPORT RenderFrameImpl #endif void SetSelectedText(const std::u16string& selection_text, size_t offset, - const gfx::Range& range) override; + const gfx::Range& range, + bool user_initiated) override; void AddMessageToConsole(blink::mojom::ConsoleMessageLevel level, const std::string& message) override; blink::PreviewsState GetPreviewsState() override; @@ -633,7 +634,7 @@ class CONTENT_EXPORT RenderFrameImpl // it has changed or if the forced flag is passed. The forced flag is used // when the browser selection may be out of sync with the renderer due to // incorrect prediction. - void SyncSelectionIfRequired(blink::SyncCondition force_sync, bool is_empty_selection) override; + void SyncSelectionIfRequired(blink::SyncCondition force_sync, bool is_empty_selection, bool user_initiated) override; void CreateAudioInputStream( blink::CrossVariantMojoRemote< blink::mojom::RendererAudioInputStreamFactoryClientInterfaceBase> diff --git a/chromium/pdf/pdf_view_web_plugin.cc b/chromium/pdf/pdf_view_web_plugin.cc index aa50cccff71..1aca19f2e63 100644 --- a/chromium/pdf/pdf_view_web_plugin.cc +++ b/chromium/pdf/pdf_view_web_plugin.cc @@ -223,7 +223,7 @@ class BlinkContainerWrapper final : public PdfViewWebPlugin::ContainerWrapper { blink::WebLocalFrame* frame = GetFrame(); frame->View()->SetFocusedFrame(frame); - frame->TextSelectionChanged(selection_text, offset, range); + frame->TextSelectionChanged(selection_text, offset, range, /* user_initiated = */true); } std::unique_ptr<blink::WebAssociatedURLLoader> CreateAssociatedURLLoader( diff --git a/chromium/third_party/blink/public/mojom/frame/frame.mojom b/chromium/third_party/blink/public/mojom/frame/frame.mojom index 19c639bf81e..a40939d9b54 100644 --- a/chromium/third_party/blink/public/mojom/frame/frame.mojom +++ b/chromium/third_party/blink/public/mojom/frame/frame.mojom @@ -439,7 +439,8 @@ interface LocalFrameHost { // std::u16string text in the document. TextSelectionChanged(mojo_base.mojom.BigString16 text, uint32 offset, - gfx.mojom.Range range); + gfx.mojom.Range range, + bool user_initiated); // Show a popup menu using native controls on Mac or Android. // The popup menu is hidden when the mojo channel is closed. diff --git a/chromium/third_party/blink/public/web/web_local_frame.h b/chromium/third_party/blink/public/web/web_local_frame.h index a6b928747c6..6c79dbc68b0 100644 --- a/chromium/third_party/blink/public/web/web_local_frame.h +++ b/chromium/third_party/blink/public/web/web_local_frame.h @@ -500,7 +500,8 @@ class WebLocalFrame : public WebFrame { virtual void TextSelectionChanged(const WebString& selection_text, uint32_t offset, - const gfx::Range& range) = 0; + const gfx::Range& range, + bool user_initiated) = 0; // DEPRECATED: Use moveRangeSelection. virtual void SelectRange(const gfx::Point& base, diff --git a/chromium/third_party/blink/public/web/web_local_frame_client.h b/chromium/third_party/blink/public/web/web_local_frame_client.h index 88cdfd93be4..a54eb0499ba 100644 --- a/chromium/third_party/blink/public/web/web_local_frame_client.h +++ b/chromium/third_party/blink/public/web/web_local_frame_client.h @@ -729,7 +729,7 @@ class BLINK_EXPORT WebLocalFrameClient { // TextInputState may have changed call DidChangeSelection instead. // If the browser selection may not match the last synced // value, SyncCondition::kForced can be passed to force a sync. - virtual void SyncSelectionIfRequired(SyncCondition force_sync, bool is_empty_selection) {} + virtual void SyncSelectionIfRequired(SyncCondition force_sync, bool is_empty_selection, bool user_initiated) {} // TODO(https://crbug.com/787252): Remove the methods below and use the // Supplement mechanism. diff --git a/chromium/third_party/blink/public/web/web_widget.h b/chromium/third_party/blink/public/web/web_widget.h index 0f70b5d492e..602b579dd47 100644 --- a/chromium/third_party/blink/public/web/web_widget.h +++ b/chromium/third_party/blink/public/web/web_widget.h @@ -153,6 +153,8 @@ class WebWidget { // Set state that the widget is in the process of handling input events. virtual void SetHandlingInputEvent(bool handling) = 0; + virtual bool ImeCompositionReplacement() = 0; + // Process the input event, blocking until complete. virtual void ProcessInputEventSynchronouslyForTesting( const WebCoalescedInputEvent&) = 0; diff --git a/chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.cc b/chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.cc index 87720e55dbb..683e3d162a6 100644 --- a/chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.cc +++ b/chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.cc @@ -479,6 +479,10 @@ void WebPagePopupImpl::SetHandlingInputEvent(bool handling) { widget_base_->input_handler().set_handling_input_event(handling); } +bool WebPagePopupImpl::ImeCompositionReplacement() { + return widget_base_->input_handler().ime_composition_replacement(); +} + void WebPagePopupImpl::ProcessInputEventSynchronouslyForTesting( const WebCoalescedInputEvent& event) { widget_base_->input_handler().HandleInputEvent(event, nullptr, diff --git a/chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.h b/chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.h index 7a326a1d482..96772094917 100644 --- a/chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.h +++ b/chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.h @@ -169,6 +169,7 @@ class CORE_EXPORT WebPagePopupImpl final : public WebPagePopup, void SetCursor(const ui::Cursor& cursor) override; bool HandlingInputEvent() override; void SetHandlingInputEvent(bool handling) override; + bool ImeCompositionReplacement() override; void ProcessInputEventSynchronouslyForTesting( const WebCoalescedInputEvent&) override; void UpdateTextInputState() override; diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame.cc b/chromium/third_party/blink/renderer/core/frame/local_frame.cc index e4fa7685539..51e84d62055 100644 --- a/chromium/third_party/blink/renderer/core/frame/local_frame.cc +++ b/chromium/third_party/blink/renderer/core/frame/local_frame.cc @@ -1382,8 +1382,9 @@ String LocalFrame::SelectedTextForClipboard() const { void LocalFrame::TextSelectionChanged(const WTF::String& selection_text, uint32_t offset, - const gfx::Range& range) const { - GetLocalFrameHostRemote().TextSelectionChanged(selection_text, offset, range); + const gfx::Range& range, + bool user_initiated) const { + GetLocalFrameHostRemote().TextSelectionChanged(selection_text, offset, range, user_initiated); } PositionWithAffinity LocalFrame::PositionForPoint( diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame.h b/chromium/third_party/blink/renderer/core/frame/local_frame.h index b52d6d575fc..2770f007523 100644 --- a/chromium/third_party/blink/renderer/core/frame/local_frame.h +++ b/chromium/third_party/blink/renderer/core/frame/local_frame.h @@ -365,7 +365,8 @@ class CORE_EXPORT LocalFrame final String SelectedTextForClipboard() const; void TextSelectionChanged(const WTF::String& selection_text, uint32_t offset, - const gfx::Range& range) const; + const gfx::Range& range, + bool user_initiated) const; PositionWithAffinityTemplate<EditingAlgorithm<NodeTraversal>> PositionForPoint(const PhysicalOffset& frame_point); diff --git a/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc index 2bba71833d6..da796cf0860 100644 --- a/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc +++ b/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc @@ -2400,6 +2400,11 @@ void WebFrameWidgetImpl::SetHandlingInputEvent(bool handling) { widget_base_->input_handler().set_handling_input_event(handling); } +bool WebFrameWidgetImpl::ImeCompositionReplacement() +{ + return widget_base_->input_handler().ime_composition_replacement(); +} + void WebFrameWidgetImpl::ProcessInputEventSynchronouslyForTesting( const WebCoalescedInputEvent& event, WidgetBaseInputHandler::HandledEventCallback callback) { @@ -3593,7 +3598,8 @@ void WebFrameWidgetImpl::Replace(const String& word) { // If the resulting selection is not actually a change in selection, we do not // need to explicitly notify about the selection change. focused_frame->Client()->SyncSelectionIfRequired( - blink::SyncCondition::kNotForced); + blink::SyncCondition::kNotForced, false /* is_empty_selection */, + true /* user_initiated */); } void WebFrameWidgetImpl::ReplaceMisspelling(const String& word) { diff --git a/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.h b/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.h index 9122fb0838e..0301c92547f 100644 --- a/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.h +++ b/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.h @@ -361,6 +361,7 @@ class CORE_EXPORT WebFrameWidgetImpl void SetCursor(const ui::Cursor& cursor) override; bool HandlingInputEvent() override; void SetHandlingInputEvent(bool handling) override; + bool ImeCompositionReplacement() override; void ProcessInputEventSynchronouslyForTesting( const WebCoalescedInputEvent&) override; WebInputEventResult DispatchBufferedTouchEvents() override; diff --git a/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.cc index 8cdd9af092a..780468a755e 100644 --- a/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.cc +++ b/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.cc @@ -1384,8 +1384,9 @@ WebString WebLocalFrameImpl::SelectionAsMarkup() const { void WebLocalFrameImpl::TextSelectionChanged(const WebString& selection_text, uint32_t offset, - const gfx::Range& range) { - GetFrame()->TextSelectionChanged(selection_text, offset, range); + const gfx::Range& range, + bool user_initiated) { + GetFrame()->TextSelectionChanged(selection_text, offset, range, user_initiated); } bool WebLocalFrameImpl::SelectAroundCaret( diff --git a/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.h b/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.h index be3edad4ab9..a63ab7d21c0 100644 --- a/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.h +++ b/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.h @@ -215,7 +215,8 @@ class CORE_EXPORT WebLocalFrameImpl final WebString SelectionAsMarkup() const override; void TextSelectionChanged(const WebString& selection_text, uint32_t offset, - const gfx::Range& range) override; + const gfx::Range& range, + bool); bool SelectAroundCaret(mojom::blink::SelectionGranularity granularity, bool should_show_handle, bool should_show_context_menu); diff --git a/chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.cc b/chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.cc index ae8e1bb2803..3df8d4264df 100644 --- a/chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.cc +++ b/chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.cc @@ -162,7 +162,8 @@ void FakeLocalFrameHost::FocusedElementChanged( void FakeLocalFrameHost::TextSelectionChanged(const WTF::String& text, uint32_t offset, - const gfx::Range& range) {} + const gfx::Range& range, + bool user_initiated) {} void FakeLocalFrameHost::ShowPopupMenu( mojo::PendingRemote<mojom::blink::PopupMenuClient> popup_client, const gfx::Rect& bounds, diff --git a/chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.h b/chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.h index f8b98bcb7da..59f1eafb64d 100644 --- a/chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.h +++ b/chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.h @@ -105,7 +105,8 @@ class FakeLocalFrameHost : public mojom::blink::LocalFrameHost { blink::mojom::FocusType focus_type) override; void TextSelectionChanged(const WTF::String& text, uint32_t offset, - const gfx::Range& range) override; + const gfx::Range& range, + bool user_initiated) override; void ShowPopupMenu( mojo::PendingRemote<mojom::blink::PopupMenuClient> popup_client, const gfx::Rect& bounds, diff --git a/chromium/third_party/blink/renderer/platform/widget/input/widget_base_input_handler.h b/chromium/third_party/blink/renderer/platform/widget/input/widget_base_input_handler.h index 426cc0e890f..8c083002abc 100644 --- a/chromium/third_party/blink/renderer/platform/widget/input/widget_base_input_handler.h +++ b/chromium/third_party/blink/renderer/platform/widget/input/widget_base_input_handler.h @@ -90,6 +90,13 @@ class PLATFORM_EXPORT WidgetBaseInputHandler { // cursor. bool DidChangeCursor(const ui::Cursor& cursor); + bool ime_composition_replacement() const { + return ime_composition_replacement_; + } + void set_ime_composition_replacement(bool ime_composition_replacement) { + ime_composition_replacement_ = ime_composition_replacement; + } + private: class HandlingState; struct InjectScrollGestureParams { @@ -137,6 +144,10 @@ class PLATFORM_EXPORT WidgetBaseInputHandler { const bool supports_buffered_touch_ = false; + // Used to suppress notification about text selection changes triggered by + // IME composition when it replaces text. + bool ime_composition_replacement_ = false; + base::WeakPtrFactory<WidgetBaseInputHandler> weak_ptr_factory_{this}; }; diff --git a/chromium/third_party/blink/renderer/platform/widget/widget_base.cc b/chromium/third_party/blink/renderer/platform/widget/widget_base.cc index 5c2a96b1458..bd88fc480ac 100644 --- a/chromium/third_party/blink/renderer/platform/widget/widget_base.cc +++ b/chromium/third_party/blink/renderer/platform/widget/widget_base.cc @@ -1248,6 +1248,7 @@ void WidgetBase::ImeSetComposition( } ImeEventGuard guard(weak_ptr_factory_.GetWeakPtr()); + input_handler_.set_ime_composition_replacement(replacement_range.IsValid()); if (!frame_widget->SetComposition(text, ime_text_spans, replacement_range, selection_start, selection_end)) { // If we failed to set the composition text, then we need to let the browser @@ -1258,6 +1259,7 @@ void WidgetBase::ImeSetComposition( host->ImeCancelComposition(); } } + input_handler_.set_ime_composition_replacement(false); UpdateCompositionInfo(false /* not an immediate request */); } |