Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
26 changes: 26 additions & 0 deletions knowledge-base/assets/kb0118/windows-compliant-app-sequence.mmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
sequenceDiagram
autonumber
participant User as User
participant OS as Windows OS
participant TSF as TSF Manager
participant Keyman as Keyman TIP
participant App as Application (Compliant)

User->>OS: Press key (e.g. 'D')
OS->>TSF: Deliver key event
TSF->>Keyman: Call OnKeyDown(ITfContext)

Note right of Keyman: Keyman create TIPEditSession & requests context
Keyman->>TSF: ITfContext.GetStatus()
Keyman->>TSF: ITfContext.GetSelection()
TSF->>App: Request current selection
App-->>TSF: Return selection
TSF-->>Keyman: Return GetSelection


Note right of Keyman: Keyman applies keyboard rules and inserts or modifies the text in the selection

Keyman->>TSF: ITfContext.SetSelection()
TSF->>App: Modified selection is applied to the application

App-->>User: Display “∆” in document
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 29 additions & 1 deletion knowledge-base/kb0118.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,4 +223,32 @@ on the Keyman system service which emits a fake key event. That way it is possib

## Compliance on Windows

TODO
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, as a selection object, 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()`** — Used by Keyman for Windows to get the context next to the cursor.

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


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.

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

<img src="./assets/kb0118/windows-compliant-app-sequence.png" width="75%" alt="compliant sequence on Windows"/>

The sequence diagram is for a rule that replaces "D" with "∆".

Note: For both compliant and non-compliant apps. When there is a highlighted section of text if backspace is the determined action from processing the keystroke on Windows Keyman will emit the key (backspace), allowing the application to handle clearing selected text in the correct manner.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sentence is hard to read and understand.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Reading it again, it is hard to understand.
The point I was trying to make in the in the higlighted text selection case when backspace is pressed, Keyman doesn't use SetSelection instead it emits the keystroke and leaves it up to the application to handle. I think this might be unique to Windows. However, I'm not sure it adds anything to this knowedge base which is more concerned with on complaint vs non-complaint behaviour. It is probably best not to mention it at all.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an interesting point which should be carried into our compatibility matrix discussion!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just dumped the note in the document EB had started so we dont' loose it.


### Non-compliance on Windows

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.

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).