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> | 2021-10-04 10:21:13 +0200 |
commit | d6f8fb4f7390cc52f8cd4a08b890bac77bc9c678 (patch) | |
tree | 7d52759901d0ebce67ba7d98a3f5e6e0eb03805f | |
parent | 040ca9ac423dbaead66b14b414a66b0ee143912f (diff) | |
download | qtwebengine-chromium-d6f8fb4f7390cc52f8cd4a08b890bac77bc9c678.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>
29 files changed, 144 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 c48863fc9c2..ed441caa5f3 100644 --- a/chromium/content/browser/renderer_host/render_frame_host_impl.cc +++ b/chromium/content/browser/renderer_host/render_frame_host_impl.cc @@ -5359,9 +5359,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 3456986091a..760ccc5c757 100644 --- a/chromium/content/browser/renderer_host/render_frame_host_impl.h +++ b/chromium/content/browser/renderer_host/render_frame_host_impl.h @@ -1861,7 +1861,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 6a784277073..7b576ab127d 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_impl.cc +++ b/chromium/content/browser/renderer_host/render_widget_host_impl.cc @@ -2139,9 +2139,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 bc4800b72f8..2c1a07c6daa 100644 --- a/chromium/content/browser/renderer_host/render_widget_host_impl.h +++ b/chromium/content/browser/renderer_host/render_widget_host_impl.h @@ -696,7 +696,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 b8ae3c5d06c..1cfec9cf5f1 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 @@ -2576,7 +2576,9 @@ 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 ec0d6b0acbc..b67a546bd65 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 @@ -176,9 +176,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 8cc591cfc75..f1739d6f84c 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 @@ -211,7 +211,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 707d5d7348f..b8eab6b746f 100644 --- a/chromium/content/browser/renderer_host/text_input_manager.cc +++ b/chromium/content/browser/renderer_host/text_input_manager.cc @@ -340,9 +340,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); } @@ -431,11 +432,13 @@ TextInputManager::TextSelection::~TextSelection() {} 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 f1cc5560c1a..d7d887e8aef 100644 --- a/chromium/content/browser/renderer_host/text_input_manager.h +++ b/chromium/content/browser/renderer_host/text_input_manager.h @@ -108,12 +108,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 @@ -132,6 +134,9 @@ 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); @@ -215,7 +220,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 577f42d52e0..4a5fcfca191 100644 --- a/chromium/content/public/renderer/render_frame.h +++ b/chromium/content/public/renderer/render_frame.h @@ -215,7 +215,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 b43d23fce76..7b47dafa6d5 100644 --- a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc +++ b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc @@ -1294,7 +1294,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 09cf0bc111e..12d0e63945e 100644 --- a/chromium/content/renderer/render_frame_impl.cc +++ b/chromium/content/renderer/render_frame_impl.cc @@ -1970,7 +1970,7 @@ 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); + SyncSelectionIfRequired(blink::SyncCondition::kNotForced, true /* user_initiated */); } #endif // BUILDFLAG(ENABLE_PLUGINS) @@ -2357,9 +2357,11 @@ bool RenderFrameImpl::IsFTPDirectoryListing() { 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( @@ -3967,20 +3969,32 @@ 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 (is_empty_selection) selection_text_.clear(); + if (!user_initiated) { + // Do not update text input state unnecessarily when text selection remains + // empty. + if (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 // was changed, and SyncSelectionIfRequired may send SelectionChanged // to notify the selection was changed. Focus change should be notified // before selection change. GetLocalRootWebFrameWidget()->UpdateTextInputState(); - SyncSelectionIfRequired(force_sync); + SyncSelectionIfRequired(force_sync, user_initiated); } void RenderFrameImpl::OnMainFrameIntersectionChanged( @@ -5297,10 +5311,11 @@ void RenderFrameImpl::UpdateEncoding(WebFrame* frame, GetFrameHost()->UpdateEncoding(encoding_name); } -void RenderFrameImpl::SyncSelectionIfRequired(blink::SyncCondition force_sync) { +void RenderFrameImpl::SyncSelectionIfRequired(blink::SyncCondition force_sync, + bool user_initiated) { std::u16string text; - size_t offset; - gfx::Range range; + size_t offset = 0; + gfx::Range range = gfx::Range::InvalidRange(); #if BUILDFLAG(ENABLE_PLUGINS) if (focused_pepper_plugin_) { focused_pepper_plugin_->GetSurroundingText(&text, &range); @@ -5311,31 +5326,37 @@ void RenderFrameImpl::SyncSelectionIfRequired(blink::SyncCondition force_sync) { { 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; } } @@ -5351,7 +5372,7 @@ void RenderFrameImpl::SyncSelectionIfRequired(blink::SyncCondition force_sync) { 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 f659ea4833f..c5328328e6b 100644 --- a/chromium/content/renderer/render_frame_impl.h +++ b/chromium/content/renderer/render_frame_impl.h @@ -359,7 +359,8 @@ class CONTENT_EXPORT RenderFrameImpl bool IsFTPDirectoryListing() override; 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; @@ -610,7 +611,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) override; + void SyncSelectionIfRequired(blink::SyncCondition force_sync, bool user_initiated) override; void CreateAudioInputStream( blink::CrossVariantMojoRemote< blink::mojom::RendererAudioInputStreamFactoryClientInterfaceBase> diff --git a/chromium/third_party/blink/public/mojom/frame/frame.mojom b/chromium/third_party/blink/public/mojom/frame/frame.mojom index 3bb95982889..fad36112e5a 100644 --- a/chromium/third_party/blink/public/mojom/frame/frame.mojom +++ b/chromium/third_party/blink/public/mojom/frame/frame.mojom @@ -433,7 +433,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 9b42baf6eb4..6929ab8ca64 100644 --- a/chromium/third_party/blink/public/web/web_local_frame.h +++ b/chromium/third_party/blink/public/web/web_local_frame.h @@ -476,7 +476,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; // Expands the selection to a word around the caret and returns // true. Does nothing and returns false if there is no caret or 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 c17f15d9cbf..ec423c3d29f 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 @@ -710,7 +710,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) {} + virtual void SyncSelectionIfRequired(SyncCondition force_sync, 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 190cc57ddbb..df5e4a8e17e 100644 --- a/chromium/third_party/blink/public/web/web_widget.h +++ b/chromium/third_party/blink/public/web/web_widget.h @@ -155,6 +155,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; + using HandledEventCallback = base::OnceCallback<void( mojom::InputEventResultState ack_state, const ui::LatencyInfo& latency_info, 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 bd6d49a8124..39e61aac2fa 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 @@ -475,6 +475,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, HandledEventCallback callback) { 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 4e25100f681..1df5c11223e 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 @@ -167,6 +167,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&, HandledEventCallback) 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 fab2d2cbc44..df8eafc11d3 100644 --- a/chromium/third_party/blink/renderer/core/frame/local_frame.cc +++ b/chromium/third_party/blink/renderer/core/frame/local_frame.cc @@ -1605,8 +1605,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 777647d822d..ac2254f0de4 100644 --- a/chromium/third_party/blink/renderer/core/frame/local_frame.h +++ b/chromium/third_party/blink/renderer/core/frame/local_frame.h @@ -360,7 +360,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 3dd4e255bd0..c41df9b6526 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 @@ -2328,6 +2328,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, HandledEventCallback callback) { @@ -3498,7 +3503,7 @@ 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, 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 3475cad430b..cec066aad5d 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 @@ -344,6 +344,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&, HandledEventCallback) 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 dd4012a8dc0..6aa502cd702 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 @@ -1398,8 +1398,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::SelectWordAroundCaret() { 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 c722101236b..9be01605790 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 @@ -213,7 +213,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 user_initiated) override; bool SelectWordAroundCaret() override; void SelectRange(const gfx::Point& base, const gfx::Point& extent) override; void SelectRange(const WebRange&, 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 70d0a8e83a8..7fa96978dcd 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 @@ -165,7 +165,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 674aa1836e9..cb21b2c131b 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 240c06a824a..de2b557db10 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 bcf11465aa1..dad08c26cfb 100644 --- a/chromium/third_party/blink/renderer/platform/widget/widget_base.cc +++ b/chromium/third_party/blink/renderer/platform/widget/widget_base.cc @@ -1211,6 +1211,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 @@ -1221,6 +1222,7 @@ void WidgetBase::ImeSetComposition( host->ImeCancelComposition(); } } + input_handler_.set_ime_composition_replacement(false); UpdateCompositionInfo(false /* not an immediate request */); } |