Omahub
← All plugins
M

Press & Hold

by msouza

macOS-style press-and-hold accented character picker, powered by Fcitx5's native long-press engine.

Security review

No obvious issues detected

Deterministic scan — not a security guarantee

None
Risk level
None
Analyzed commit
71f7fe0
Scanned
1 month ago

No potentially dangerous behavior detected in the analyzed commit.

Automated analysis only — not a security guarantee.

AI advisory review

No obvious issues detected

Language-model assessment · ~deepseek/deepseek-v4-flash-latest — advisory only

None
AI risk level
None
Recommendation
install
Model
~deepseek/deepseek-v4-flash-latest
Analyzed commit
71f7fe0
Reviewed
1 month ago

This is a well-engineered, transparent plugin that toggles Fcitx5's native long-press feature via its D-Bus API, with a clean fallback to config-file editing. The code is thoroughly commented, follows least-privilege principles (only touches two Fcitx5 keys, snapshots prior values for restoration), and contains no obfuscation, network access, credential handling, or destructive operations. The uninstall script is notably careful, only removing files it created and preserving user edits.

How this check works

This review combines the deterministic scan (the rule-based results above) with an independent look at the plugin's code by a language model. The model reads a trimmed sample of the repository's files, the manifest, and the README, then gives a plain-language risk level and a recommendation: install (no notable danger), review (look closer first), or avoid (clearly dangerous).

It runs on the same analyzed commit as the deterministic scan and is strictly advisory — it is not a security guarantee and never blocks a plugin by itself. A human moderator still reviews plugins before they are listed.

AI advisory only — automated analysis, not a security guarantee.

Install
$ omarchy plugin add https://github.com/msouza10/omarchy-presshold --enable
Productivity #quickshell #system

Press & Hold

The accent popup appearing while typing a URL, offering ç ć č

A macOS-style press-and-hold accented character picker for Omarchy.

Hold down a key like a and a popup lets you pick an alternate like á, à, â, ã... just like on macOS.

This plugin does not reimplement press-and-hold from scratch. Fcitx5's keyboard-us (and compatible) engine already has native long-press support — this plugin is a thin, portable layer that toggles it on/off from the bar, lets you reorder each key's accents, and writes Fcitx5's config the way Fcitx5 itself expects.

What it does

  • Adds a small icon to the bar showing whether Press & Hold is on or off.
  • Click it to open a toggle. Turning it on sets EnableLongPress and Choose Modifier through Fcitx5's own config API — only those two keys, every other setting you already have is left untouched — and takes effect immediately, with no restart.
  • Turning it on also sets Choose Modifier=None, so pressing a plain number (1-9) selects a candidate. Fcitx5 defaults this to Alt (requiring Alt+1, Alt+2...); without overriding it, a bare number press isn't intercepted at all and gets typed into the field instead of picking a character.
  • Before that first write it records what those keys were set to, so turning the toggle back off restores them instead of just switching long-press off.
  • The first time you turn it on, it also installs the theme-matching hook (extras/theme-set.d/fcitx5-theme.sh) into ~/.config/omarchy/hooks/theme-set.d/, so the popup matches your Omarchy theme out of the box — no manual step needed. It never overwrites a copy that's already there, so any edits you've made to it are left alone.
  • Customize accents › opens a keyboard picker where a key's accents can be dragged into whatever order you want — ã ahead of à on a, say.
  • The icon always reflects the real state of keyboard.conf, even if you edit it by hand outside the plugin.

Install

omarchy plugin add https://github.com/msouza10/omarchy-presshold.git --enable

Local checkout:

omarchy plugin validate .
omarchy plugin add "$PWD" --enable

Remove

~/.config/omarchy/plugins/io.github.msouza10.presshold/scripts/uninstall.sh
omarchy plugin remove io.github.msouza10.presshold --yes

The first line undoes everything the plugin ever wrote outside its own folder, so the second leaves nothing behind:

  • the keyboard engine's EnableLongPress and Choose Modifier go back to the values recorded before the first time you turned the toggle on — not to a guess, and not merely to "off";
  • the candidate popup's ClassicUI settings go back to what they were before the theme hook first ran;
  • the generated Fcitx5 theme and the theme-set.d hook are removed. That hook matters: left behind, it keeps regenerating a theme for a plugin that is no longer installed, on every omarchy theme set. If you have edited your copy of it, it is kept and you are told so, rather than having your edits deleted.

Everything else is left alone: Fcitx5 itself, its service, and any setting this plugin never wrote. So is the candidate order you set through the keyboard picker — that is Fcitx5's own data and stays meaningful without this plugin.

Why this isn't automatic: Omarchy's plugin manifest has no uninstall hook. omarchy plugin remove disables the plugin in the shell, deletes or backs up the folder, and rescans — there is no point at which it can call into the plugin being removed. So a revert has to be triggered by hand; what the plugin can do is make it one exact command instead of a list of manual steps.

Just turning the toggle off in the bar also reverts the keyboard settings completely (that is what the snapshot is for) — it just leaves the theme hook and the generated theme in place.

The snapshots live in ~/.local/state/io.github.msouza10.presshold/, outside the plugin folder on purpose: omarchy plugin remove deletes the plugin, and a record of what to undo is worth nothing if it goes with it. Only the keys this plugin writes are recorded, never a copy of the whole keyboard.conf — restoring a whole-file backup would also roll back any unrelated Fcitx5 setting you changed in the meantime.

If you installed the plugin before this existed, there is no snapshot to restore from; the revert falls back to Fcitx5's own defaults (EnableLongPress=False, Choose Modifier=Alt).

Requirements

  • Omarchy Quattro shell.
  • Fcitx5 with the keyboard-us (or another Fcitx5 Keyboard-engine-based) input method active. This is the default on a stock Omarchy install.
  • bash, sed, grep (present on any Omarchy system).
  • python3 with python-dbus, used to talk to Fcitx5's config API. Also present on any Omarchy system — it comes in transitively with uwsm, a hard dependency of the omarchy package. If it were missing, the on/off toggle falls back to editing ~/.config/fcitx5/conf/keyboard.conf and restarting Fcitx5; the keyboard picker needs D-Bus and has no fallback.

How it works

Bar icon click
      ↓
scripts/toggle-longpress.sh enable|disable
      ↓
scripts/fcitx5_config.py → D-Bus SetConfig on fcitx://config/addon/keyboard
      ↓                     (EnableLongPress=True|False, Choose Modifier=None on enable)
the live Fcitx5 process applies it, then persists keyboard.conf itself
      ↓
Fcitx5 Keyboard Engine's native long-press / candidate list

Fcitx5 stays fully responsible for input handling, key repeat, the candidate list, and committing text. This plugin only manages configuration and the bar UI.

Reordering accents: the keyboard picker

Fcitx5 ships a fixed candidate order per key: holding a offers à first, then á, ã, and so on. If you write Portuguese, having ã first saves a keystroke every single time — and the ones you never use are worth pushing to the end. The popup's second view rearranges that list.

Click Customize accents › in the bar popup and you get a drawing of a US keyboard:

  • Keys that have long-press candidates are lit, and print the character they currently offer first underneath the legend. Click one to see its whole list.
  • Keys that don't stay dim and inert. The board still draws the full keyboard — it just doesn't pretend every key is customizable.
  • ⇧ Shift swaps every legend for its shifted twin. Fcitx5 keeps uppercase (A → À Á Â) and shifted-symbol (! → ¡, $ → ¢ € £) entries separately from their unshifted ones, so this puts each one under the key you would physically press for it.
  • Other scripts, below the board, holds what no US key can reach: Fcitx5 also ships entries for Cyrillic, Hebrew and Arabic.

Picking a key lays its candidates out in order, numbered, with the current default marked:

  • Drag a character anywhere in the sequence and drop it there. The others shuffle around it as you go and the numbers count up live, so the arrangement you see mid-drag is the one you get — ã to third place is a drag to third place, not four separate promotions.
  • Tap a character to send it straight to the front. It is the move most people came for, so it keeps a shortcut.

The order is re-read from Fcitx5 after every change rather than patched locally, so what you see is always the real order. Changes made while a save is still in flight are queued, not dropped.

Keyboard picker click
      ↓
scripts/reorder-candidates.py --set <key> <c1> <c2> ...
      ↓
D-Bus SetConfig on fcitx://config/addon/keyboard/longpress
      ↓
the live Fcitx5 applies the new order, then persists keyboard-longpress.conf itself

The same commands are available from the installed plugin directory:

scripts/reorder-candidates.py --keys        # every long-press key and its candidates
scripts/reorder-candidates.py --status a    # one key's current order, one per line
scripts/reorder-candidates.py a ã           # promote ã to the front of a
scripts/reorder-candidates.py --set a ã á â ā à ä æ å   # write the whole order

Two things worth knowing about that config:

  • SetConfig on the longpress URI is a full replace, not a merge. Sending back only the key you changed silently wipes every other key's candidates. So every write fetches the complete ~87-entry table, rearranges one key's list within it, and sends the rest back untouched.
  • --set only ever rearranges. The characters it is given have to be a permutation of the ones the key already has, or it writes nothing and says why. The picker sends a list it read moments earlier, and if Fcitx5's table changed underneath it in between, writing that list would quietly drop or resurrect candidates instead of just moving them.
  • Reordering needs Fcitx5 running (the script exits 3 otherwise). Unlike the on/off toggle, it has no edit-the-file-instead fallback: writing this table by hand would mean reimplementing Fcitx5's serialization for a ~87-entry nested structure, and if Fcitx5 is down there is no long-press to reorder in the first place. Start it and retry. See the note on writing Fcitx5's config for why the toggle does have that fallback.

Known limitations (v0.2)

  • Terminal emulators may behave differently — you may genuinely want aaaa... there instead of a popup. Fcitx5's own app-exclusion settings can be used for that; this plugin does not yet expose them.
  • Of the engine's own settings, only EnableLongPress and Choose Modifier are managed — both are restored on disable, from the values recorded before the first enable.
  • The revert has to be run by hand (scripts/uninstall.sh) because Omarchy's plugin manifest has no uninstall hook for omarchy plugin remove to call.
  • The keyboard picker reorders a key's candidates; it does not change which characters a key offers. Adding or removing candidates, and per-app blacklists (Fcitx5 ships with konsole excluded by default), are configured in Fcitx5 itself, not by this plugin, in this version.
  • The picker draws a US layout. Keys that only exist on other physical layouts still reach their candidates through the Other scripts strip, but they aren't placed on the board.

A note on writing Fcitx5's config

Config changes go through Fcitx5's own D-Bus API (org.fcitx.Fcitx.Controller1.SetConfig), not by editing ~/.config/fcitx5/conf/*.conf behind its back.

Fcitx5 owns those files while it runs: it rewrites them from its in-memory state on a periodic autosave (roughly every 30 minutes) and again on shutdown — including the shutdown half of a systemctl restart issued to apply an edit. An edit written straight to the file therefore races Fcitx5's own save, and is silently reverted whenever it loses. That race is what made the toggle work only sometimes, and what could leave the candidate popup on Fcitx5's stock theme after a theme change. Going through SetConfig updates the live process, which then persists the file itself: no race, and no restart needed for a pure config change.

Writing the file directly is still the right move when Fcitx5 is not running — nothing is up to overwrite it, and Fcitx5 reads it on its next start — so that is exactly the fallback path the scripts take (and the only path that restarts anything).

A note on restarting Fcitx5

The theme hook is the one place that still restarts Fcitx5, once, after regenerating the theme: the theme name never changes, only the PNGs behind it, and a running ClassicUI keeps the images it has already loaded. Nothing else restarts, so an enable that also installs the theme hook no longer restarts twice in a row — back-to-back restarts leave a window with no input method bound at all (Fcitx5's Wayland handshake takes ~10s) and can trip the unit's StartLimitBurst.

On a stock Omarchy install, Fcitx5 runs under a systemd user service (omarchy-fcitx5.service, Restart=always). This plugin restarts Fcitx5 with systemctl --user restart omarchy-fcitx5.service — never a detached fcitx5 -r &. A detached replace process steals Fcitx5's D-Bus name out from under the service; the service's own process then fails to reacquire that name, exits, and systemd immediately restarts it, forever, in a silent fast crash-loop that leaves the orphan as the only working instance. systemctl restart stops the managed process first, so there's no name collision. If the unit isn't present, the script falls back to the detached replace.

Extra: matching the candidate popup to your Omarchy theme

extras/theme-set.d/fcitx5-theme.sh regenerates a Fcitx5 ClassicUI theme ("omarchy") from your active Omarchy theme's colors (omarchy-theme-color): matching background/accent/foreground, rounded corners with a soft drop shadow (generated as 9-patch PNGs, since Fcitx5's theme format only takes flat colors or images — no border-radius), the system font (JetBrainsMono Nerd Font), UseAccentColor=False (ClassicUI otherwise resolves a system accent color from the desktop portal asynchronously, repainting the popup a while after it is already up, with a color unrelated to your Omarchy theme), and native compositor blur via Fcitx5's own EnableBlur (the KDE blur protocol, which Hyprland also implements — this does not touch Hyprland's own decoration:blur:enabled, so it works even on themes that keep window blur off).

The plugin installs this automatically into ~/.config/omarchy/hooks/theme-set.d/ the first time you turn Press & Hold on — no manual step needed. To install or reapply it by hand instead:

mkdir -p ~/.config/omarchy/hooks/theme-set.d
cp extras/theme-set.d/fcitx5-theme.sh ~/.config/omarchy/hooks/theme-set.d/
chmod +x ~/.config/omarchy/hooks/theme-set.d/fcitx5-theme.sh
~/.config/omarchy/hooks/theme-set.d/fcitx5-theme.sh   # apply immediately

Once installed (by the plugin or by hand), Omarchy re-runs it automatically on every omarchy theme set (via the theme-set.d hook contract), so the popup keeps matching whichever theme you switch to.

Optional dependency: rounded corners and the drop shadow are generated with ImageMagick (magick), which is not part of a stock Omarchy install — only omarchy-theme-color is guaranteed present. If magick isn't found, the hook still applies colors, font, and blur, just with a flat rectangle (Color/BorderColor) instead of rounded corners. Install imagemagick if you want the rounded version.

Known limitation: the popup's position relative to the text cursor (Fcitx5 anchors near the cursor rect it's given, extending right/down — not centered above the character like macOS) is not configurable; Fcitx5's ClassicUI doesn't expose an anchor/gravity setting for the panel itself, only for decorative overlays within the theme images.

License

MIT