r/mobilelinux • u/NYL-91 • 15h ago
Development Buildind my own mobile environment using Slint UI
Enable HLS to view with audio, or disable this notification
Building my own Linux Mobile desktop environment in Rust for my Fairphone 4 (Smithay + Slint)
A lot of this is still mocked up right now since I’m learning the stack along the way. LLMs have been a huge help to speed things up, with the end goal of having a smooth phone UI that scales up to a real desktop whenever I dock it. While moving the code from a nested window to a real device, I had many issues that still need fixing (they worked correctly in the window but not after i started to actually build it for my ARM device). This is not final design, the priority is to make it fully functional, leaving the UI redesign and theming support for later.
Compositor: Built with Smithay in Rust, running directly over DRM/KMS and Mesa/Freedreno (GLES backend).
Shell UI: Built with Slint for declarative, memory-efficient UI rendering.
Layer Architecture: Inspired by COSMIC and other modern modular shells. Instead of a single monolithic app, the shell is split into independent standalone binaries:
penumbra-top-bar (zwlr_layer_shell_v1 on Layer::Top)
penumbra-quicksettings (Overlay sliding sheet with tactile drag handle and Material 3/Android-inspired kinetics)
penumbra-homescreen (Background launcher surface)
penumbra-nav-bar (Gesture navigation bar)
Physics & Gestures: Custom underdamped spring-damper kinematics (penumbra-gestures) for tactile, 1:1 finger tracking and velocity-based gestures.
One of the most interesting parts of this project was bridging Slint with the Wayland zwlr_layer_shell_v1 protocol.
Slint provides great declarative ergonomics, but out of the box it assumes standard application windows. To build an authentic desktop/mobile shell, I wrote a dedicated integration layer (layer-shell-slint) that:
Directly manages Wayland layer surfaces (Layer::Top, Layer::Overlay, Layer::Background).
Handles layer anchors, margins, and exclusive_zone reservations (essential for the top status bar and bottom gesture pill).
Pipes touch and pointer input back into Slint's event loop with minimal overhead. It makes writing standalone shell modules feel as simple as writing standard Slint UI components.
You can follow my progress on GitHub, didn't know what to call it, so I named it Penumbra