Skip to content
doqhuPublic

About

Hotkey dictionary and translator for Linux: English, Spanish and Catalan words and sentences in Russian, with screen OCR

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

addict

addict is a hotkey translator for Linux readers of English, Spanish and Catalan. Select or copy a word or a sentence anywhere, press the shortcut, and a small window shows the dictionary article of the word: its senses, synonyms, transcriptions with recordings, and its Russian translations. Click a word of a sentence and DeepL translates the word in that sentence, and the sentence itself, into Russian. Text that cannot be selected, such as an image or a video, can be captured from the screen and read with Tesseract OCR.

The addict window with the article of a Catalan word

Features

  • A clipboard shortcut reads the selected text, or the clipboard when nothing is selected, the same way in every application. A separate screenshot shortcut opens the interactive region picker for OCR.
  • Offline dictionary lookup in English, Spanish and Catalan, by the word as written and by its dictionary forms. When the reading language has dictionaries but none of them has the word, the other two are asked.
  • Russian translations from the dictionaries and, online, from DeepL: the clicked word in the context of its sentence, the sentence, or a chosen definition. Answers are cached on disk for up to 90 days after their last use.
  • Capture: choose an area of the screen, and its text replaces the field.
  • A Russian word is looked up the other way: its translations into the reading language.
  • An icon in the top bar with Show, Settings, About and Exit.

Requirements

  • Linux with GNOME 48 or later on Wayland, which has the GlobalShortcuts portal. KDE Plasma 6 may work but is not tested.
  • GTK 4.20 or later. On a distribution with older GTK, such as Debian 13 or Ubuntu 24.04, the build from source fails; use the AppImage or the Flatpak bundle (see Install).
  • Tesseract, with the data of English, Spanish and Catalan, for Capture only.
  • A DeepL API key (the free plan is enough), for the online translations only.
  • The top-bar icon needs a StatusNotifierItem host; on GNOME, the AppIndicator extension. Without one, addict runs without the icon.

Install

Each release carries an AppImage and a Flatpak bundle for x86_64, each with a .sha256 file; <version> below stands for the release's version, such as 0.2.0. addict is not on Flathub yet. To build it yourself, see Build from source.

AppImage

The AppImage was tried on GNOME with Debian 13 and Ubuntu 24.04. It needs no FUSE, and carries GTK and Tesseract, so it works where GTK is too old for a build from source.

  1. Download Addict-<version>-x86_64.AppImage and Addict-<version>-x86_64.AppImage.sha256 from the release, and check the download:

    sha256sum --check Addict-<version>-x86_64.AppImage.sha256
  2. Make it executable and start it:

    chmod +x Addict-<version>-x86_64.AppImage
    ./Addict-<version>-x86_64.AppImage
  3. To add it to the application menu, open the file with Gear Lever and let it integrate the app, or run ./Addict-<version>-x86_64.AppImage install, which writes the same kind of desktop entry as a source build. Keep the file where it is: the entry names its path, so after moving it run install again.

To update, download the new release's AppImage and use it in place of the old one. addict does not update itself. Settings, the dictionaries and the cache stay where they are.

On Ubuntu 24.04, whose desktop portal is older, the AppImage starts and looks words up, but Capture gives no text and Start at login is unavailable.

The release also carries what the AppImage's licenses require: its corresponding sources (Addict-<version>-x86_64.AppImage.sources.tar.00, ...) and the files of its build, described in docs/release.md.

Flatpak bundle

Download Addict-<version>-x86_64.flatpak and its .sha256 file, then:

sha256sum --check Addict-<version>-x86_64.flatpak.sha256
flatpak install --user Addict-<version>-x86_64.flatpak
flatpak run io.github.doqhu.Addict

The bundle needs the GNOME runtime, which Flatpak installs from a remote such as Flathub, so set that remote up first if you have not. A bundle does not update itself: install the next release's bundle the same way. Before you switch from a source build or an AppImage launcher, run addict uninstall (for an AppImage, ./Addict-<version>-x86_64.AppImage uninstall) and quit the running addict; the note below says why.

Build from source

On Fedora 43, install the build tools and Tesseract:

sudo dnf install git gcc pkgconf-pkg-config gtk4-devel rust cargo \
    tesseract tesseract-langpack-eng tesseract-langpack-spa \
    tesseract-langpack-cat

Other distributions need the same: a C compiler, pkg-config, the GTK 4.20 development files, a recent stable Rust with Cargo (1.85 at least, for edition 2024), and Tesseract. Then build:

git clone https://github.com/doqhu/addict.git
cd addict
cargo build --release --locked

The program is target/release/addict. Register it with the desktop and start it:

target/release/addict install
target/release/addict

addict install writes a desktop entry and the app icons into your home directory, so addict appears among your applications. The entry names the program by its full path, so run install again if you move the program. addict uninstall removes what install wrote, and turns off login startup first (see below).

To start addict at login, turn on Settings → Start at login. addict asks the desktop's Background portal to do it, in the Flatpak and in a source build, and then starts silently at each login. install does not set it up, but a source build needs it first: the portal knows addict by the entry it writes. The switch shows what the portal last confirmed, as the portal cannot be asked what is set. If the two have drifted apart, for instance after you move the program or delete the entry by hand, turn the switch off and on again to repair it.

An older build wrote its own login entry, which keeps starting addict and may open the window at each login. A source build then shows the switch on, with a line saying so; turning it off and on replaces that entry with the portal's.

addict uninstall asks the portal to remove a login entry of ours before it removes anything else. If the portal is unavailable or refuses, it removes nothing and names the file. A file of that name that addict did not write, or a symlink, is refused and left alone, and the portal is not asked.

Before you switch to a Flatpak of addict (from Flathub, or built from packaging/flatpak), run addict uninstall and quit the running addict: choose Exit in its top-bar menu, or run pkill -x addict when there is no icon. The entry install wrote hides the Flatpak's, and a running addict built from source answers in place of the Flatpak.

Normal launches show the main window, including the first launch and launches while addict is already running. Open Settings from the window's main menu or the top-bar menu; tray support is optional. Closing the window or pressing Esc keeps addict running for its shortcuts.

On the first start, the desktop portal asks you to confirm the shortcuts. The clipboard action suggests Super+Q and keeps any existing assignment. The screenshot action has no suggested key: open Settings → Configure shortcuts… and assign a free key to Screen region (OCR). The portal owns both assignments, and Settings shows changes immediately. Its dialog configures both actions independently. Portals of GlobalShortcuts version 1, as on stock GNOME, have no such dialog to reopen, and neither do portals that offer version 2 over a desktop backend without it (xdg-desktop-portal before 1.22 with GNOME's backend). There addict binds both actions again under new IDs, which makes the desktop show its dialog with the current keys filled in; cancelling it leaves the keys as they were. addict remembers which IDs are current in shortcut-generation, in its configuration directory. Ubuntu's dock holds Super+Q, so choose another key there.

With the window closed, the screenshot key opens the region picker. Choose an area to put editable OCR text in the window, using its reading language; cancelling starts no OCR or translation. The clipboard key continues to read selected or copied text independently.

A capture that ends without a snapshot opens the window, with a line saying what happened and Capture focused: press Enter to open the picker again. If the shortcut is not bound, Retry has the focus instead, and Capture is one click away. The window also opens after Esc, because GNOME reports Esc and a real failure the same way, so addict cannot tell them apart. No permission is involved on GNOME: an interactive screenshot asks for none, and there is nothing to grant.

Use addict --background (or flatpak run io.github.doqhu.Addict --background) for a silent login launch. This mode stays silent even if shortcut setup fails, including when forwarded to a running instance. Launch normally to see its status and Retry in the main window. This flag does not set up autostart; the Start at login switch in Settings does.

Where addict finds Tesseract

addict runs the program named in ~/.config/addict/tesseract if that file exists, else tesseract in the directory of the addict program, else tesseract on PATH. It reads the language data from the directory named in ~/.config/addict/tessdata if that file exists, else from ../share/tessdata resolved from the directory of the addict program (for /app/bin/addict, /app/share/tessdata), else from where Tesseract looks by itself (TESSDATA_PREFIX is honoured). Each file holds an absolute path on its first nonblank line; a relative path, or a file that cannot be read, is ignored. A build from source with the system Tesseract needs neither file.

Dictionaries

addict looks words up in dictionary indexes. The first start offers to download the published indexes. Settings → Dictionaries → Download dictionaries checks all published indexes and offers only missing or unreadable files. You can use it after choosing Not now, or to restore a deleted or damaged index; healthy files, including manually imported editions, are kept. To import an upstream file yourself, download a file below, open Settings → Dictionaries → Import file…, and choose it. The app builds its index in the background and shows completion or a failure beside the action. A newly added dictionary is available on the next lookup. If that dictionary was already in use, restart Addict to use its new edition.

Use this in-app route for Flatpak: its file chooser grants access to the selected download through the desktop portal, with no additional filesystem permissions. The command line remains available for a build from source:

target/release/addict import ~/Downloads/english-wordnet-2025.xml.gz

addict accepts only these exact editions: it checks each file's size and SHA-256 before it writes anything. The Kaikki files are the exception: Kaikki replaces them about every week, so addict accepts any edition of them by its content (it must read as a Kaikki file and hold at least 10,000 headwords), but only under its upstream name, as linked below; the older name kaikki.org-dictionary-Español.jsonl.gz is accepted too. Such an index is dated by the file's modification time. One index is enough to start, and the window says which ones are missing. The indexes are kept in ~/.local/share/addict.

Language What it gives File
English definitions and synonyms english-wordnet-2025.xml.gz
English Russian translations freedict-eng-rus-2025.11.23.src.tar.xz
Spanish Russian translations es-ru.sqlite3
Spanish definitions and synonyms es-extract.jsonl.gz
Spanish synonyms omw-es-2.0.tar.xz
Spanish English glosses kaikki.org-dictionary-Spanish.jsonl.gz
Catalan Russian translations ca-ru.sqlite3
Catalan definitions ca_dbnary_ontolex_2026-10-01.ttl.bz2
Catalan synonyms th_ca_ES.dat
Catalan English glosses kaikki.org-dictionary-Catalan.jsonl.gz
Russian English translations ru-en.sqlite3
Russian Spanish translations ru-es.sqlite3
Russian Catalan translations ru-ca.sqlite3

CREDITS names the authors and the license of each source.

Configuration

addict keeps its settings as small files in ~/.config/addict ($XDG_CONFIG_HOME/addict when that is set):

  • deepl.key -- the DeepL API key. Enter it in Settings, which writes the file with mode 0600; a file with any permission beyond 0600 is refused.
  • tesseract, tessdata -- where to find Tesseract and its data (see above).
  • vulkan-drivers -- which Vulkan driver GTK uses. By default addict picks the driver of the GPU that drives the display, so a sleeping discrete GPU stays asleep. all turns this off; any other line, such as nvidia_icd*, is used as is.
  • language -- the reading language, written when you switch it in the window.

DeepL answers are cached in ~/.cache/addict; Settings shows the cache size and clears it.

License

addict is licensed under the MIT License. The dictionary data and the OCR software and data it uses have their own licenses and credits, listed in CREDITS and in the app under About → Credits. The screenshot, docs/screenshot.png, shows dictionary data, so it is under CC BY-SA 4.0 instead (see REUSE.toml).

Use of AI in addict

addict was built with heavy use of generative AI. Below is each part of the project, with how much of it AI wrote. The figures come from the git history at commit f59cf7e (12 November 2026); scripts/ai-figures.sh f59cf7e reproduces them.

Code

Almost all of the code was written by AI: Claude (Anthropic's Opus and Sonnet models), through Claude Code, in 126 commits, and OpenAI's Codex in 7. Over 99% of the lines in the tracked files (generated and license files included) come from AI-assisted commits. 133 of the project's 139 commits were AI-assisted; the other six are five merge commits and a release-please commit. This covers all crates and their tests.

The maintainer chose the features, directed the work and tested the result in use. The maintainer did not review every line of the AI-written code.

Documentation

The README, CONTRIBUTING and this disclosure are drafted by AI and edited by the maintainer. Code comments were written by AI along with the code.

Packaging, CI and project configuration

  • Flathub manifest: written by the maintainer, with no AI-generated or AI-assisted content. It is separate from the development manifest below.
  • Flathub submission: the pull request, its description, commit messages and replies are written by the maintainer, without AI.
  • Everything else: the CI workflows, the secret-scan configuration, the check and acceptance scripts, the development Flatpak manifest (packaging/flatpak), its sources script (scripts/flatpak-sources.sh), the crate license list's configuration (packaging/licenses) and script (scripts/crate-licenses.sh), the figures script (scripts/ai-figures.sh), the desktop entry and the MetaInfo (data), the AppImage recipe and the project configuration files (Cargo.toml, REUSE.toml, .gitignore) are written by AI under the maintainer's direction.

Artwork

The app icon was made with an image-generation tool. The smaller sizes are built from it by a script.

Not counted above

AI was also used for research, discussion and debugging. That use did not add anything to the repository by itself.

About

Hotkey dictionary and translator for Linux: English, Spanish and Catalan words and sentences in Russian, with screen OCR

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages