Skip to content
jptr-techPublic

About

GTK4 Mail Client

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

20 Commits

Folders and files

Repository files navigation

Jmail

The best GTK email client (for me at least :p)

Features

  • Joined Inbox across multiple accounts, adaptive three-pane layout.
  • Gmail-style vim keybindings (j/k, o, e, #, s, …).
  • HTML mail rendered with WebKitGTK.
  • Compose in markdown with live inline styling and a rendered preview.
  • Recipient autocomplete from people you have sent to and your GNOME address book.
  • GOA integration + custom IMAP support.

Requirements

  • Flatpak — for the sandboxed build, or

  • A local toolchain: Rust, plus GTK4, libadwaita, and WebKitGTK development files. On Fedora:

    sudo dnf install gtk4-devel libadwaita-devel webkitgtk6.0-devel \
        javascriptcoregtk6.0-devel libsoup3-devel

Running

Flatpak (recommended)

make flatpak     # build + install
make run         # ...or run the cargo crate
flatpak run tech.jptr.jmail

make flatpak runs the equivalent of:

flatpak-builder --user --install --force-clean --assumeyes \
  --disable-rofiles-fuse --state-dir=.flatpak-builder build-dir tech.jptr.jmail.yaml

Locally with Cargo

make run         # = cargo run -p jmail-ui

Other targets: make test, make mock, make clean, make help.

The cache lives at ~/.local/share/jmail/cache.db (local runs) or ~/.var/app/tech.jptr.jmail/data/jmail/cache.db (Flatpak).

Useful environment variables:

Variable Effect
JMAIL_DEV_PLAINTEXT=1 Store passwords in the DB instead of the system keyring (dev).
JMAIL_SEED=1 Insert demo accounts/messages on first launch.
RUST_LOG=debug Verbose sync-engine and IMAP connect/auth logging.

Test server

A mock IMAP server ships in the workspace (crates/jmail-mock-imap) with a canned mailbox and live IDLE push — perfect for trying the app without a real account. It also runs a companion SMTP server that captures anything the app sends, so you can exercise compose/reply/drafts locally.

Start it from the repo root (plaintext, default IMAP port 1143):

cargo run -p jmail-mock-imap

It prints both listeners, e.g. Mock IMAP listening on 127.0.0.1:1143 and Mock SMTP listening on 127.0.0.1:2525. The SMTP port is stable by default (2525) so the account setting survives restarts — use it when adding the account (see below).

Server options

cargo run -p jmail-mock-imap -- [--port N] [--smtp-port N] [--tls] [--push-after N]
Flag Meaning
--port N IMAP listen port N (default 1143).
--smtp-port N SMTP listen port N (default 2525; 0 picks a free port).
--tls Enable implicit TLS / STARTTLS with a self-signed cert.
--push-after N After N seconds, inject a new Inbox message to exercise IDLE push.

The demo mailbox has the folders INBOX, Sent, Drafts, Archive, Trash, Spam, Projects, with sample messages (including an HTML one) and reply messages.

GNOME Online Accounts

Jmail does not run its own OAuth flow. It picks up the mail accounts already configured in GNOME Online Accounts (the org.gnome.OnlineAccounts session service, usually driven from Settings → Online Accounts):

  • On every launch — and whenever the window regains focus — the system accounts are reconciled into the local cache. Newly discovered accounts are enabled and synced automatically; a user's enable/disable choice is preserved.
  • OAuth2 accounts (e.g. Google) authenticate with SASL XOAUTH2 using an access token fetched from goa-daemon; password accounts (the GOA IMAP/SMTP provider) read their password the same way. Jmail never stores those secrets.
  • Each GOA account has a switch in Settings → Accounts to disable it: its folders and mail are hidden and syncing pauses, without touching the system account (re-enabling restores them).

Jmail never modifies GOA accounts. The first-run welcome dialog offers a button that opens the system Online Accounts settings when nothing is configured yet.

GOA is officially aimed at GNOME core applications; third-party access works today but is not a guaranteed interface.

Recipient autocomplete

The To/Cc/Bcc fields suggest addresses from two places:

  • People you have sent mail to — read from the cached Sent folders and ranked by how often and how recently you used them.
  • GNOME address books — read (read-only) from Evolution Data Server over D-Bus. Only cards with an email address appear; this can be switched off in Settings → Composing.

Suggestions update as you type. Use ↑/↓ and Enter/Tab to pick one, or Escape to dismiss. Opening a composer asks the sync engine to check the Sent folder for new headers (at most every two minutes), so mail sent from another device shows up without restarting Jmail. Contact data stays in memory and is never written to the mail cache or logs.

In the Flatpak sandbox this needs the EDS Sources5, AddressBook10 and Subprocess.Backend.* talk-name permissions, which are already part of the manifest.

Adding an account / logging in

  1. Launch the app.

  2. Open Settings (Shift+,) → Accounts → Add.

  3. With the mock server running, fill in:

    Field Value
    Name Mock (anything)
    Email you@example.com
    IMAP server 127.0.0.1
    Port 1143
    Security None
    Username you@example.com
    Password hunter2
    SMTP server 127.0.0.1
    SMTP port 2525 (the mock's default; change if you passed --smtp-port)
    SMTP security None
  4. Click Add Account. The dialog first checks that IMAP (and SMTP, if you filled in an SMTP server) accepts the settings; only then is the account saved. The engine syncs folders and the Joined Inbox fills. Select a message to preview it; the body is fetched on demand.

Test runs the same check without saving. Save refuses to persist an account whose servers reject the connection. If a server presents a certificate that cannot be verified, you are asked to confirm before it is accepted for that account (stored as accept invalid certificates, only for that account).

Custom accounts added this way can be revised later with Edit on the account row (GOA accounts instead have an enable switch).

In the Flatpak sandbox 127.0.0.1 is the host loopback, so the mock server running on your machine is reachable.

To verify live push, start the server with --push-after 15; a new Inbox message ("Live push while you idled") arrives without any interaction.

Rebuilding the cache

If mail looks stale — or after changing the mock demo data — open Settings → Advanced → Force resync. This deletes the cached mail for every account and re-fetches all folders from the server (SyncCommand::Rebuild). Message bodies are cached, so this is also how to pull an updated body for a message you have already opened.

Keyboard shortcuts

Key Action
j / k Next / previous message
o / Enter Open conversation in a new window
click Preview in the reading pane
c Compose
r / a / f Reply / reply all / forward (inline, at the bottom of the conversation)
e Archive
# Delete
s Star
Shift+I / Shift+U Mark read / unread
/ Search
g then i/t/d/a Jump to Inbox / Sent / Drafts / All
Shift+, Settings
? Keyboard shortcuts

Development

cargo test -p jmail-core     # unit + integration tests (uses the mock server)
cargo build -p jmail-ui

See TODO.md for the roadmap and current status.

About

GTK4 Mail Client

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages