Slint Kit Documentation

Focus management

Focus Target for Slint

KitFocusTarget · Slint Kit 0.3.1

Bridge between an actual visual target and focus-registry requests.

Bridge between an actual visual target and focus-registry requests.
Native app built from the example below.

Try the component

Download the complete project, extract it and run cargo run --locked in its folder. Rust 1.92+; Slint Kit 0.3.0 from crates.io. You can also copy the four files below.

Click the button: Rust publishes a fresh focus request; then type into Project name.

ui/app.slint

export { KitFormValidation, HtmlInputKind, NumberInputFormat, KitInputConstraints, KitValidationResult, KitValidityState } from "@kit/kit.slint";
// SPDX-License-Identifier: GPL-3.0-or-later
import { KitFocusTarget, KitTextField, KitThemes, FocusRequest, KitButton } from "@kit/kit.slint";
export { FocusRequest }
export component App inherits Window {
    title: "KitFocusTarget";
    preferred-width: 460px;
    preferred-height: 260px;
    max-width: 100000px;
    max-height: 100000px;
    background: KitThemes.light.canvas;
    in-out property <string> draft;
    in property <FocusRequest> focus-request;
    callback request-focus();
    VerticalLayout {
        padding: 24px; spacing: 16px; alignment: start;
        KitButton { text: "Focus project name"; activated => { root.request-focus(); } }
        KitFocusTarget {
            token: 42; generation: 1; request: root.focus-request;
            focus-requested => { editor.take-focus(); }
            editor := KitTextField { label: "Project name"; text <=> root.draft; }
        }
        Text { text: "Draft: " + root.draft; color: KitThemes.light.text-primary; }
    }
}

src/main.rs

// SPDX-License-Identifier: GPL-3.0-or-later
use slint::ComponentHandle;
use std::cell::Cell;
slint::include_modules!();

fn main() -> Result<(), slint::PlatformError> {
    let app = App::new()?;
    slint_kit::init_form_validation!(self, app);
    let sequence = Cell::new(0_i32);
    let weak = app.as_weak();
    app.on_request_focus(move || {
        if let Some(app) = weak.upgrade() {
            let request = sequence
                .get()
                .checked_add(1)
                .expect("focus request capacity");
            sequence.set(request);
            app.set_focus_request(FocusRequest {
                present: true,
                token: 42,
                generation: 1,
                request,
            });
        }
    });
    app.run()
}

Cargo.toml and build.rs

Cargo.toml

[package]
name = "slint-kit-focus-target-example"
version = "0.1.0"
edition = "2024"
rust-version = "1.92"
license = "GPL-3.0-or-later"
publish = false

[dependencies]
slint-kit = "=0.3.0"
slint = { version = "=1.18.1", default-features = false, features = ["std", "compat-1-18", "backend-winit", "renderer-skia", "accessibility"] }

[build-dependencies]
slint-kit-build = "=0.3.0"

[workspace]

build.rs

fn main() {
    slint_kit_build::compile("ui/app.slint").expect("compile component example");
}

Files: Cargo.toml · build.rs · ui/app.slint · src/main.rs

Assign a stable token and generation. Publish a new FocusRequest from Rust for each request, then forward focus-requested to the native editor’s take-focus().

A FocusRequest applies only when token, generation and eligibility match, once per request identifier. A recycled target must change generation; focus-applied acknowledges the processed request.

Visual composition

The file below produces the screenshot. For controller-driven components, it shows the displayed state without supplying the Rust wiring. Create a project.

Show the screenshot source
Bridge between an actual visual target and focus-registry requests.
Native screenshot of the same example, rendered with Skia.
// SPDX-License-Identifier: GPL-3.0-or-later
import { KitFocusTarget, KitTextField, KitTheme, KitThemes } from "@kit/kit.slint";

export component Example inherits Window {
    title: "KitFocusTarget example";
    preferred-width: 420px;
    preferred-height: 180px;
    max-width: 100000px;
    max-height: 100000px;
    background: root.theme.canvas;
    in-out property <KitTheme> theme: KitThemes.light;
    in-out property <string> status;
    VerticalLayout {
        padding: 24px; spacing: 16px; alignment: start;
        Text { text: "Focus Target"; color: root.theme.text-primary; font-size: 20px * root.theme.text-scale; font-weight: 600; }
        KitFocusTarget { token: 42; generation: 1; request: { present: true, token: 42, generation: 1, request: 1 }; focus-requested => { editor.take-focus(); } editor := KitTextField { theme: root.theme; label: "Project name"; text: "Field notes"; } }
        if root.status != "": Text { text: root.status; color: root.theme.text-secondary; font-size: 12px * root.theme.text-scale; wrap: word-wrap; }
    }
}

Download this example

Public API

Inherits FocusScope.

Properties

Name Type Direction
token int in
generation int in
eligible bool in
request FocusRequest in

Types and variants

Type Declaration
struct FocusRequest present: bool, token: int, generation: int, request: int

Callbacks

See also