Omahub
← All plugins
M

Workspace Tags

by MGC <chagel@gmail.com>

A workspace indicator that belongs to the monitor it is drawn on: each bar shows its own screen's tags and its own selection, instead of every bar mirroring whichever workspace is globally focused. Optionally generates a Hyprland config giving each monitor a private set of dwm-style tags, with per-tag layouts.

Security review

No obvious issues detected

Deterministic scan — not a security guarantee

None
Risk level
None
Analyzed commit
e9cfdac
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

Low
AI risk level
Low
Recommendation
install
Model
~deepseek/deepseek-v4-flash-latest
Analyzed commit
e9cfdac
Reviewed
1 month ago

The plugin is a legitimate workspace-tags bar widget that writes to Hyprland config files (with backups) and runs hyprctl commands, all clearly documented and user-consented. No obfuscation, network access, or destructive behavior was found; the deterministic scan also reported no issues.

  • Modifies ~/.config/hypr/hyprland.lua by appending a fenced require block (backed up first) and generates ~/.config/hypr/workspace-tags.lua; this is expected functionality but touches critical config.
  • Runs shell commands via bar.run (hyprctl dispatch, cp) but uses proper quoting and only for workspace management and backups.
  • Development scripts (scripts/apply, scripts/watch) are not part of the runtime and are not executed automatically.
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/chagel/omarchy-workspace-tags --enable
Widgets #Hyprland #bar #workspaces

Workspace Tags

Per-monitor workspace tags for Omarchy, in the style of dwm. A bar widget that belongs to the monitor it is drawn on, plus an optional Hyprland config giving each screen its own private set of tags. Configured entirely from its own settings panel.

Omarchy's stock workspace widget lights whichever workspace is globally focused, so on two monitors both bars draw the same row and one of them is wrong:

                      stock                        this plugin
  left monitor    [1] 2  3  4  5              [1] 2  3  4  5  6  7  8  9
  right monitor   [1] 2  3  4  5               1  2  3  4  5 [6] 7  8  9
                   └── both bars agree,        └── each bar shows its own
                       and one of them lies        screen's tags

The tag row and the settings panel

Requirements

  • Omarchy with omarchy-shell (Quickshell)
  • Hyprland 0.56+ for per-monitor tags (Lua config API)
  • A CJK font for the two Chinese label styles only

No network access, no privileged operations, no bundled binaries.

Install

omarchy plugin add https://github.com/chagel/omarchy-workspace-tags.git --enable

It lands at the left of the bar and stands Omarchy's own workspace widget down so you are not left with two rows. Move it with omarchy bar move chagel.workspace-tags --section center.

Click the icon after the tags to open settings, or press SUPER+ALT+W. Clicking a tag only ever views that tag.

The widget works on stock Omarchy as-is — each bar showing its own screen's state. For the full dwm behaviour, turn on Per-monitor tags in the settings. That appends one fenced block to your ~/.config/hypr/hyprland.lua (backed up first, removed again when you switch it off), which is where keybindings and workspace rules have to live.

Bindings

All editable in the Shortcuts tab.

Key dwm Action
CTRL + 1–9 view Show tag N on this monitor. Asking for the tag you are on does nothing, as in dwm
SUPER+SHIFT + 1–9 tag Move the window to tag N here, and follow it
SUPER+SHIFT+ALT + 1–9 tag Move it there and stay put
SUPER + [ / ] focusmon Focus the monitor left / right
SUPER+SHIFT + , / . tagmon Move the window to the monitor left / right
SUPER + wheel Previous / next tag, wrapping within this monitor
SUPER+ALT + L layout keys Cycle this tag's layout: dwindle → master → scrolling
SUPER+ALT + W Open the settings panel

To go back to the tag you came from, use Omarchy's own SUPER+CTRL+Tab ("Former workspace"). Note its "previous" is Hyprland's and therefore global — change monitors in between and it can send you to the other screen.

All three of Omarchy's digit rows are unbound, not just the colliding ones: they switch by absolute workspace, which once ids are partitioned means teleporting to whichever monitor owns that id. Digit bindings of your own are unaffected.

How per-monitor tags work

Each monitor gets a block of ten workspace ids, and every binding resolves a tag against the focused monitor's block — so a digit key can never move focus between screens:

monitor tags workspace ids
leftmost 1–9 1–9
next 1–9 11–19
next 1–9 21–29

An id reads on sight: tens digit is the monitor, units the tag, so 16 is monitor 2's tag 6.

Monitors need no setting up — each is detected and remembered the first time it appears, left to right, and keeps its block whether or not it is plugged in, so unplugging one never renumbers the others. To reorder or prune, edit the monitors entry in shell.json.

Turning it on moves existing workspaces into the block that now owns them, windows included. To keep a window on a particular screen, renumber its workspace into the right block first:

hyprctl dispatch 'hl.dsp.workspace.change_id({ workspace = 6, id = 16 })'

Per-tag layouts

dwm's other half: each tag remembers its own arrangement. SUPER+ALT+L cycles dwindle → master → scrolling for the tag you are on. The choice is written where Omarchy already keeps per-workspace layouts, so its own layout toggle and this one cannot disagree.

Settings

Setting Default
tags 9 Tags per monitor, 1–9
monitors (detected) Remembered monitors, left to right. Edit shell.json to reorder or prune
tagLabels numbers Label style — see below
showSettingsIcon true Show the settings icon after the tags
settingsGlyph 󱂬 That icon's glyph
activeGlyph 󱓻 Marker for the active tag; empty shows its label
dimUnfocusedMonitor true Dim the selection on the monitor you are not on
occupiedOpacity 0.85 Opacity of tags holding windows
emptyOpacity 0.3 Opacity of empty tags

Every keybinding is a setting too (viewMods, moveMods, moveSilentMods, focusMonitorLeft/Right, moveMonitorLeft/Right, nextTag, previousTag, cycleLayout, openSettings), all edited from the Shortcuts tab.

Labels

tagLabels 1–9
numbers 1 2 3 4 5 6 7 8 9
roman I II III IV V VI VII VIII IX
greek α β γ δ ε ζ η θ ι
chinese 一 二 三 四 五 六 七 八 九
chinese-formal 壹 貳 參 肆 伍 陸 柒 捌 玖
letters A B C D E F G H I
dots ● ● ● ● ● ● ● ● ●

What it writes

~/.config/omarchy/shell.json its own settings entry, and the bar layout when a master switch stands another widget down
~/.config/hypr/hyprland.lua one fenced block, only while Per-monitor tags is on. Backed up first; nothing else touched
~/.config/hypr/workspace-tags.lua generated config, created and owned by this plugin
~/.local/state/omarchy/workspace-layouts/<id>.lua one line per tag whose layout you cycled

Nothing under ~/.config/hypr is written until you turn per-monitor tags on.

Remove

Turn Per-monitor tags off first — that takes the line back out of your hyprland.lua and gives Omarchy's workspace widget back. Then:

omarchy plugin remove chagel.workspace-tags

Removing the plugin while tags are still on leaves both behind, since nothing of ours runs afterwards to undo them. By hand: delete the fenced workspace-tags block from hyprland.lua, then rm ~/.config/hypr/workspace-tags.lua, then omarchy plugin enable omarchy.workspaces.

Windows keep their ids — 16 stays 16, now an ordinary workspace. Renumber with hyprctl dispatch 'hl.dsp.workspace.change_id({ workspace = 16, id = 6 })'.

Notes

  • The generated config is build output. Saving in the panel rewrites it and reloads Hyprland; hand edits do not survive. Change the settings instead.
  • omarchy refresh hyprland overwrites hyprland.lua, so the switch will read as off afterwards. omarchy update is safe.
  • There is deliberately no swap_monitors binding. It would put a pinned id on the wrong screen and fight the workspace rules. Move the windows instead.

Development

Link the plugin folder at your checkout and the QML reloads as you save it:

ln -s "$PWD" ~/.config/omarchy/plugins/chagel.workspace-tags

Generator.js does not follow — the QML engine loads a .pragma library once and keeps it, so the shell has to restart before an edit takes effect. Two scripts cover that:

scripts/apply    # restart the shell, then check the generated config matches
scripts/watch    # do it automatically as files are saved
node test/generator.test.js

Plain node, no dependencies. Generator.js holds everything that turns settings into Lua and is kept free of Qt so it can be tested outside the shell.

License

MIT