A native file-transfer client for Omarchy.
Bookmarks, a remote file browser and a transfer queue for SFTP, FTP, WebDAV,
S3, B2 and the ~60 other backends
rclone speaks.
An SFTP session, one click after launch. Dotfiles are hidden but counted (4 items · 42 hidden), and every colour on screen came from the running Omarchy theme.
One binary. No Electron, no Java. Qt Quick on top of a private rclone rcd,
painted live in whatever Omarchy theme you are running.
- Instant and native. Opening a bookmark shows the directory immediately; a 10,000-entry bucket sorts in single-digit milliseconds, because the table is a C++ model, not a QML one.
- rclone underneath. Omaport never re-implements a protocol — SFTP, FTP(S), WebDAV, Nextcloud/ownCloud, S3 and compatibles, Backblaze B2, Azure Blob, SMB and Google Cloud Storage are configured straight from the connection dialog.
- Omarchy through and through. Colours from the live theme, text size from
omarchy display text size, both applied the instant they change — no restart. - Secrets stay secret. Passwords live in the Secret Service keyring, travel to rclone in POST bodies (never argv, never a config file), and bookmark exports are sealed with AES-256-GCM under a PBKDF2 key.
- Keyboard-first. Every action has a key;
?shows the whole map, and a test fails if that sheet ever disagrees with what the app actually binds.
git clone https://github.com/SilentKernel/omaport
cd omaport
./bin/install # builds, then makepkg -fsiOmaport then appears in the Omarchy launcher, and registers as the handler for
sftp://, ftp://, ftps://, webdav:// and smb:// URLs —
xdg-open sftp://[email protected]/srv/www opens the browser at that path as an
ad-hoc connection that is never saved and never touches the keyring.
Build deps: cmake ninja qt6-base qt6-declarative qt6-svg libsecret openssl gcc make
Runtime: rclone, xdg-desktop-portal (folder picker), and a Secret Service
provider such as gnome-keyring for stored passwords.
Omaport degrades gracefully: without a keyring, passwords are session-only and
the dialog says so; without rclone it tells you to install it rather than fail.
A bookmark is a nickname, protocol, host, port, user, initial path and any
backend extras, stored in ~/.config/omaport/bookmarks.json — written
atomically, readable only by you, and never overwritten if it cannot be parsed.
Passwords never touch that file. They go to the keyring under the bookmark's
id, obscured through the daemon's own core/obscure endpoint. Google Drive,
Dropbox and OneDrive need a browser OAuth flow Omaport cannot drive yet; the
dialog says so and points you at rclone config rather than pretending.
SSH keys. An SFTP bookmark authenticates by SSH agent, key file or
password. Omaport finds a live agent socket itself — $SSH_AUTH_SOCK,
1Password, systemd, gnome-keyring, gcr — probing each until one answers, because
an app started from the launcher never read your shell profile. The socket is
handed to the rclone engine alone.
Moving machines. The ⋯ menu exports any selection of bookmarks — saved
passwords included — into one password-protected .omaport file, sealed with
AES-256-GCM under a PBKDF2-HMAC-SHA256 key. Importing adds; it never merges
over a bookmark you have since edited.
A sortable table of name, size, modified time and — where the backend really reports modes — permissions. Breadcrumbs, a live filter, and a status line that says how many items you are looking at, including how many hidden files are out of sight (dotfiles are hidden by default, never silently).
↑ ↓ / a–z |
move / type-ahead |
Home End / PgUp PgDn |
first and last row / a screen at a time |
Enter / Backspace |
descend / up one level |
Alt+← Alt+→ |
back / forward (mouse side buttons too) |
Alt+↑ / Alt+Home |
up / back to the bookmark's folder |
/ |
filter (Escape clears) |
Ctrl+G |
type a path |
Ctrl+click / Shift+click / Shift+↑↓ |
pick several rows |
Ctrl+A |
select everything in the folder |
Ctrl+↓ / Ctrl+↑ |
download the selection / upload here |
Ctrl+L / Tab |
show or hide the local pane / move between the panes |
Ctrl+Shift+N / F2 / Ctrl+D / Delete |
new folder / rename / duplicate / delete |
Ctrl+I / Ctrl+E |
Info drawer / edit in $EDITOR |
Ctrl+R F5 / Ctrl+, |
refresh / preferences |
? F1 |
the whole map, on one screen |
Press ? anywhere — and a test fails if this sheet ever
disagrees with what the app actually binds.
A click leaves the row lit, the way a file manager does, and the selection survives everything the keyboard does to it. Download, Duplicate and Delete act on the whole selection — a multi-file download is one queue batch, so its overwrite prompt is asked once. Rename, Edit and the Info drawer stay on one file and go quiet when several are picked.
Errors appear in a bar above the table — never a modal you must dismiss before you can read the path that failed. Deleting asks first (configurable), counts what it is about to remove, and says out loud when a folder goes with everything inside it.
Ctrl+L — or the two-panel button on the toolbar — opens your own disk beside
the remote, the way WinSCP and Total Commander do it. It is the same table over
the same model, listing through rclone's :local: backend, so sorting,
filtering, type-ahead, New folder, Rename, Duplicate and Delete all work on the
local side exactly as they do on the remote one. The pane comes back the way
you left it: open it, quit, and the next launch opens with both panes on the
folder you were last looking at.
With the pane open you can drag rows either way — which is the direction
that could not exist before: under Wayland a drag out of the browser would have
to hand a file manager a URI for a file nobody has downloaded yet. Ctrl+↑
sends the local selection up, Ctrl+↓ brings the remote selection down into
the folder the pane is showing rather than into the download folder, and Tab
moves between the two sides. A drop from a file manager still lands in whichever
pane you drop it on.
Both sides refresh themselves when a transfer lands in them: upload a file and it appears in the remote listing, download one and it appears in the local one, with no manual refresh either way.
The pane opens on your home folder the first time, and afterwards on wherever
you left it — remembered in settings.json. A folder that has been deleted,
moved or unplugged since falls back to home without forgetting the folder you
chose, so an unmounted drive is still there next time.
A queue under the table, visible only when something is in it. Each row has its
own progress, speed, ETA, Cancel and — on failure — rclone's actual error and a
Retry. Four run at once by default (1–8 in Preferences). Name collisions ask
once per batch: Overwrite, Skip or Rename (report (1).txt). Files dropped from
a file manager upload to the directory on screen, and with the local pane open
a drag between the panes queues a transfer in either direction. When a queue drains, Omaport
notifies through omarchy-notification-send if it is installed.
Ctrl+I slides in a drawer: full path, size both ways round, times, MIME type,
backend metadata, and a checksum button — hashing reads the whole object, so
it never runs unasked. Permissions show as an rwx grid plus octal, read-only,
with the reason printed under it: rclone has no chmod, and Omaport does not
pretend otherwise.
Ctrl+E opens the file in $VISUAL/$EDITOR (terminal editors get a
terminal), staged under $XDG_RUNTIME_DIR, and every save uploads back. Saves
are detected by content, so vim's rename-over-target trick works, a burst of
saves is one upload, and a failed upload leaves the temp file and tells you
exactly where it is.
Omaport reads ~/.local/state/omarchy/current/theme/colors.toml and re-themes
the moment you switch themes. Text size follows omarchy display text size
live, on the same type scale the Omarchy shell uses. Anything painted in the
accent colour picks its own label colour by WCAG contrast rather than assuming
white. Off Omarchy, every colour and size has a sane fallback.
One private rclone rcd per run, bound to a random loopback port with random
per-run credentials passed in the environment — never on a command line another
process could read — and killed by the kernel if Omaport dies. Your
~/.config/rclone/rclone.conf is never read or written: each bookmark is
rendered into an rclone connection string at call time and sent in the request
body.
./bin/build # cmake + ninja → build/omaport
./bin/test # every suite, in parallel, offscreen — no mocks, no network, no Docker
./bin/install # build, then makepkg -fsi from pkgbuild/
make check # build + suites + clang-tidy + clazy on what you changed
make check-all # the same, linting the whole treeThe suites spawn a real rclone rcd against its :local: and :memory:
backends, so a passing run means real listings and real byte-for-byte copies.
tests/sftp/demo.sh and agent-demo.sh go further — a throwaway Dockerised
SFTP server, connect → browse → upload → download → edit → verify — and are
deliberately outside the suite.
Sync, Cryptomator vaults, S3 versioning/ACL/lifecycle, bandwidth throttling,
Bonjour discovery, importing bookmarks from other transfer clients, native
OAuth flows for the browser-login clouds, and a mount mode (rclone mount).
Keep ./bin/test green — the suites are the specification. Never re-implement
a protocol rclone already speaks, and never put a secret on a command line.
Every line here is written for this project: other clients may inform what
Omaport does, never how it is written, and no code is ever copied from one.
MIT — see LICENSE.
Built with Qt 6 under the LGPLv3, linked dynamically.
Omarchy is a trademark of the Omacom Foundation; rclone is by Nick Craig-Wood and contributors. Omaport is an independent project, affiliated with neither.

