On a page with forge/web an ltk app had a main surface, overlays and subsurfaces, but none of what a shell such as crustace needs from the compositor: fullscreen did nothing, the app heard nothing of the other windows, an activation token it asked for never came, forge/web was never told when a launched window had shown, the shell could not speak its protocol, and the app had no way to read its own files in a browser. Each now goes through the app's connection to forge/web, in the shape of the Wayland protocol it stands for. Fullscreen. On a page with forge/web, `App::fullscreen` and `App::start_fullscreen` send a `set_fullscreen` request for the main window, as `xdg_toplevel.set_fullscreen` does, instead of doing nothing; alone on a page the canvas still takes the browser's fullscreen. `examples/web_hello.rs` gains a button that toggles it. The desktop's windows. On connecting, the backend asks for the list of toplevels, and forge/web's `toplevel_opened` and `toplevel_closed` events become `ToplevelEvent`s for `App::on_toplevel_event`, as `ext-foreign-toplevel-list-v1` does on Wayland, so a shell's dock knows which applications have windows open. Activation. The tokens an app asks for with `App::take_activation_requests` are issued before it draws: forge/web's, through its `activation_token` request, or empty without a desktop, as on Wayland without xdg-activation, and handed to `App::on_activation_token` with their messages processed. A browser app that launched others through tokens waited for one that never came. Each surface's first presented frame is reported with a `presented` request (`WebSurfaceState::presented`), so forge/web knows when a window it launched has shown and can report it activated, which dismisses crustace's splash. The shell protocol. `platform/web/shell.rs` carries the JSON a shell speaks to forge over its socket over the app's connection to forge/web: `ltk::web::shell_send( json )` sends it as a `shell` request, and each `shell` event's message reaches the listener `ltk::web::set_shell_listener` gives, as JSON. What is sent before the app has connected is kept and sent once it has, so a shell can tell forge/web its theme while it starts. An overlay's role now carries its `App::overlay_namespace`, as its layer-shell namespace does on Wayland, so forge/web can tell a shell's overlays apart. The cursor over every surface. The CSS `cursor` was set on the main surface's element only, so over an overlay the pointer kept the page's arrow. `WebSurfaceState` keeps the element that takes its input, the shape moves to that of the surface the pointer enters, and `WebPlatform::cursor` keeps the last one asked for. An app's own files. `ltk::vfs`, through which ltk reads its themes, fonts and keyboard layouts, is public: `read`, `read_to_string`, `read_dir`, `is_file` and `is_dir` read the file system natively and, in a browser, the files the page loaded into memory. `ltk::web::load_tree( base, root ).await` loads any tree served with a `MANIFEST` under `root`, and `load_resources` is that into `/ltk` with the directory made the resource directory. `ltk::time::Instant` is public too, `std`'s natively and `web_time`'s on wasm32, where `std::time::Instant::now` panics, so an app that builds for both measures time with ltk's clock. wasm-bindgen-cli. `scripts/wasm-bindgen-cli.sh TOOLS_DIR` builds wasm-bindgen-cli into `TOOLS_DIR/bin` at the version of the `wasm-bindgen` crate ltk pins in its `Cargo.toml`, from its sources with a lock resolved for Debian's rustc, which is what `make web-deps` did inline and now runs. Since `make install` copies `scripts/` into the registry, a project that builds for the browser against the installed ltk, such as forge/web or crustace, gets the same CLI without a checkout of ltk. The README and docs/architecture.md say so. Images named by their caller. Every draw through `draw_image_data` fingerprints its pixels to find them in the image caches, which for a terminal means hashing every glyph of every frame. `Canvas::draw_image_keyed( key, rgba, w, h, dest, opacity )` is `draw_image_data` with `key` naming the pixels in place of their fingerprint: every draw with the same key must pass the same pixels, which are read only when the image is not cached. Both backends' caches are keyed by `ImageId`, `Content` for a fingerprint and `Keyed` for a caller's key, so a key never names an image drawn by content even when it equals its fingerprint. `GlesCanvas` and `SoftwareCanvas` gain `draw_image_keyed`, and their `draw_image_data` and it share one private `draw_image`. Tests check that a keyed image draws as its pixels do and that a key equal to a fingerprint is another image. A held button is not also tapped. A button with `on_long_press` and no `on_drag_start` stayed a tap after its hold fired, so releasing it sent its `on_press` as well. `GestureState::long_press_msg_fired` is set when the hold fires `long_press_msg` and suppresses the press message on release; a test covers it. `CHANGELOG.md` describes these changes.
160 lines
7.4 KiB
Makefile
160 lines
7.4 KiB
Makefile
REGISTRY ?= /usr/share/cargo/registry/ltk
|
|
DOCDIR ?= /usr/share/doc/libltk-doc/html
|
|
|
|
# The Android build uses Debian's own packages: rustc and rust-src of the
|
|
# same version, whose std `-Zbuild-std` compiles for the target, and the NDK
|
|
# that google-android-ndk-r27c-installer (non-free) unpacks.
|
|
NDK ?= /usr/lib/android-sdk/ndk/27.2.12479018
|
|
ANDROID_API ?= 26
|
|
ANDROID_TARGET ?= aarch64-linux-android
|
|
NDK_BIN = $(NDK)/toolchains/llvm/prebuilt/linux-x86_64/bin
|
|
NDK_CC = $(NDK_BIN)/$(ANDROID_TARGET)$(ANDROID_API)-clang
|
|
ANDROID_ENV = RUSTC_BOOTSTRAP=1 \
|
|
CC_$(subst -,_,$(ANDROID_TARGET))=$(NDK_CC) \
|
|
CXX_$(subst -,_,$(ANDROID_TARGET))=$(NDK_CC)++ \
|
|
AR_$(subst -,_,$(ANDROID_TARGET))=$(NDK_BIN)/llvm-ar \
|
|
CARGO_TARGET_$(shell echo $(ANDROID_TARGET) | tr a-z- A-Z_)_LINKER=$(NDK_CC)
|
|
ANDROID_CARGO = -Zbuild-std=std,panic_abort --target $(ANDROID_TARGET) --no-default-features --features android
|
|
# Where `android-assets` writes the `ltk/` tree an APK carries under `assets/`.
|
|
ANDROID_ASSETS ?= target/android/assets
|
|
# The example APK, packaged with aapt, zipalign, apksigner and
|
|
# android-framework-res, and installed with adb (android-sdk-platform-tools).
|
|
ANDROID_ABI ?= arm64-v8a
|
|
ANDROID_APK ?= target/android/ltk-hello.apk
|
|
|
|
# The browser build uses Debian's std for wasm32 (libstd-rust-dev-wasm32) and
|
|
# wasm-bindgen-cli, which Debian does not package and whose version must be
|
|
# the one of the wasm-bindgen crate ltk pins.
|
|
WEB_TARGET = wasm32-unknown-unknown
|
|
WEB_CARGO = --target $(WEB_TARGET) --no-default-features --features web
|
|
WEB_OUT ?= target/web
|
|
# web_hello runs alone on a page; web_shell needs forge/web, whose `make hello` serves both.
|
|
WEB_EXAMPLES = web_hello web_shell
|
|
# Fallback fonts a page bundles beyond the theme's, for text Sora does not
|
|
# cover: Cyrillic, Greek and extended Latin, symbols, arrows and box drawing.
|
|
WEB_FONTS ?= $(wildcard /usr/share/fonts/truetype/noto/NotoSans-Regular.ttf /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf /usr/share/fonts/truetype/noto/NotoSansSymbols2-Regular.ttf)
|
|
# Where web-deps installs wasm-bindgen-cli, so nothing needs to be on PATH;
|
|
# one already on PATH is used when there is none here.
|
|
WEB_TOOLS = target/tools
|
|
WASM_BINDGEN ?= $(or $(wildcard $(WEB_TOOLS)/bin/wasm-bindgen),$(shell command -v wasm-bindgen 2>/dev/null))
|
|
|
|
# Targets are recipes, not files. Listing them as PHONY tells make to
|
|
# ignore filesystem entries with the same name — without this `examples`
|
|
# silently no-ops because the `examples/` directory exists, and `doc`
|
|
# would do the same once `target/doc` is around.
|
|
.PHONY: all deps android-deps test doctest-md stylecheck clippy audit doc install examples clean distclean android-check android-assets android-apk android-install web-deps web-check web-assets web-example web-serve
|
|
|
|
all:
|
|
cargo build --release
|
|
|
|
# What building, testing and linting need, from Debian.
|
|
deps:
|
|
sudo apt-get install -y cargo rustc rust-clippy pkg-config libwayland-dev libegl-dev libxkbcommon-dev
|
|
|
|
# What the android-* targets need, from Debian: std's sources for -Zbuild-std,
|
|
# the NDK installer (non-free), the APK tools, rsvg-convert for SVG icons, javac, dx and
|
|
# android.jar (non-free) for the keep-alive service, and adb.
|
|
android-deps:
|
|
sudo apt-get install -y rust-src google-android-ndk-r27c-installer aapt zipalign apksigner android-framework-res librsvg2-bin default-jdk-headless art-standalone google-android-platform-34-installer android-sdk-platform-tools
|
|
|
|
test:
|
|
cargo test --features test-support
|
|
|
|
# Typecheck the `no_run` snippets in docs/*.md by feeding each markdown
|
|
# file to `rustdoc --test`. Catches API drift in cookbook + widget
|
|
# reference: drops a renamed builder, removed function, etc. surface
|
|
# here just like `cargo test --doc` does for in-source doctests.
|
|
doctest-md:
|
|
./scripts/doctest-md.sh
|
|
|
|
# Mechanical style checks (tabs, attribute-bracket spacing) — the
|
|
# grep-verifiable subset of code_style_guide.md.
|
|
stylecheck:
|
|
./scripts/style-check.sh
|
|
|
|
# Semantic lints, mirroring the CI invocation. Warnings are errors so a
|
|
# local run predicts the CI verdict.
|
|
clippy:
|
|
cargo clippy --workspace --all-targets --features test-support -- -D warnings
|
|
|
|
# Typecheck the Android backend. Needs rust-src and the NDK (see NDK above).
|
|
android-check:
|
|
@test -x $(NDK_CC) || { echo "No NDK compiler at $(NDK_CC); install google-android-ndk-r27c-installer or set NDK="; exit 1; }
|
|
$(ANDROID_ENV) cargo check $(ANDROID_CARGO)
|
|
|
|
# The in-tree default theme and the fonts it names, as an APK carries them.
|
|
android-assets:
|
|
./scripts/android-assets.sh $(ANDROID_ASSETS) themes default
|
|
|
|
# examples/android_hello.rs as an APK, with the in-tree default theme.
|
|
android-apk: android-assets
|
|
@test -x $(NDK_CC) || { echo "No NDK compiler at $(NDK_CC); install google-android-ndk-r27c-installer or set NDK="; exit 1; }
|
|
$(ANDROID_ENV) cargo build --release --example android_hello $(ANDROID_CARGO)
|
|
ANDROID_ABI=$(ANDROID_ABI) MIN_SDK=$(ANDROID_API) ./scripts/android-apk.sh $(ANDROID_APK) \
|
|
target/$(ANDROID_TARGET)/release/examples/libandroid_hello.so net.liberux.ltk.Hello "ltk hello" $(ANDROID_ASSETS)
|
|
|
|
android-install: android-apk
|
|
adb install -r $(ANDROID_APK)
|
|
|
|
# What the web-* targets need: Debian's std for wasm32, and wasm-bindgen-cli at the version ltk pins, which scripts/wasm-bindgen-cli.sh builds.
|
|
web-deps:
|
|
sudo apt-get install -y libstd-rust-dev-wasm32 curl
|
|
./scripts/wasm-bindgen-cli.sh $(WEB_TOOLS)
|
|
|
|
# Typecheck the browser backend.
|
|
web-check:
|
|
cargo check $(WEB_CARGO)
|
|
|
|
# The in-tree default theme, the fonts it names and $(WEB_FONTS), as a page serves them.
|
|
web-assets:
|
|
EXTRA_FONTS="$(WEB_FONTS)" ./scripts/web-assets.sh $(WEB_OUT) themes default
|
|
|
|
# examples/web_hello.rs as a page under $(WEB_OUT), with its resources.
|
|
web-example: web-assets
|
|
@test -n "$(WASM_BINDGEN)" || { echo "No wasm-bindgen in $(WEB_TOOLS)/bin or on PATH; run make web-deps"; exit 1; }
|
|
cargo build --release $(addprefix --example ,$(WEB_EXAMPLES)) $(WEB_CARGO)
|
|
for example in $(WEB_EXAMPLES); do \
|
|
$(WASM_BINDGEN) --target web --no-typescript --out-dir $(WEB_OUT)/pkg target/$(WEB_TARGET)/release/examples/$$example.wasm || exit 1; \
|
|
done
|
|
cp web/index.html $(WEB_OUT)/
|
|
|
|
web-serve: web-example
|
|
cd $(WEB_OUT) && python3 -m http.server 8000
|
|
|
|
audit:
|
|
@command -v cargo-audit >/dev/null 2>&1 || cargo install cargo-audit --locked
|
|
cargo audit
|
|
|
|
doc:
|
|
cargo doc --no-deps
|
|
|
|
install: doc
|
|
install -d $(REGISTRY)
|
|
cp -r src benches examples locales protocols keyboards scripts java web build.rs Cargo.toml liberux.toml $(REGISTRY)/
|
|
cp debian/cargo-checksum.json $(REGISTRY)/.cargo-checksum.json
|
|
install -d $(DOCDIR)
|
|
cp -r target/doc/* $(DOCDIR)/
|
|
|
|
examples:
|
|
LTK_THEMES_DIR=themes cargo run --release --example showcase
|
|
LTK_THEMES_DIR=themes cargo run --release --example responsive
|
|
LTK_THEMES_DIR=themes cargo run --release --example inputs
|
|
LTK_THEMES_DIR=themes cargo run --release --example scroll
|
|
LTK_THEMES_DIR=themes cargo run --release --example sliders
|
|
LTK_THEMES_DIR=themes cargo run --release --example combo
|
|
LTK_THEMES_DIR=themes cargo run --release --example mini_shell
|
|
LTK_THEMES_DIR=themes cargo run --release --example widgets
|
|
LTK_THEMES_DIR=themes cargo run --release --example pickers
|
|
LTK_THEMES_DIR=themes cargo run --release --example dialog
|
|
LTK_THEMES_DIR=themes cargo run --release --example carousel
|
|
LTK_THEMES_DIR=themes cargo run --release --example clip_path
|
|
LTK_THEMES_DIR=themes cargo run --release --example tab_strip
|
|
|
|
clean:
|
|
dh_clean
|
|
cargo clean
|
|
rm -rf target
|
|
|
|
distclean: clean
|
|
rm -f Cargo.lock
|