/** * Placement for the hidden textarea that terminals and Wayland surfaces use * to capture IME composition. * * The host's IME draws its candidate window against the caret of the focused * editable element — which, for a view that paints its own text into a * canvas, is a 1px capture textarea that has nothing to do with where the * text is going. Parked in the corner, every composition popup opens in the * corner too, far from the words it is composing. Moving the capture * element over the *remote* caret is the whole trick: the IME then places * itself as it would in a real text field. */ /** A caret, in client coordinates (CSS pixels, as `getBoundingClientRect`). */ export interface CaretRect { left: number; top: number; /** Caret height. The IME opens its candidate window clear of this. */ height: number; } /** * The caret of a character grid, in client coordinates. * * The grid is laid out in CSS pixels (`cell.w`/`cell.h`) but centred inside * its canvas by an offset in *device* pixels, which is the one conversion * this is here to not get wrong. */ export declare function gridCaretRect(canvasOrigin: { left: number; top: number; }, cell: { w: number; h: number; pw: number; ph: number; }, offset: { x: number; y: number; }, col: number, row: number): CaretRect; /** * Park `el` over `caret`, or back at the screen's top-left corner when there * is no caret to point at (`null`). * * The corner is the historical resting place and stays the fallback for a * reason: an assist target there can never end up under a software keyboard, * so iPadOS never pans the page to reveal it. A caret keeps that property by * being clamped into the *visual* viewport, which is the part of the page the * keyboard leaves visible. * * Writes are deduped against the element's own inline style, so the render * loop can call this every frame. */ export declare function placeImeTarget(el: HTMLElement, caret: CaretRect | null): void; /** * Park a suggestion chip on the caret's own line, starting at the cursor, so * it reads as the continuation of what is being typed. * * It floats rather than occupying cells: those belong to the app, which may * be drawing its own suggestion in them. When the line has run too close to * the right edge for the chip to fit, it drops under the line instead — and * under a software keyboard that leaves no room below, above it. * * Unlike the capture element this one is *seen*, so it is sized by its own * content: the caller must have it laid out (non-empty, not `display:none`) * before calling, and `size` comes from the element itself. */ export declare function placeChip(el: HTMLElement, caret: CaretRect, size: { width: number; height: number; }): void; //# sourceMappingURL=imeTarget.d.ts.map