Skip to main content
WordWrap logo

WordWrap

Fix text typed in the wrong keyboard layout - the Linux answer to Punto Switcher.

Select the mistyped text, press Ctrl+F1: ghbdtn becomes привет, руддщ becomes hello, and the system layout switches to match.

Python Platform License Tests


Why

You typed a whole sentence before noticing the layout was wrong. Instead of deleting and retyping, select it and hit one hotkey - WordWrap rewrites the characters through the correct layout, pastes the result back in place, and flips the system layout so your next keystroke is already right.

It is manual on purpose: it never watches what you type and never guesses. It acts only when you press the hotkey.

Features

  • Bidirectional - works whether EN or RU is currently active; direction is picked from the text itself, not from the active layout.
  • Works anywhere text is typed - editors, browsers, VS Code, Telegram; terminals get a dedicated hotkey that clears the input line and pastes with Ctrl+Shift+V.
  • Fix the last word with a single hotkey - no selection needed.
  • Tray app - enable / disable with a click, colour or monochrome icon.
  • Bilingual UI - English by default, Russian selectable in Settings.
  • Launch on login - one checkbox in Settings.
  • Privacy-first - text content is never logged, no network access of any kind.

How it works

  1. Global hotkey caught via evdev (needs the input group).
  2. Your clipboard is saved and a private marker is put in it; the selection is copied over the marker with Ctrl+Insert. Marker still there means nothing is selected, so the last word is selected automatically (optional).
  3. Text is converted character-by-character between layouts (en <-> ru and en <-> uk built in). The direction comes from the text itself, not from the active layout.
  4. The result is pasted back via clipboard + synthetic Ctrl+V - wtype is not supported by Mutter, so this is the reliable path.
  5. The system layout is switched via gsettings; the real state is read back from GNOME's mru-sources, and if the switch did not take effect the GNOME Super+Space shortcut is pressed as a fallback.
  6. Your clipboard is restored.

Terminal mode (Ctrl+Shift+F1) is different: it takes the mouse selection, clears the whole readline input line (Ctrl+A, Ctrl+K - Ctrl+Y brings it back) and pastes the fixed text with Ctrl+Shift+V. It assumes the mistyped text is the current input line. For TUI prompts that do not understand Ctrl+A / Ctrl+K (Claude Code, some REPLs) switch Settings -> Behavior -> Terminal: how to erase the old text to Backspace per character and keep the cursor at the end of the mistyped text. Full-screen TUIs (vim, tmux, htop) are not supported.

Hotkeys

Action Hotkey
Convert selection Ctrl+F1
Convert in a terminal (clears the input line, pastes with Ctrl+Shift+V) Ctrl+Shift+F1
Convert the last word (no selection needed) Ctrl+F2
Enable / disable conversion Ctrl+Pause

All configurable in Settings or ~/.config/sgk-wordwrap/config.json. The listener only watches the keyboard and does not consume the event, so the hotkey also reaches the focused app - that is why the defaults are otherwise-unused keys.

Tray and settings

The tray icon (top panel) shows enabled / disabled state. Left-click toggles it; right-click opens the menu:

  • Enabled / Paused - toggle conversion
  • Settings... - language, launch-on-login, monochrome icon, hotkeys, excluded programs, behavior (word fallback, clipboard restore, terminal paste / erase mode)
  • About - version, author, links to star or support the project
  • Quit

Language and icon-style changes apply immediately; hotkey changes need a restart.

Install (GNOME Wayland / Ubuntu)

Requires wl-clipboard, python3-pyqt6, python3-evdev and membership in the input group (for the evdev listener and the uinput virtual keyboard).

With pipx:

sudo apt install wl-clipboard python3-pyqt6 python3-evdev pipx
sudo usermod -aG input "$USER"          # then log out and back in once
pipx install --system-site-packages git+https://github.com/sgk-dev/wordwrap
sgk-wordwrap --install-desktop          # adds WordWrap to the applications menu

Then open the GNOME activities overview, search for WordWrap and launch it. Turn on Launch on login in Settings if you want it to start with your session.

From a clone, as a systemd user service:

bash packaging/install.sh
# log out and back in once (for the 'input' group), then:
systemctl --user start sgk-wordwrap

install.sh creates a venv, the menu entry and a sgk-wordwrap user service that starts with the graphical session. Use either the service or the Settings checkbox for autostart, not both - a second instance simply exits.

Run in the foreground

python3 -m sgk_wordwrap --log-level DEBUG      # with tray
python3 -m sgk_wordwrap --no-gui               # headless

Configuration

~/.config/sgk-wordwrap/config.json (created on first run):

{
  "ui": { "language": "en", "tray_icon_style": "color" },
  "hotkeys": {
    "convert": "ctrl+f1",
    "convert_terminal": "ctrl+shift+f1",
    "convert_last_word": "ctrl+f2",
    "toggle": "ctrl+pause"
  },
  "layouts": { "custom_maps_dir": null },
  "behavior": {
    "enabled_on_start": true,
    "fallback_to_word_on_no_selection": true,
    "restore_clipboard": true,
    "terminal_paste_combo": "ctrl+shift+v",
    "terminal_erase": "line",
    "copy_settle_ms": 400,
    "clipboard_settle_ms": 150,
    "paste_settle_ms": 100
  }
}

Custom layouts

Point layouts.custom_maps_dir at a folder and drop JSON files into it:

{
  "name": "en-de", "from_layout": "en", "to_layout": "de",
  "map": { "y": "z", "z": "y", "Y": "Z", "Z": "Y" }
}

Notes and limitations

  • Direction is detected from the text. Pressed on correct text by mistake? Undo with Ctrl+Z in the app - the paste is a single edit.
  • Non-text clipboard (image / files) cannot be restored; it is cleared after the operation. Text is restored as it was.
  • Password fields: window / process detection is not available on GNOME Wayland, so the excluded-programs list is best-effort only. Do not press the hotkey in a password field.
  • Active layouts come from the system (gsettings), not from the config.
  • Supported environment: GNOME on Wayland (Ubuntu, Mutter). X11 / KDE / wlroots code exists in the tree but is out of scope for this release.

Support the project

If WordWrap saves you time, a star on GitHub or a small donation via GitHub Sponsors helps a lot.

License

WordWrap is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License v3.0 or later (see LICENSE). It is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY.

Copyright (c) 2026 SGK (sidash.seo@gmail.com)

The WordWrap name and logo are not covered by the GPL and remain the property of SGK; forks must use a different name and their own artwork.


Developed by SGK with ❤️

Metadata

Release files for sgk-wordwrap 0.3.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sgk-wordwrap 0.3.2
File Size Uploaded
sgk_wordwrap-0.3.2.tar.gz 124.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sgk-wordwrap 0.3.2
File Interpreter ABI Platform
sgk_wordwrap-0.3.2-py3-none-any.whl Python 3 none any Details

Total release size: 252.6 kB

Release files / sgk_wordwrap-0.3.2.tar.gz

Download URL sgk_wordwrap-0.3.2.tar.gz
Size 124.1 kB
Tags Source
SHA-256 checksum
How to use checksums
0a46638161fcb134ef51cf6a0affce8eec6b6fb204955ab88347d97f50b78731
BLAKE2b-256 checksum
How to use checksums
6a1270f622e3411e371609a4ec81aa457e15356c175e889b31b3573a60094ea7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / sgk_wordwrap-0.3.2-py3-none-any.whl

Download URL sgk_wordwrap-0.3.2-py3-none-any.whl
Size 128.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dd7f358b2fbf4a546f55333318282c7d1df26bababd3b402ea19029604b7cbe7
BLAKE2b-256 checksum
How to use checksums
ec5b45f73adc49180ffaa4c549225afbc65b32774485c7b7f3dd3268c9b89bb9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release history Release notifications | RSS feed

0.3.4

2 release files

0.3.3

2 release files

This release

0.3.2 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page