94a2686dcbe832bc0494a4557539d852851a09da
Four faults that only show on a device, and one that was hiding on the desktop too. The system bars. Target SDK 36 forces edge-to-edge, so the window spans the display and the develop status strip was drawn underneath the clock and the wifi icons. Slint already computes the inset from Android's OnApplyWindowInsetsListener and exposes it as Window.safe-area-insets; nothing read it. The four views now sit inside a shell placed within the safe area. Every inset is zero on the desktop, so that layout does not move. Sliders under a finger. A Flickable steals any gesture that drifts more than 8 logical pixels along its scrolling axis within half a second of the press, and it steals it by cancelling the child. ParamSlider's axis test correctly declined to claim vertical drags, but nothing told the Flickable to stand down once a drag was claimed — so an adjustment would start moving and then be taken away mid-motion. A mouse holds a horizontal line closely enough to stay under 8px; a finger does not, which is why these worked on the desktop and not on the tablet. The claim now sets `interactive: false` for the rest of the gesture. The tone curve had the same fault and worse: its points are dragged vertically, which is the Flickable's own axis, so every drag was stolen — on the desktop as well. The back gesture. Nothing handled it, so back closed the application from anywhere in it. Android delivers it as Key.Back to the focused item and bubbles it up the ancestors, which is the second reason the shell wraps the views rather than sitting beside them. The order is innermost first: settings, then crop, then zoom, then develop to the grid, then a collection scope. Answering false at the top of the stack leaves Android to close the activity, as it does for every other application there. Escape does the same on a keyboard. back_step is a pure function over a flat NavState so the ordering can be tested without a backend: which of two states is left first is the whole of the feature, and it is the part that is easy to get subtly wrong when spelled out in nested ifs over live properties. Develop's canvas now takes focus on show. Without it the arrow keys did nothing until the canvas was clicked, and Key.Back had no focus item to bubble from. Panels that close. The collections sidebar and the develop column are collapsible from the grid header and the status strip. The layout class now supplies only the default: a panel closed to see more of a photograph stays closed while the window keeps its shape, and the choice is dropped when the class changes, because rotating a tablet asks a different question from the one answered in landscape. IMAGE became a Section, being the only group in the column that could not be put away and the one whose content is read first and needed least. Pinch to zoom on the develop canvas, anchored on the midpoint between the fingers (FR-UI-4). The wheel is the desktop's answer and there is no wheel on a tablet. The develop status strip was 28px against the 44px headers on the library and settings pages either side of it — the one screen where a way out has to be found was the one drawn smallest. All three now agree. Verified with cargo test -p dr-ui (192 passing, 6 new), clippy at -D warnings, and an arm64-v8a release build packaged to an APK. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
DarkRoom
A cross-platform, non-destructive RAW photo editor for Linux and Android.
Status: early. v0.1 is a remote library viewer — see docs/milestone-v0.1.md.
Documentation
| Document | Contents |
|---|---|
| requirements.md | What the software must do — 122 numbered requirements |
| architecture.md | How it is built — crates, GPU pipeline, data model, sync |
| milestone-v0.1.md | The first buildable milestone |
Building
Desktop:
cargo run -p darkroom-desktop
Android (containerised toolchain, see docker/android):
./docker/android/build.sh cargo ndk -t arm64-v8a build --release
Current state
Working: workspace, GPU context and compute pass, adaptive Slint shell, Android cross-compilation of the core crates.
Not yet working: the zero-copy display path. The build currently uploads frames through the CPU, which is exactly what ARCH §6.1 forbids — measured at 96% of frame time at 4K. Replacing it is spike S1, the project's highest priority.
cargo run -p dr-gpu --example bench --features readback
reproduces that measurement.
Licence
GPL-3.0-or-later.
Releases
20
DarkRoom 0.24.0
Latest
Languages
Rust
86.1%
Slint
10.3%
Python
1.1%
Shell
1%
WGSL
0.9%
Other
0.6%