Skip to content

Commit

Permalink
Work around for MS Word's rejecting sync edit sessions
Browse files Browse the repository at this point in the history
This is a workaround for Microsoft Word's suddenly stopping accepting
synchronous edit sessions after moving ruler UI.

While MS Word's stack trace after entering the failure mode strongly
implies that this is an unexpected behavior in Microsoft Word [1],
realistically Mozc needs to work around this by avoiding synchronous
edit sessions whenever possible as TSF team has recommended [2].

Also MS-IME in Windows 11 22H2 does use asynchronous edit sessions
even from the key event handler unless

  "Use previous version of Microsoft IME"

settings is enabled.  This means that stopping relying on synchronous
edit sessions in Mozc also benefits the general app compatibility.

The problem is that redesigning edit session handling is a relatively
big project [3].  As a quick workaround, this commit aims to address
the main typing issue in MS Word by tweaking 'OnOutputReceivedImpl'.
The following features remains to be unavailable in the failure mode.

 * Reconversion triggered from IMEs.
 * Undo-commit

Closes google#819 with known issues.

 [1]: google#819
 [2]: https://learn.microsoft.com/en-us/archive/blogs/tsfaware/rules-of-text-services
 [3]: google#821

PiperOrigin-RevId: 573696936
  • Loading branch information
yukawa authored and coooooooozy committed Nov 25, 2023
1 parent 7e22d96 commit b37cb0d
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 0 deletions.
17 changes: 17 additions & 0 deletions src/win32/tip/tip_edit_session.cc
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,15 @@ bool OnOutputReceivedImpl(TipTextService *text_service, ITfContext *context,
auto edit_session = MakeComPtr<SyncEditSessionImpl>(text_service, context,
std::move(new_output));

TipThreadContext *thread_context = text_service->GetThreadContext();

if (mode == kSync && thread_context->use_async_lock_in_key_handler()) {
// A workaround for MS Word's failure mode.
// See https://github.com/google/mozc/issues/819 for details.
// TODO(https://github.com/google/mozc/issues/821): Remove this workaround.
mode = kAsync;
}

DWORD edit_session_flag = TF_ES_READWRITE;
switch (mode) {
case kAsync:
Expand All @@ -526,6 +535,14 @@ bool OnOutputReceivedImpl(TipTextService *text_service, ITfContext *context,
const HRESULT hr = context->RequestEditSession(
text_service->GetClientID(), edit_session.get(), edit_session_flag,
&edit_session_result);

if (mode == kSync && edit_session_result == TF_E_SYNCHRONOUS) {
// A workaround for MS Word's failure mode.
// See https://github.com/google/mozc/issues/819 for details.
// TODO(https://github.com/google/mozc/issues/821): Remove this workaround.
thread_context->set_use_async_lock_in_key_handler(true);
}

return SUCCEEDED(hr) && SUCCEEDED(edit_session_result);
}

Expand Down
12 changes: 12 additions & 0 deletions src/win32/tip/tip_thread_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,21 @@ class TipThreadContext {
int32_t GetFocusRevision() const { return focus_revision_; }
void IncrementFocusRevision();

void set_use_async_lock_in_key_handler(bool value) {
use_async_lock_in_key_handler_ = value;
}
bool use_async_lock_in_key_handler() const {
return use_async_lock_in_key_handler_;
}

private:
TipInputModeManager input_mode_manager_;
int32_t focus_revision_ = 0;

// A workaround for MS Word's failure mode.
// See https://github.com/google/mozc/issues/819 for details.
// TODO(https://github.com/google/mozc/issues/821): Remove this workaround.
bool use_async_lock_in_key_handler_ = false;
};

} // namespace tsf
Expand Down

0 comments on commit b37cb0d

Please sign in to comment.