Skip to content
Open
Show file tree
Hide file tree
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
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- **Versioned IME contract (v2)** — additive `IMEControllerV2`,
`IMEEventSourceV2`, and `IMECapabilityProviderV2` interfaces. Existing
`EventSource` and `IMEController` implementations remain valid.
- **IME payload/range types** — UTF-8 byte-offset composition and surrounding
text ranges, candidate cursor area, cancellation, and delete-surrounding
events.
- **ContentPurpose/ContentHint** — cross-platform content type values and ten
advisory hint flags, plus capability discovery helpers.

## [0.28.0] - 2026-08-13

### Added
Expand Down
44 changes: 44 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ go get github.com/gogpu/gpucontext
- **ScrollEventSource** — Scroll/wheel events with pixel/line/page modes
- **Texture** — Minimal interface for GPU textures with TextureUpdater/TextureRegionUpdater/TextureDrawer/TextureCreator
- **IME Support** — Input Method Editor for CJK languages (Chinese, Japanese, Korean)
- **Versioned IME contract** — optional cursor ranges, surrounding text, content purpose/hints, cancellation, and capability discovery without changing existing implementors
- **WindowChrome** — Custom window chrome for frameless windows (hit testing, minimize/maximize/close) + runtime fullscreen toggle
- **Registry[T]** — Generic registry with priority-based backend selection
- **WebGPU Interfaces** — Device, Queue, Adapter, Surface interfaces
Expand Down Expand Up @@ -199,6 +200,49 @@ func (input *TextInput) Focus(controller gpucontext.IMEController) {
}
```

#### Versioned IME extension

The original `EventSource` and `IMEController` interfaces are kept intact. A
host that supports the richer contract implements the optional `V2` interfaces
and advertises the operations it can provide:

```go
if caps, ok := gpucontext.DiscoverIMECapabilities(app); ok {
if caps.Supports(gpucontext.IMECapabilityContentPurpose |
gpucontext.IMECapabilityContentHints) {
if controller, ok := app.(gpucontext.IMEControllerV2); ok {
controller.SetIMEContentType(
gpucontext.ContentPurposePassword,
gpucontext.ContentHintSensitiveData|gpucontext.ContentHintHiddenText,
)
}
}
}

if source, ok := app.(gpucontext.IMEEventSourceV2); ok {
source.OnIMECompositionUpdateV2(func(state gpucontext.IMEComposition) {
// CursorBegin/End and SelectionStart/End are half-open UTF-8 byte
// ranges into CompositionText (not rune or UTF-16 indexes).
// Check HasCursor before drawing a caret: -1,-1 hides it.
renderPreedit(state.CompositionText, state.CursorRange())
})
source.OnIMECanceled(func() { clearPreedit() })
source.OnIMEDeleteSurrounding(func(event gpucontext.IMEDeleteSurroundingEvent) {
// Before and After are UTF-8 byte counts around the current cursor.
deleteSurrounding(event.Before, event.After)
})
}
```

`IMECursorArea` uses logical DIP relative to the window content area, matching
`WindowProvider` and pointer callbacks. `IMESurroundingText.Cursor` and
`Anchor` are UTF-8 byte offsets and preserve selection direction. Hosts must
convert to native UTF-16 or protocol units at the platform boundary and must
not expose surrounding text while IME is disabled. A provider may implement
`IMEEventSourceV2`, `IMEControllerV2`, and `IMECapabilityProviderV2`
independently; consumers should check capability bits rather than assuming a
platform supports every operation.

### Texture Interface

`Texture` provides a minimal interface for GPU textures, enabling sharing between packages:
Expand Down
3 changes: 2 additions & 1 deletion doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
// projects to enable GPU resource sharing without circular dependencies:
//
// - DeviceProvider: Interface for providing GPU device and queue
// - EventSource: Interface for window/input events (keyboard, mouse)
// - EventSource: Interface for window/input events (keyboard, mouse, legacy IME)
// - IMEControllerV2/IMEEventSourceV2: Optional versioned IME contract
// - PointerEventSource: Interface for unified pointer events (W3C Level 3, mouse+touch+pen)
// - WindowProvider: Interface for window geometry, DPI, and redraw requests
// - PlatformProvider: Interface for clipboard, cursor, dark mode, accessibility
Expand Down
16 changes: 15 additions & 1 deletion events.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,27 @@ type IMEState struct {
CompositionText string

// CursorPos is the cursor position within the composition text.
//
// This field is retained for compatibility with the original v1 contract.
// Versioned IME providers should also populate CursorBegin and CursorEnd;
// when the cursor is collapsed, CursorPos should equal CursorBegin.
CursorPos int

// CursorBegin is the first UTF-8 byte of the active cursor range within
// CompositionText. It is available to consumers using IMEContractVersion.
CursorBegin int

// CursorEnd is the first UTF-8 byte after the active cursor range within
// CompositionText. A collapsed cursor has CursorBegin == CursorEnd.
CursorEnd int

// SelectionStart is the start of the selection within the composition text.
// This is used for candidate selection in some IME systems.
// This is used for candidate selection in some IME systems. Versioned IME
// providers report it as a UTF-8 byte offset.
SelectionStart int

// SelectionEnd is the end of the selection within the composition text.
// Versioned IME providers report it as a UTF-8 byte offset.
SelectionEnd int
}

Expand Down
Loading
Loading