Browse Source

fix: re-enable synchronous spellcheck on Windows (#45712)

* fix: re-enable synchronous spellcheck on Windows

* revert: fix: empty suggestions with windows platform checker

---------

Co-authored-by: Samuel Maddock <[email protected]>
Keeley Hammond 1 month ago
parent
commit
6248c2436a

+ 1 - 0
patches/chromium/.patches

@@ -140,3 +140,4 @@ revert_code_health_clean_up_stale_macwebcontentsocclusion.patch
 ignore_parse_errors_for_pkey_appusermodel_toastactivatorclsid.patch
 feat_add_signals_when_embedder_cleanup_callbacks_run_for.patch
 feat_separate_content_settings_callback_for_sync_and_async_clipboard.patch
+fix_win32_synchronous_spellcheck.patch

+ 29 - 0
patches/chromium/fix_win32_synchronous_spellcheck.patch

@@ -0,0 +1,29 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Keeley Hammond <[email protected]>
+Date: Wed, 19 Feb 2025 11:18:44 -0800
+Subject: fix: re-enable synchronous spellcheck on Windows
+
+This fix partially reverts 6109477: Code Health:
+Clean up stale base::Feature "WinRetrieveSuggestionsOnlyOnDemand"
+https://chromium-review.googlesource.com/c/chromium/src/+/6109477
+by re-adding a synchronous call to FillSuggestionList.
+
+This patch can be removed when an asynchronous spellcheck API
+option is added to Electron.
+
+diff --git a/components/spellcheck/browser/windows_spell_checker.cc b/components/spellcheck/browser/windows_spell_checker.cc
+index f5a7411037758427eddc088b5426554b4a500d33..04b3edd4d8c58d38e260cc54beb0dab86368fc25 100644
+--- a/components/spellcheck/browser/windows_spell_checker.cc
++++ b/components/spellcheck/browser/windows_spell_checker.cc
+@@ -239,6 +239,11 @@ std::vector<SpellCheckResult> BackgroundHelper::RequestTextCheckForAllLanguages(
+             (action == CORRECTIVE_ACTION_GET_SUGGESTIONS ||
+              action == CORRECTIVE_ACTION_REPLACE)) {
+           std::vector<std::u16string> suggestions;
++          // TODO (vertedinde): Perform the synchronous operation of retrieving
++          // suggestions for all misspelled words while performing a text check.
++          FillSuggestionList(it->first,
++            text.substr(start_index, error_length),
++            &suggestions);
+           result_map[std::tuple<ULONG, ULONG>(start_index, error_length)]
+               .push_back(suggestions);
+         }

+ 1 - 42
shell/browser/api/electron_api_web_contents.cc

@@ -194,14 +194,6 @@
 #include "content/public/browser/plugin_service.h"
 #endif
 
-#if BUILDFLAG(IS_WIN) && BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
-#include "chrome/browser/spellchecker/spellcheck_factory.h"
-#include "chrome/browser/spellchecker/spellcheck_service.h"
-#include "components/spellcheck/browser/spellcheck_platform.h"
-#include "components/spellcheck/common/spellcheck_common.h"
-#include "components/spellcheck/common/spellcheck_features.h"
-#endif
-
 #if !IS_MAS_BUILD()
 #include "chrome/browser/hang_monitor/hang_crash_dump.h"  // nogncheck
 #endif
@@ -1521,44 +1513,11 @@ void WebContents::RendererResponsive(
 
 bool WebContents::HandleContextMenu(content::RenderFrameHost& render_frame_host,
                                     const content::ContextMenuParams& params) {
-#if BUILDFLAG(IS_WIN) && BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
-  if (!params.misspelled_word.empty() && spellcheck::UseBrowserSpellChecker()) {
-    SpellcheckService* spellcheck_service =
-        SpellcheckServiceFactory::GetForContext(
-            render_frame_host.GetBrowserContext());
-    if (spellcheck_service) {
-      spellcheck_platform::GetPerLanguageSuggestions(
-          spellcheck_service->platform_spell_checker(), params.misspelled_word,
-          base::BindOnce(&WebContents::OnGetPlatformSuggestionsComplete,
-                         GetWeakPtr(), std::ref(render_frame_host), params));
-    }
-  } else {
-#endif
-    Emit("context-menu",
-         std::make_tuple(params, &render_frame_host,
-                         std::optional<std::vector<std::u16string>>{}));
-#if BUILDFLAG(IS_WIN) && BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
-  }
-#endif
+  Emit("context-menu", std::make_pair(params, &render_frame_host));
 
   return true;
 }
 
-#if BUILDFLAG(IS_WIN) && BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
-void WebContents::OnGetPlatformSuggestionsComplete(
-    content::RenderFrameHost& render_frame_host,
-    const content::ContextMenuParams& params,
-    const spellcheck::PerLanguageSuggestions&
-        platform_per_language_suggestions) {
-  std::vector<std::u16string> combined_suggestions;
-  spellcheck::FillSuggestions(platform_per_language_suggestions,
-                              &combined_suggestions);
-  Emit("context-menu",
-       std::make_tuple(params, &render_frame_host,
-                       std::make_optional(combined_suggestions)));
-}
-#endif
-
 void WebContents::FindReply(content::WebContents* web_contents,
                             int request_id,
                             int number_of_matches,

+ 0 - 12
shell/browser/api/electron_api_web_contents.h

@@ -57,10 +57,6 @@ class ScriptExecutor;
 }
 #endif
 
-#if BUILDFLAG(IS_WIN) && BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
-#include "components/spellcheck/common/spellcheck_common.h"
-#endif
-
 namespace blink {
 struct DeviceEmulationParams;
 // enum class PermissionType;
@@ -761,14 +757,6 @@ class WebContents final : public ExclusiveAccessContext,
   // Update the html fullscreen flag in both browser and renderer.
   void UpdateHtmlApiFullscreen(bool fullscreen);
 
-#if BUILDFLAG(IS_WIN) && BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
-  void OnGetPlatformSuggestionsComplete(
-      content::RenderFrameHost& render_frame_host,
-      const content::ContextMenuParams& params,
-      const spellcheck::PerLanguageSuggestions&
-          platform_per_language_suggestions);
-#endif
-
   v8::Global<v8::Value> session_;
   v8::Global<v8::Value> devtools_web_contents_;
   v8::Global<v8::Value> debugger_;

+ 3 - 6
shell/common/gin_converters/content_converter.cc

@@ -88,7 +88,8 @@ v8::Local<v8::Value> Converter<blink::mojom::MenuItem::Type>::ToV8(
 v8::Local<v8::Value> Converter<ContextMenuParamsWithRenderFrameHost>::ToV8(
     v8::Isolate* isolate,
     const ContextMenuParamsWithRenderFrameHost& val) {
-  auto [params, render_frame_host, optional_suggestions] = val;
+  const auto& params = val.first;
+  content::RenderFrameHost* render_frame_host = val.second;
   auto dict = gin_helper::Dictionary::CreateEmpty(isolate);
   dict.SetGetter("frame", render_frame_host, v8::DontEnum);
   dict.Set("x", params.x);
@@ -113,11 +114,7 @@ v8::Local<v8::Value> Converter<ContextMenuParamsWithRenderFrameHost>::ToV8(
   dict.Set("misspelledWord", params.misspelled_word);
   dict.Set("selectionRect", params.selection_rect);
 #if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
-  if (optional_suggestions) {
-    dict.Set("dictionarySuggestions", optional_suggestions.value());
-  } else {
-    dict.Set("dictionarySuggestions", params.dictionary_suggestions);
-  }
+  dict.Set("dictionarySuggestions", params.dictionary_suggestions);
   dict.Set("spellcheckEnabled", params.spellcheck_enabled);
 #else
   dict.Set("spellcheckEnabled", false);

+ 1 - 3
shell/common/gin_converters/content_converter.h

@@ -26,9 +26,7 @@ struct NativeWebKeyboardEvent;
 }
 
 using ContextMenuParamsWithRenderFrameHost =
-    std::tuple<content::ContextMenuParams,
-               content::RenderFrameHost*,
-               std::optional<std::vector<std::u16string>>>;
+    std::pair<content::ContextMenuParams, content::RenderFrameHost*>;
 
 namespace gin {