Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 54 additions & 1 deletion knowledge-base/kb0118.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,4 +223,57 @@ on the Keyman system service which emits a fake key event. That way it is possib

## Compliance on Windows

TODO
Compliance on Windows

On Windows, Keyman integrates with applications primarily through the Text Services Framework (TSF). Keyman implements a Text Input Processor (TIP) that communicates with the TSF manager and the target application.

When the user types, the TSF manager passes key events and text context to Keyman through the ITfContext interface, which provides access to the current edit context within the application. Keyman relies on this interface to retrieve context, determine the current selection, and insert or replace text.
For ITfContext details see [Learn Microsoft](https://learn.microsoft.com/en-us/windows/win32/api/msctf/nn-msctf-itfcontext).

Relevant for Keyman are the following API functions:

**`GetStatus()`** — Retrieves the current status of the text context. Keyman uses this to check for the TF_SS_TRANSITORY flag, which indicates temporary or non-standard contexts that may not behave consistently.

**`GetSelection()`** — Retrieves the current text selection or caret position.

**`SetSelection()`** — Updates the current selection or caret position after Keyman inserts or replaces text.

**`GetText()`** — Retrieves text from a specified range around the caret, giving Keyman the context needed to process complex keyboard rules.

**`SetText()`** — Replaces text in a specific range within the context.

Applications can restrict how much surrounding text can be read; Keyman limits its requests to 64 characters of context.

Keyman determines whether an application is compliant by inspecting the status returned by `ITfContext::GetStatus()`.

- **Compliant applications** provide a stable, non-transitory context and correctly implement the TSF APIs needed to retrieve context and modify text.
- **Non-compliant applications** may expose only a transitory context or fail to return reliable selection or text data.

If the `TF_SS_TRANSITORY` flag is present or context cannot not be read as expected, Keyman treats the application as non-compliant and falls back to legacy behavior, maintaining its own internal context buffer and simulating text operations where possible.

### Non-compliance on Windows

When a non-compliant application is detected, Keyman falls back to **legacy behavior**.

With non-compliant applications, Keyman maintains an **internal context buffer** that records the characters it has recently output. This buffered context is used to apply keyboard rules that depend on previously typed characters.


### Limitations of legacy behavior

The internal context buffer remains valid only while Keyman has exclusive knowledge of text changes. The buffer becomes invalid if the user performs actions such as:

- Moving the caret using the mouse or keyboard
- Changing the selection
- Using shortcut keys or menu commands to edit text
- Switching to another application or document

When such an action occurs, Keyman discards its internal context and assumes an empty context. If this happens in the middle of typing a multi-character sequence, the sequence may not be recognized correctly and may need to be retyped.

### Simulating text operations

Because TSF APIs cannot be relied upon in non-compliant applications, Keyman may simulate text operations by generating keyboard events:

- **Backspace key events** are used to delete previously typed characters
- **Synthetic key events** may be used to insert characters

These simulated events are asynchronous and are processed by the application in sequence. As a result, text deletion and insertion may not always behave exactly as intended, particularly when dealing with composed characters or surrogate pairs.