DEV Community

Cover image for I built a radial menu that converts any file on Linux
freerave
freerave

Posted on

I built a radial menu that converts any file on Linux

DotMorph: right-click a file, a wheel blooms, pick a format. 440+ local conversions for images, PDF, SVG, video, audio and Office files, from your file manager, a hotkey or a screen edge.

The DotMorph wheel opening on a video, blooming the Video fan, converting to GIF and finishing with a particle burst

Right-click a file. A wheel blooms around it. Pick a format. Done.

That is the whole idea behind DotMorph, a file converter for Linux that lives in a radial menu instead of a window. It does 440+ conversions (images, PDF, SVG, video, audio, Office documents, Markdown) and everything happens on your machine. It's free, open source (Apache 2.0) and part of DotSuite, my collection of developer tools.

This is the first of four posts. This one is the tour; the next three are about how it's built.

Why another converter?

Converting a file on Linux usually goes one of three ways:

  1. You remember (or search for) the right ffmpeg / magick / libreoffice --headless incantation.
  2. You install a big GUI app, open it, find the file again, pick a format from a dropdown.
  3. You upload your file to some random website and hope it isn't keeping a copy.

On Windows there's a nice pattern for this: converters that sit in the right-click menu. I wanted that on Linux, and I wanted it to feel like a tool, not a form. So: a wheel that appears where you are, shows only what makes sense for the file you picked, and gets out of the way.

What it converts

DotMorph doesn't reimplement codecs. It drives the tools that are already the best at each job, and only offers what your machine can actually do:

Files Examples Done by
Images PNG, JPG, WebP, AVIF, HEIC, GIF, TIFF, ICO, PSD, XCF, JPEG XL Pillow, ImageMagick
SVG → PNG, WebP, … and vector PDF librsvg (via ctypes)
PDF → images (one per page), → text, compress, merge poppler, Ghostscript
Video MP4, MKV, WebM, MOV, AVI, … ↔ each other, → GIF, → audio ffmpeg
Audio MP3, M4A, OGG, Opus, FLAC, WAV, AAC ffmpeg
Documents DOCX, ODT, PPTX, XLSX, … → PDF and between Office formats LibreOffice (headless)
Text Markdown, HTML, reST, Org, EPUB ↔ DOCX, ODT, EPUB, PDF pandoc

Plus tools that keep the format: compress (never returns a bigger file), resize, rotate, strip metadata (EXIF, GPS, tags), mute a video, merge images and PDFs into one PDF.

On a machine with everything installed that's 53 formats, 6 tools and 440+ conversions. If a tool is missing, its conversions simply don't show up, and dotmorph doctor tells you which package to install for apt, dnf, pacman or zypper.

Many ways in, one wheel

The wheel opens from wherever you happen to be:

  • File manager right-click: Nautilus, Thunar, Dolphin and Nemo, with a DotMorph submenu and quick actions (To PNG, To PDF, To MP4, Compress…) that run without any window.
  • Open with DotMorph in any app that lists launchers.
  • A global hotkey (Super+Shift+M): copy files in your file manager, press it, the wheel opens with those files.
  • The edge dock: drag the wheel against the side of the screen and it turns into a slim tab. Hover it and half a wheel slides out, like Android's edge panels. Drop files on it.
  • Watched folders: dotmorph watch ~/Downloads --to webp converts new files as they land (inotify, run as a systemd user service).
  • The terminal, for everything above and more.

Dragging the wheel to the left edge: it docks as a tab, then opens as a half wheel on hover

Thanks to a small background daemon, the wheel opens in about 0.1 s instead of the ~1 s it takes to start Qt. Post 3 is about how that works.

The command line is a first-class citizen

Everything the wheel does, the CLI does too:

dotmorph convert holiday/*.heic --to jpg              # batch, in parallel
dotmorph convert talk.mov --to mp4                    # same codec? stream copy, seconds
dotmorph convert report.docx slides.pptx --to pdf
dotmorph convert photos/*.jpg --preset web            # WebP, ≤1920 px, quality 80, no metadata
dotmorph convert scan.pdf --to compress
dotmorph convert diagram.svg --to pdf                 # stays vector
dotmorph formats video.mp4                            # what can this file become?
dotmorph doctor                                       # what's installed, what's missing
Enter fullscreen mode Exit fullscreen mode

You get a live progress bar, Ctrl-C cancels cleanly, existing files are never overwritten (you get name (1).ext), and half-written files never appear because every job works in a hidden folder and finishes with a rename.

Settings, in English and Arabic

There's a separate settings window: themes (dark, light, glass), pinned and hidden formats, the hotkey recorder, file-manager integration, watch folders, and a page that lists every engine with a "copy install command" button. The whole interface is also available in Arabic, laid out right to left.

The settings window in English (dark theme) and Arabic (light theme, right to left)

Install

pipx install 'dotmorph[gui]'
Enter fullscreen mode Exit fullscreen mode

Or grab the AppImage (one file, no install, and AppImageUpdate can update it), the .deb, or the Arch package from the releases page. Every file is checksummed and GPG-signed.

DotMorph is also on AppImageHub and OpenDesktop, and in the AppImage community catalog that stores like AppImagePool read from.

Then, optionally:

dotmorph integrate          # right-click menus
dotmorph daemon --install   # instant wheel + edge dock at login
dotmorph hotkey             # Super+Shift+M
Enter fullscreen mode Exit fullscreen mode

It needs Python 3.10+ and works on glibc 2.28 and newer (Ubuntu 20.04, Debian 11, RHEL 8 and later).

Honest limitations

  • On Wayland the wheel runs through XWayland, so it can stay on top and be placed. A native layer-shell version is planned.
  • The hotkey is registered automatically on GNOME and Xfce; on other desktops dotmorph hotkey prints the command to bind yourself.
  • The AppImage is x86_64 only for now.
  • LibreOffice conversions run one at a time (a limitation of its profile).

What's next in this series

  1. This post: the tour.
  2. The engine: eight backends behind one interface, safe output, cancelling, and the SVG bug that started the whole rewrite.
  3. The wheel: QML, GPU-drawn ring sectors, particles, a 0.1 s daemon and the edge dock.
  4. Shipping it: PyPI, AppImage, .deb, Arch and AUR from one signed tag, and why the AppImage went from 109 MB to 73 MB.

If you try it, I'd love to hear what you convert most, and what's missing.

Top comments (0)