Skip to content

Commit c271166

Browse files
authored
Merge pull request #2326 from keymanapp/docs/windows/2061/non-compliant-apps
docs(windows): describe windows compliant app implementation with sequence diagram
2 parents dbe8072 + d961009 commit c271166

File tree

3 files changed

+53
-1
lines changed

3 files changed

+53
-1
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
sequenceDiagram
2+
autonumber
3+
participant User as User
4+
participant OS as Windows OS
5+
participant TSF as TSF Manager
6+
participant Keyman as Keyman TIP
7+
participant App as Application (Compliant)
8+
9+
User->>OS: Press key (e.g. 'D')
10+
OS->>TSF: Deliver key event
11+
TSF->>Keyman: Call OnKeyDown(ITfContext)
12+
13+
Note right of Keyman: Keyman create TIPEditSession & requests context
14+
Keyman->>TSF: ITfContext.GetStatus()
15+
Keyman->>TSF: ITfContext.GetSelection()
16+
TSF->>App: Request current selection
17+
App-->>TSF: Return selection
18+
TSF-->>Keyman: Return GetSelection
19+
20+
21+
Note right of Keyman: Keyman applies keyboard rules and inserts or modifies the text in the selection
22+
23+
Keyman->>TSF: ITfContext.SetSelection()
24+
TSF->>App: Modified selection is applied to the application
25+
26+
App-->>User: Display “∆” in document
1.14 MB
Loading

knowledge-base/kb0118.md

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,4 +223,30 @@ on the Keyman system service which emits a fake key event. That way it is possib
223223

224224
## Compliance on Windows
225225

226-
TODO
226+
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.
227+
228+
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, as a selection object, and insert or replace text.
229+
For `ITfContext` details see [Learn Microsoft](https://learn.microsoft.com/en-us/windows/win32/api/msctf/nn-msctf-itfcontext).
230+
231+
Relevant for Keyman are the following API functions:
232+
233+
**`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.
234+
235+
**`GetSelection()`** — Used by Keyman for Windows to get the context next to the cursor.
236+
237+
**`SetSelection()`** — Updates the current selection or caret position after Keyman inserts or replaces text in the selection retrieved with `GetSelection()`.
238+
239+
240+
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.
241+
242+
Applications can restrict how much surrounding text can be read; Keyman limits its requests to 64 characters of context.
243+
244+
<img src="./assets/kb0118/windows-compliant-app-sequence.png" width="75%" alt="compliant sequence on Windows"/>
245+
246+
The sequence diagram is for a rule that replaces "D" with "∆".
247+
248+
### Non-compliance on Windows
249+
250+
If the `TF_SS_TRANSITORY` flag is present or context cannot 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.
251+
252+
The limitations are as stated at the start of this knowledge base article [Working around non-compliant behavior](##-working-around-non-compliant-behavior). Further reading on sending a backspace to an application to perform a delete can be found on the Keyman wiki [here](https://github.com/keymanapp/keyman/wiki/Backspace-and-cluster-deletion).

0 commit comments

Comments
 (0)