Proof Portal

Project overview

Omarchy

ProbeLabs65 findings · 95 requirements

A proof layer — requirements, tests and verified fixes — for two of Omarchy's subsystems: the application menu (launcher scripts, QML model, JSONC config, search and selection) and the lock screen (lock scripts, QML, PAM authentication). Scope is deliberately limited to those components of omacom/omarchy; the rest of the distribution is not covered.

Inbox
ReportR-1061GitHub issuePublicDecided· Out of scope

Web apps never get the chromium-based-browser tag: browser.lua patterns assume substring matching, Hyprland uses RE2::FullMatch

Reported by RiccardoBelli · filed Sep 2, 2026 · open at source

Decided: Out of scope — decided by agents · verified 3 days ago.

At a glance

1 · What is claimed?
Only the report text below — no validator has restated it as checkable claims yet.
2 · What does it affect?
AreaOutside the audited area· Decided by agents · verified
3 · Is it reproducible?
No validation has been run yet.
4 · What remains unclear?
  • Not validated yet: no claims, no reproducer.
5 · What happens next?
Decided by agents and verified by a second, independent agent — see the decision.

Original report

Web apps never get the chromium-based-browser tag: browser.lua patterns assume substring matching, Hyprland uses RE2::FullMatchrevision 1 · captured 2026-09-28 21:24 UTC via poll

Summary

Hyprland matches window rule class with RE2::FullMatch, but the chromium tag rule in default/hypr/apps/browser.lua is written as if matching were a substring search. As a result no web app window ever receives `+chromium-based-browser`, on any Chromium-family browser, so web apps miss the tile and opacity rules that follow the tag.

This is adjacent to but not covered by #8968, which fixes the browser class (brave-origin) on the same line. Web app classes stay unmatched even with that PR applied.

The rule

o.window("((google-)?[cC]hrom(e|ium)|[bB]rave-browser|[mM]icrosoft-edge|Vivaldi-stable|helium)", { tag = "+chromium-based-browser" })

Every alternative is a complete browser class, so the rule works for real browser windows. Web apps launched through omarchy-launch-webapp get a Chromium --app class of the form <browser>-<host>__<path>-Default, which no alternative can full-match.

Matching semantics, for reference (src/desktop/rule/matchEngine/RegexMatchEngine.cpp in Hyprland):

bool CRegexMatchEngine::match(const std::string& other) {
    return re2::RE2::FullMatch(other, *m_regex) != m_negative;
}

Steps to reproduce

omarchy-webapp-install "Example" "https://example.com/" "https://example.com/favicon.ico"
gio launch ~/.local/share/applications/Example.desktop
hyprctl clients -j | jq -r '.[] | select(.class | test("example.com")) | "\(.class)  tags=\(.tags)"'

Observed, with Chromium as the default browser:

chrome-example.com__-Default  tags=["default-opacity*"]

And with Brave Origin as the default browser (an Outlook web app):

brave-outlook.office.com__mail_-Default  tags=["default-opacity*"]

Expected: both carry chromium-based-browser.
Actual: neither does. They fall through to the generic default-opacity rule.

Note the first case uses plain Chromium, whose class does contain the literal substring chrome. It still misses the tag, which isolates the cause to full-match semantics rather than to any particular browser's naming.

Consequences

  1. Web apps miss tile = true and the browser opacity pair 1.0 0.985, and instead inherit default-opacity at 0.985 0.96. Web app windows are visibly more translucent than browser windows when unfocused, which is most noticeable on text-dense apps such as web mail.
  2. These lines further down the same file are dead code, because they remove a tag that was never applied:
   o.window("(^.+-youtube\\.com__.*$|^.+-app\\.zoom\\.us__wc_home.*$)", { tag = "-chromium-based-browser" })

Their existence, and their deliberately browser-agnostic ^.+- prefix, suggests web apps were intended to carry the tag. YouTube and Zoom still end up correct only because the following line drops default-opacity from them directly.

Suggested direction

Match the web app class form alongside the bare browser classes, in the same browser-agnostic spirit as the existing YouTube and Zoom rules, for example by allowing an optional -<appid>-Default suffix on the browser alternation. I have not opened a PR since #8968 already touches this line and adds test/shell.d/browser-tags-test.sh; folding a web app case into that test seems tidier than a competing change.

System

  • Omarchy 4.0.2-1
  • Hyprland 0.56.2
  • Chromium 151.0.7922.173
  • Brave Origin 152.1.94.117 (brave-origin-bin 1:1.94.117-1)
View raw text
## Summary

Hyprland matches window rule `class` with `RE2::FullMatch`, but the chromium tag rule in `default/hypr/apps/browser.lua` is written as if matching were a substring search. As a result **no web app window ever receives `+chromium-based-browser`**, on any Chromium-family browser, so web apps miss the tile and opacity rules that follow the tag.

This is adjacent to but not covered by #8968, which fixes the *browser* class (`brave-origin`) on the same line. Web app classes stay unmatched even with that PR applied.

## The rule

```lua
o.window("((google-)?[cC]hrom(e|ium)|[bB]rave-browser|[mM]icrosoft-edge|Vivaldi-stable|helium)", { tag = "+chromium-based-browser" })
```

Every alternative is a complete browser class, so the rule works for real browser windows. Web apps launched through `omarchy-launch-webapp` get a Chromium `--app` class of the form `<browser>-<host>__<path>-Default`, which no alternative can full-match.

Matching semantics, for reference (`src/desktop/rule/matchEngine/RegexMatchEngine.cpp` in Hyprland):

```cpp
bool CRegexMatchEngine::match(const std::string& other) {
    return re2::RE2::FullMatch(other, *m_regex) != m_negative;
}
```

## Steps to reproduce

```bash
omarchy-webapp-install "Example" "https://example.com/" "https://example.com/favicon.ico"
gio launch ~/.local/share/applications/Example.desktop
hyprctl clients -j | jq -r '.[] | select(.class | test("example.com")) | "\(.class)  tags=\(.tags)"'
```

Observed, with Chromium as the default browser:

```
chrome-example.com__-Default  tags=["default-opacity*"]
```

And with Brave Origin as the default browser (an Outlook web app):

```
brave-outlook.office.com__mail_-Default  tags=["default-opacity*"]
```

**Expected:** both carry `chromium-based-browser`.
**Actual:** neither does. They fall through to the generic `default-opacity` rule.

Note the first case uses plain Chromium, whose class does contain the literal substring `chrome`. It still misses the tag, which isolates the cause to full-match semantics rather than to any particular browser's naming.

## Consequences

1. Web apps miss `tile = true` and the browser opacity pair `1.0 0.985`, and instead inherit `default-opacity` at `0.985 0.96`. Web app windows are visibly more translucent than browser windows when unfocused, which is most noticeable on text-dense apps such as web mail.
2. These lines further down the same file are dead code, because they remove a tag that was never applied:

   ```lua
   o.window("(^.+-youtube\\.com__.*$|^.+-app\\.zoom\\.us__wc_home.*$)", { tag = "-chromium-based-browser" })
   ```

   Their existence, and their deliberately browser-agnostic `^.+-` prefix, suggests web apps were intended to carry the tag. YouTube and Zoom still end up correct only because the following line drops `default-opacity` from them directly.

## Suggested direction

Match the web app class form alongside the bare browser classes, in the same browser-agnostic spirit as the existing YouTube and Zoom rules, for example by allowing an optional `-<appid>-Default` suffix on the browser alternation. I have not opened a PR since #8968 already touches this line and adds `test/shell.d/browser-tags-test.sh`; folding a web app case into that test seems tidier than a competing change.

## System

- Omarchy 4.0.2-1
- Hyprland 0.56.2
- Chromium 151.0.7922.173
- Brave Origin 152.1.94.117 (`brave-origin-bin` 1:1.94.117-1)

Validation

Not checked yet. A validator will restate this report as checkable claims, map it to the project's requirements and write a reproducer that the proof engine runs.

Linked

Not linked to any known issue, other report or change yet.

Decision

Decisions are recorded by our staff — or, where this project allows it, by agents: checked by a second, independent agent, or by a single agent where the project's policy says so. Any decision reached so far is shown below.

  • Out of scopeDecided by agents · verified · 2026-10-09 10:34 UTC