Linux Mobile Apps
Writing a Linux Mobile App
I recently got my hands on a Linux mobile running Phosh and PostmarketOS and am pretty happy with it. However there are a bunch of apps and features that I'd like, particularly integrations with Immich for photos and Navidrome for music streaming.
The most common Linux mobile apps seem to be based in the GNOME ecosystem, using gtk as a base UI toolkit and libadwaita for combined desktop and mobile UI support. I've spent plenty of time working with Qt before - but this is a first dip into the world of GTK.
Apparently new native applications should consider Rust over C and C++ (which I'm pretty familiar with). So, this seems like a good time to try to pick up some Rust as well. This (old) intro for C++ people seems useful: https://fasterthanli.me/articles/a-half-hour-to-learn-rust
Setting up the Development Environment
First, I want to set up a development environment. I'm using Guix, which will make this reproducible - although I hear doesn't play so nicely with Rust.
Let's get a Rust environment going in Guix shell. First I use guix search to see if I can find something claiming to be a rust toolchain:
guix search rust
It looks like a package called rust will do the job:
guix shell rust
I'm aware of Rust bindings for GTK (there is even a book). It seems like rust-gtk4 will do the job. As I build up shell packages it is time to start a manifest:
guix shell rust rust-gtk4 --export-manifest > manifest.scm
and load the shell with:
guix shell -m manifest.scm
I may later regret this, but I'm going to try to bundle the project with meson so will add meson and pkg-config to the environment.
Following the gtk-rs book I start with a hello-world:
use gtk::prelude::*;
use gtk::{glib, Application};
const APP_ID: &str = "org.gtk_rs.HelloWorld1";
fn main() -> glib::ExitCode {
// Create a new application
let app = Application::builder().application_id(APP_ID).build();
// Run the application
app.run()
}
Now we hit some issues. First, I need some Rust support in my Emacs and second, unsurprisingly, this doesn't compile with rustc since it doesn't know the path to the gtk crate. The emacs rustic package with rust-analyzer seem to be the way to go.
So, how do I combine gtk, rust and meson - well it seems like some horrible mix of cargo and meson boilerplat: captured here https://gitlab.gnome.org/World/Rust/gtk-rust-template/-/tree/master with more background here: https://coaxion.net/blog/2023/04/building-a-gstreamer-plugin-in-rust-with-meson-instead-of-cargo/
Let's go for it.