max / alloy_tui
- Co-Authored-By
- Claude Opus 4.7 (1M context) <noreply@anthropic.com>
8 files changed,
+124 insertions,
-93 deletions
| @@ -180,9 +180,10 @@ | |||
| 180 | 180 | ||
| 181 | 181 | # ===================================================================== | |
| 182 | 182 | # Config tree — the etc/ and usr/ trees in the repo map 1:1 into | |
| 183 | - | # the image. Per-user defaults live under etc/skel/.config/; | |
| 184 | - | # system-wide config under etc/; Alloy-owned templates under | |
| 185 | - | # usr/share/alloy/. See docs/IMAGE.md for the layout. | |
| 183 | + | # the image. Per-user defaults live under etc/skel/.config/ and | |
| 184 | + | # etc/skel/.mozilla/ (Firefox first-launch profile seed); system- | |
| 185 | + | # wide config under etc/; Firefox autoconfig + mozilla.cfg under | |
| 186 | + | # usr/lib64/firefox/. See docs/IMAGE.md for the layout. | |
| 186 | 187 | # ===================================================================== | |
| 187 | 188 | COPY etc/ /etc/ | |
| 188 | 189 | COPY usr/ /usr/ |
| @@ -68,7 +68,7 @@ | |||
| 68 | 68 | 2. **Third-party repos:** Tailscale, any COPRs Alloy depends on for packages not in Fedora main. | |
| 69 | 69 | 3. **Package additions:** the full Alloy stack from [STACK.md](STACK.md) — compositor, bar, launcher, notifications, terminal, editor, shell, viewers, utilities, continuity daemons, fonts, themes. | |
| 70 | 70 | 4. **Package removals:** stock Silverblue desktop pieces Alloy replaces (gnome-shell, gdm — the latter gated on the greeter pick). | |
| 71 | - | 5. **Config tree:** the tree at `etc/skel/.config/*` (new-user defaults), `etc/*` (system-wide), and `usr/share/alloy/*` (Alloy-owned templates) in the repo maps 1:1 into the image. | |
| 71 | + | 5. **Config tree:** the tree at `etc/skel/.config/*` and `etc/skel/.mozilla/*` (new-user defaults, including the Firefox first-launch profile seed), `etc/*` (system-wide, including `etc/firefox/policies/policies.json`), and `usr/lib64/firefox/*` (Firefox autoconfig + `mozilla.cfg` default prefs) in the repo maps 1:1 into the image. | |
| 72 | 72 | 6. **Systemd presets:** which services are enabled by default (syncthing off by default, gammastep off until enrolled, alloy-hinged conditionally on FW12, etc.). | |
| 73 | 73 | 7. **Branding:** os-release, plymouth splash. | |
| 74 | 74 | 8. **Validation:** `bootc container lint` runs at build. |
| @@ -119,13 +119,14 @@ | |||
| 119 | 119 | ||
| 120 | 120 | ## Browser | |
| 121 | 121 | ||
| 122 | - | **Firefox (upstream) baked in as the default; ungoogled-chromium available as an opt-in Flatpak.** Alloy's identity work happens at the engine level, not the fork level, so upstream Firefox is the right base — no ESR lag, no fork-specific patch drift, the most-tested Gecko build shipping. Alloy owns the visual and behavioral layer via three files: | |
| 122 | + | **Firefox (upstream) baked in as the default; ungoogled-chromium available as an opt-in Flatpak.** Alloy's identity work happens at the engine level, not the fork level, so upstream Firefox is the right base — no ESR lag, no fork-specific patch drift, the most-tested Gecko build shipping. Alloy owns the visual and behavioral layer via four files, each landing at the path Firefox actually reads: | |
| 123 | 123 | ||
| 124 | - | - `/etc/firefox/policies/policies.json` — enterprise policy. Pins **uBlock Origin** as a force-installed, update-locked extension. Disables telemetry, Pocket, studies, sponsored tiles, new-tab feed, formfill, and password saving at the policy layer (higher-precedence than user prefs). | |
| 125 | - | - `usr/share/alloy/firefox/user.js` — user-profile prefs. Backs up the policy kills for the settings not exposed to enterprise policy, and configures compact UI density, blank new tab, DuckDuckGo suggestions off, quiet scroll. | |
| 126 | - | - `usr/share/alloy/firefox/userChrome.css` — Helium-style ultra-compact horizontal chrome (thin tab strip, compact address bar, no title bar, no menu bar, no bookmarks bar), using Alloy's light-mode tokens (H=80, C=0.012 ramp from [TOKENS.md](TOKENS.md)). | |
| 124 | + | - [`etc/firefox/policies/policies.json`](../etc/firefox/policies/policies.json) — enterprise policy. Pins **uBlock Origin** as a force-installed, update-locked extension. Disables telemetry, Pocket, studies, sponsored tiles, new-tab feed, formfill, and password saving at the policy layer (higher-precedence than user prefs). | |
| 125 | + | - [`usr/lib64/firefox/mozilla.cfg`](../usr/lib64/firefox/mozilla.cfg) — system-wide default prefs, loaded via Firefox autoconfig. Configures compact UI density, blank new tab, DuckDuckGo suggestions off, quiet scroll, and enables `toolkit.legacyUserProfileCustomizations.stylesheets` so `userChrome.css` gets read. Every entry uses `defaultPref()` so users can still override in `about:config`. | |
| 126 | + | - [`usr/lib64/firefox/defaults/pref/autoconfig.js`](../usr/lib64/firefox/defaults/pref/autoconfig.js) — one-line pointer telling Firefox to load `mozilla.cfg` at startup. | |
| 127 | + | - [`etc/skel/.mozilla/firefox/profiles.ini`](../etc/skel/.mozilla/firefox/profiles.ini) + [`etc/skel/.mozilla/firefox/alloy.default/chrome/userChrome.css`](../etc/skel/.mozilla/firefox/alloy.default/chrome/userChrome.css) — first-launch profile seed. `profiles.ini` names a fixed-path profile (`alloy.default/`) so the pre-seeded `chrome/userChrome.css` (Helium-style ultra-compact horizontal, Alloy light-mode tokens from [TOKENS.md](TOKENS.md)) lands under it. Firefox opens the seeded profile on first launch instead of generating a random-suffix one. | |
| 127 | 128 | ||
| 128 | - | Runs all modern sites (uBlock Origin blocks ads, never JS). Horizontal tabs only, per firm preference. Config lives at [`usr/share/alloy/firefox/`](../usr/share/alloy/firefox/) and [`etc/firefox/policies/`](../etc/firefox/policies/) with a README explaining install and verification. | |
| 129 | + | Runs all modern sites (uBlock Origin blocks ads, never JS). Horizontal tabs only, per firm preference. | |
| 129 | 130 | ||
| 130 | 131 | **Ungoogled-chromium** is offered as the second-engine escape valve for the rare site that only renders correctly under Blink, and for users who prefer Chromium ergonomics without Google telemetry. Not baked into the ISO. Install path: | |
| 131 | 132 |
| @@ -9,7 +9,7 @@ | |||
| 9 | 9 | * warm cream / papery beige — the Flatwhite family aesthetic — by design. | |
| 10 | 10 | * | |
| 11 | 11 | * Requires: toolkit.legacyUserProfileCustomizations.stylesheets = true | |
| 12 | - | * (set in user.js). | |
| 12 | + | * (set in usr/lib64/firefox/mozilla.cfg as a system default). | |
| 13 | 13 | */ | |
| 14 | 14 | ||
| 15 | 15 | :root { |
| @@ -1,0 +1,9 @@ | |||
| 1 | + | [General] | |
| 2 | + | StartWithLastProfile=1 | |
| 3 | + | Version=2 | |
| 4 | + | ||
| 5 | + | [Profile0] | |
| 6 | + | Name=alloy | |
| 7 | + | IsRelative=1 | |
| 8 | + | Path=alloy.default | |
| 9 | + | Default=1 |
| @@ -1,0 +1,12 @@ | |||
| 1 | + | // Alloy Firefox autoconfig pointer. | |
| 2 | + | // | |
| 3 | + | // Tells Firefox to load /usr/lib64/firefox/mozilla.cfg on startup. | |
| 4 | + | // obscure_value = 0 means mozilla.cfg is plain-text (Firefox's byte- | |
| 5 | + | // shift obfuscation is off); we still keep the mandatory first-line | |
| 6 | + | // comment because Firefox skips it unconditionally. | |
| 7 | + | // | |
| 8 | + | // See usr/lib64/firefox/mozilla.cfg for the actual defaults. | |
| 9 | + | ||
| 10 | + | pref("general.config.filename", "mozilla.cfg"); | |
| 11 | + | pref("general.config.obscure_value", 0); | |
| 12 | + | pref("general.config.sandbox_enabled", false); |
| @@ -1,0 +1,91 @@ | |||
| 1 | + | // Alloy Firefox system defaults | |
| 2 | + | // | |
| 3 | + | // Loaded via /usr/lib64/firefox/defaults/pref/autoconfig.js, which | |
| 4 | + | // points Firefox at this file at startup. Applies system-wide as | |
| 5 | + | // default preferences; users can still override any value in | |
| 6 | + | // about:config or via profile prefs. | |
| 7 | + | // | |
| 8 | + | // Locked prefs (telemetry, Pocket, extension pinning, etc.) live in | |
| 9 | + | // /etc/firefox/policies/policies.json — that layer is stronger than | |
| 10 | + | // this one and its settings cannot be overridden. | |
| 11 | + | // | |
| 12 | + | // IMPORTANT: Line 1 of this file MUST be a comment. Firefox skips | |
| 13 | + | // the first line unconditionally as an anti-tamper heuristic. Do | |
| 14 | + | // not add a `defaultPref` on line 1. | |
| 15 | + | ||
| 16 | + | // ------------------------------------------------------------------- | |
| 17 | + | // Enable userChrome.css / userContent.css loading. Alloy ships the | |
| 18 | + | // chrome CSS at ~/.mozilla/firefox/alloy.default/chrome/userChrome.css | |
| 19 | + | // via etc/skel; without this pref Firefox ignores it. | |
| 20 | + | // ------------------------------------------------------------------- | |
| 21 | + | defaultPref("toolkit.legacyUserProfileCustomizations.stylesheets", true); | |
| 22 | + | ||
| 23 | + | // ------------------------------------------------------------------- | |
| 24 | + | // Force light chrome theme — Alloy Flatwhite-adjacent palette lives | |
| 25 | + | // in userChrome.css. Do not follow system dark mode for browser UI. | |
| 26 | + | // ------------------------------------------------------------------- | |
| 27 | + | defaultPref("ui.systemUsesDarkTheme", 0); | |
| 28 | + | defaultPref("browser.theme.toolbar-theme", 1); // 0=dark, 1=light, 2=system | |
| 29 | + | defaultPref("browser.theme.content-theme", 2); // web content follows system | |
| 30 | + | ||
| 31 | + | // ------------------------------------------------------------------- | |
| 32 | + | // UI density and layout — Helium-style compact horizontal | |
| 33 | + | // ------------------------------------------------------------------- | |
| 34 | + | defaultPref("browser.uidensity", 1); // compact | |
| 35 | + | defaultPref("browser.tabs.tabMinWidth", 60); // slim tabs | |
| 36 | + | defaultPref("browser.tabs.tabmanager.enabled", false); // no dropdown list | |
| 37 | + | defaultPref("browser.bookmarks.toolbar.visibility", "never"); // hide bookmarks bar | |
| 38 | + | defaultPref("browser.tabs.firefox-view", false); // no Firefox View button | |
| 39 | + | defaultPref("browser.tabs.firefox-view-next", false); | |
| 40 | + | ||
| 41 | + | // Explicitly no vertical tabs. | |
| 42 | + | defaultPref("sidebar.verticalTabs", false); | |
| 43 | + | defaultPref("sidebar.revamp", false); | |
| 44 | + | ||
| 45 | + | // ------------------------------------------------------------------- | |
| 46 | + | // New tab / home page — blank | |
| 47 | + | // ------------------------------------------------------------------- | |
| 48 | + | defaultPref("browser.startup.homepage", "about:blank"); | |
| 49 | + | defaultPref("browser.newtabpage.enabled", false); | |
| 50 | + | defaultPref("browser.newtab.url", "about:blank"); | |
| 51 | + | defaultPref("browser.newtabpage.activity-stream.showSponsored", false); | |
| 52 | + | defaultPref("browser.newtabpage.activity-stream.showSponsoredTopSites", false); | |
| 53 | + | defaultPref("browser.newtabpage.activity-stream.feeds.topsites", false); | |
| 54 | + | defaultPref("browser.newtabpage.activity-stream.feeds.section.topstories", false); | |
| 55 | + | defaultPref("browser.newtabpage.activity-stream.feeds.snippets", false); | |
| 56 | + | ||
| 57 | + | // ------------------------------------------------------------------- | |
| 58 | + | // Search — DuckDuckGo default; suggestions off | |
| 59 | + | // ------------------------------------------------------------------- | |
| 60 | + | defaultPref("browser.search.suggest.enabled", false); | |
| 61 | + | defaultPref("browser.urlbar.suggest.searches", false); | |
| 62 | + | defaultPref("browser.urlbar.suggest.quicksuggest.sponsored", false); | |
| 63 | + | defaultPref("browser.urlbar.suggest.quicksuggest.nonsponsored", false); | |
| 64 | + | defaultPref("browser.urlbar.trending.featureGate", false); | |
| 65 | + | defaultPref("browser.urlbar.weather.featureGate", false); | |
| 66 | + | ||
| 67 | + | // ------------------------------------------------------------------- | |
| 68 | + | // Privacy defaults not covered by enterprise policy | |
| 69 | + | // ------------------------------------------------------------------- | |
| 70 | + | defaultPref("browser.contentblocking.category", "strict"); | |
| 71 | + | defaultPref("privacy.donottrackheader.enabled", true); | |
| 72 | + | defaultPref("privacy.globalprivacycontrol.enabled", true); | |
| 73 | + | defaultPref("browser.formfill.enable", false); | |
| 74 | + | ||
| 75 | + | // ------------------------------------------------------------------- | |
| 76 | + | // Miscellany — reduce noise | |
| 77 | + | // ------------------------------------------------------------------- | |
| 78 | + | defaultPref("browser.aboutConfig.showWarning", false); | |
| 79 | + | defaultPref("browser.warnOnQuitShortcut", false); | |
| 80 | + | defaultPref("browser.tabs.warnOnClose", false); | |
| 81 | + | defaultPref("browser.tabs.warnOnCloseOtherTabs", false); | |
| 82 | + | defaultPref("browser.tabs.warnOnOpen", false); | |
| 83 | + | defaultPref("browser.download.useDownloadDir", true); | |
| 84 | + | defaultPref("browser.download.alwaysOpenPanel", false); | |
| 85 | + | ||
| 86 | + | // Smooth scrolling with sensible values (not the default overshoot). | |
| 87 | + | defaultPref("general.smoothScroll", true); | |
| 88 | + | defaultPref("mousewheel.default.delta_multiplier_y", 100); | |
| 89 | + | ||
| 90 | + | // Prevent accidental font size zoom on Ctrl+scroll. | |
| 91 | + | defaultPref("mousewheel.with_control.action", 0); |