b63616422f427bb778f49f573e6cc197e29c7b4f
11
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
d3d9bea1ee |
Add a clock format with live seconds (#7586)
* Add a clock format with live seconds Right-clicking the clock now reaches "Thursday 09:39:23" and its AM/PM twin, and the widget's SystemClock ticks once a second only while a format that prints seconds is showing — every other format keeps the minute precision it had, so nobody pays for a repaint a second to read a label that changes once a minute. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Read an unterminated literal in a clock format as text Qt reads an opening quote with no closing one as a literal running to the end of the format, so "HH:mm 'sec" prints "09:39 sec" and never a second count — but the seconds test stripped only balanced quotes, saw the s, and put the widget on a per-second tick for a label that changes once a minute. The wiring assertions went the other way: each passed while the feature was broken, so hard-coding showsSeconds to false, dropping the label's onDateChanged, or commenting the precision line out and leaving the text behind all shipped green. Comments now come out of the source before it is matched, and both halves of the tick are asserted. Co-Authored-By: Codex XHigh <noreply@openai.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: Codex XHigh <noreply@openai.com> |
||
|
|
688d7df5d2 |
Drop the Windows VM start notification (#7585)
The shell already shows a "Launching Windows…" OSD from the moment the desktop entry is activated until the RDP window appears, so the notification duplicated feedback the user is already looking at. The failure notification stays: nothing else reports a VM that never came up. |
||
|
|
023021ad2d |
Add Remove > AI for the apps Install > AI offers (#7504)
* Add Remove > AI for the apps Install > AI offers Install > AI grew five entries and Remove grew one: Dictation, sitting on its own at the top level. Everything else installed from that menu had to come back out through Remove > Package by name. Mirror the install tree instead. Dictation moves under the new AI submenu where its installer already lives, and ChatGPT Desktop, Grok Bot, LM Studio, Ollama and T3 Code get removers beside it. Each entry is conditional on the thing actually being installed, so the submenu only ever lists what is there. What each remover deletes was read off a machine that had all five installed and launched, not guessed. That matters most for T3 Code, which bootstraps the agents it drives: ~/.claude.json, ~/.grok, ~/.npm and ~/.local/share/opencode all appear the first time it runs, and all of them outlive it, so it takes only ~/.config/t3code and ~/.t3. Grok Bot is the same trap in miniature -- ~/.grokbot is its own, ~/.grok belongs to the Grok CLI. Ollama drops every acceleration variant rather than the one the installer happened to pick, and disables the service before the package, since that is what holds the models open. 🤖 Generated by Opus 5 in Claude Code. * Remove only what these apps own, and only where removal works Three defects from an independent review of the previous commit. ChatGPT Desktop was deleting ~/.cache/codex-runtimes, which belongs to the Codex CLI rather than the desktop app: the `codex` binary resolves its runtime and plugins out of that directory, and it ships in a package this remover does not touch. Removing the desktop app took the CLI's prepared runtime with it, leaving a separate, still-installed tool to rebuild it -- and unable to, offline. Ollama's row appeared whenever the `ollama` command existed, but omarchy-pkg-drop removes exact package names. With ollama-bin, ollama-git or a hand-built binary the entry offered a removal it could not perform: the service went down, /var/lib/ollama and ~/.ollama were deleted, and it reported success with the program still installed. Every acceleration variant depends on the base package, so testing for that package covers each one the installer can produce and nothing it cannot remove. LM Studio keeps its models under a relocatable home, and ~/.lmstudio-home-pointer is the only record of where they went. The remover deleted the pointer and the default path, so a user who had moved their models kept every one of them while being told they were gone. Read the pointer before deleting it, and refuse one aimed at / or at the home directory itself, since following it there would take everything. Co-Authored-By: Codex XHigh <noreply@openai.com> --------- Co-authored-by: Codex XHigh <noreply@openai.com> |
||
|
|
260a729104 |
Add T3 Code to the AI install menu (#7496)
t3code-bin is in the Omarchy repo now, so the menu can offer it the way it offers Cursor and Grok Bot: install the package, then launch the desktop entry it ships.
The mark is a trace rather than a download. T3 publishes no monochrome SVG — the app icon is a black rounded tile with the letters knocked out of it, and a tile flattens to a solid square once the menu recolors every path with the theme foreground. Tracing the lettermark out of that icon keeps the silhouette that actually reads.
The font is package-owned, so the glyph reaches a desktop through an omarchy-settings release rather than omarchy update. Until that release lands, a pulled checkout draws the entry with no icon.
🤖 Generated by Opus 5 in Claude Code.
|
||
|
|
3765e8010b |
Switch DNS providers without a password prompt (#7472)
* Switch DNS providers without a password prompt The network panel and the menu run omarchy-dns from a process with no terminal, so require_root reached for pkexec and put a polkit password prompt in front of what is meant to be a one-click toggle. Grant %wheel passwordless sudo for the three stock providers and take that path whenever the grant covers the invocation. Custom stays out of the grant: it points the machine at servers the caller supplies, and it already runs in a terminal that can ask. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Pick the elevation path without asking sudo The `sudo -n -l` probe answered the wrong question. It reports whether a command is permitted, not whether it is passwordless, and the %wheel rule every Omarchy install ships permits everything -- `sudo -n -l /usr/bin/rm -rf /tmp/x` exits 0. So the probe passed for Custom too, and the exec below it ran `sudo -n`, which fails outright with no terminal and no way back to pkexec. Decide from what the sudoers rule actually says instead: sudo when there is a terminal to type into, or when the resolved path and the provider are both ones the rule names. Everything else keeps going through polkit. Pin a root-owned PATH once elevated, too. `omarchy dev link` puts a user-writable checkout ahead of sudo's secure_path for every command, so a passwordless grant on a script that resolves nmcli, tee, and install through PATH would otherwise hand root to whoever can write there. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Keep users outside %wheel on the polkit path The rule grants %wheel, so path and provider alone do not mean sudo will take it. A user outside the group was sent to sudo anyway, and with no terminal to answer the prompt that is a dead end -- polkit at least offers to authenticate as somebody else. Two holes in the test alongside it: it accepted any file containing the expected rule, so a second, argument-free line would have widened the grant unnoticed, and run as root it would have sailed past the stubs and rewritten the host's own DNS config. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Elevate the system install, whatever copy was invoked The rule names /usr/bin/omarchy-dns, so a dev-linked checkout handed sudo a path nothing could match and fell back to a polkit prompt. Re-exec the packaged path instead: the privileged half is the system install everywhere, the grant matches everywhere, and the path comparison and the PATH pinning that existed to work around the checkout both go away. Dev-linked checkouts run their own unprivileged half and the installed one as root, which is the trade for not carrying a second code path. --------- Co-authored-by: Omabot <david@hey.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
a4219f8f4a |
Store theme backgrounds as webp (#7477)
* Decode webp in the shell The background and the lock screen are drawn by Quickshell, so they decode through Qt, which ships handlers for png, jpeg and gif but not webp. QImageReader answers "Unsupported image format" and the layer comes up blank. Any third-party theme shipping a .webp background hits this today, even though every path that goes looking for a background already globs the extension. qt6-imageformats supplies the missing plugin for 71 KB downloaded. Its one new dependency of substance, libwebp, is already on every machine by way of libvips. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Store theme backgrounds as webp WebP codes both of the things these backgrounds are made of better than the formats they were in: the photographs, where its lossy mode is worth a third or more over JPEG at matched quality, and the flat art and dot patterns, where its lossless mode undercuts an oxipng-packed PNG. 28 of them become lossless webp and decode bit-for-bit identically (AE=0), so the dot patterns and flat-shaded pieces carry no quality question at all. That includes 0-launch, whose alpha channel comes through intact. The other 51 are photographs held to the same 38 dB PSNR floor as the JPEG pass, landing between 38.0 and 54.6 dB. Every image keeps its exact pixel dimensions, for 29.8 MB. Each one is encoded from the original as it stands in quattro rather than from the file the earlier commits produced, so nothing picks up a second generation of loss on the way here. 13 stay JPEG. WebP is plainly larger for most of them, and three are grainy enough that its filter smooths the grain instead of coding it: PSNR plateaus near 34 dB however high the quality goes, well under the floor. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
83987718cf |
Give the Quake console its own file, an agent, and half a screen (#7420)
* Open the scratchpad with the default agent already in it on_created_empty fires when the special workspace is created empty, so the agent starts the first time the console drops down instead of at boot, and comes back on the next open if you close it. The exec rule pins the workspace rather than trusting the spawn to inherit it: Hyprland only tags a process with its origin workspace while misc.initial_workspace_tracking is on, and we turn that off. Nothing to guard for a missing default agent. Omarchy picks none for you, and omarchy-agent exits without opening a window when none is set, so the scratchpad just opens empty until one is chosen. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Move the console into its own file and size it to half the screen The scratchpad's presentation was scattered through looknfeel: a dim in the decoration block, a workspace rule below it, two animation leaves further down again. Gathered into qconsole.lua, where the whole console is one readable thing. Sized to half the screen while it moved. A window rule cannot do that: its size expressions resolve once, when the window maps, so rescaling the monitor afterwards leaves a console that is no longer half of anything. Gaps are re-applied by the layout, so the console is sized by the gap left underneath it, recomputed from the monitor whenever the layout changes. Monitor dimensions come back in physical pixels while gaps are logical, so the scale comes out before the reserved area comes off. That arithmetic is the whole trick, and the test pins it at 1x, 2x and 1.5x. The test runs lua with an explicit "-". Bare `lua <<EOF` reads stdin as a REPL and exits 0 even after an error, which would leave its assertions unable to fail. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Only rewrite the console rule when its size actually changes Refitting replaces the rule in place rather than stacking a new one, so there was no leak, but each write still schedules a monitor and window state refresh and monitor.focused fires on every hop between screens. Remember what was last written and skip the write when the number has not moved. Also say out loud that the scale guard is what keeps the arithmetic below it safe: a monitor handle that has outlived its output answers nil to every field, and a layout change is exactly when that happens. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Drop the active window border inside the console The gradient border marks which window has focus, which the console does not need: it is only ever focused while it is open, and the dimmed workspace behind it already sets it apart. On a single agent terminal the highlight just reads as a frame around the panel. no_border on the workspace rule pins the border to 0 at workspace-rule priority, so it applies to whatever ends up in there without touching the global border. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Omabot <david@hey.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
ec779715bd |
Shrink theme backgrounds without touching resolution (#7266)
* Re-encode over-encoded theme backgrounds Several backgrounds shipped at quality 95-100, which buys nothing visible on a wallpaper but costs 20 MB. Re-encode those at quality 85, leaving resolution untouched -- every file keeps its original pixel dimensions. Only files stored above quality 90 are touched, and only when the result saves at least 15% and stays above 38 dB PSNR against the original. The 34 backgrounds already stored at quality 85 or below are left alone rather than pushed through another lossy generation for a few hundred KB. osaka-jade/2-shaded-entrance is skipped for that reason: nothing clears both bars. ristretto/2-coffee-beans is re-encoded at 90 instead of 85, where 85 fell below the PSNR floor. Theme backgrounds drop from 107 MB to 87 MB. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Store nord's night-hawks background as a palette PNG The file uses only 8 distinct colors but was saved as truecolor RGB, costing 1.8 MB for an image an indexed palette stores in half the space. Converting to a palette PNG is lossless: same dimensions, and zero pixels differ from the original. 1782 KB -> 909 KB. The other palette-eligible PNGs are already indexed, and re-compressing them with ImageMagick only makes them bigger, so they are left alone. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Recompress theme PNGs losslessly with oxipng Every background PNG was left at its authoring tool's default deflate settings. Running oxipng over them re-packs the same pixels: all 31 files decode bit-for-bit identically (AE=0) at unchanged resolution, for 981 KB. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Store photographic backgrounds as JPEG instead of PNG Four backgrounds were shipped as PNG despite being photographs and painterly illustrations, where lossless coding buys nothing the eye can see. Re-encoding them at the same q85 used by the other backgrounds keeps every pixel dimension and stays above 40 dB PSNR, for 3.3 MB. The remaining PNGs stay PNG: JPEG is larger for the dot patterns and the flat-shaded pieces, and 0-launch.png genuinely uses its alpha channel. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: David Heinemeier Hansson <david@hey.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
262d6f0681 |
Switch to the mise-bin package (#7244)
* Switch to the mise-bin package mise-bin carries mise's own release artifacts from the Omarchy repo -- PGO+BOLT-optimized on x86_64, glibc-native on both arches -- instead of Arch's mise, and tracks jdx/mise releases directly. Existing installs need a migration because the two packages conflict, and omarchy-pkg-add cannot make the swap: pacman answers its own conflict question with No under --noconfirm and fails the transaction. --ask=4 answers that one question, so mise-bin replaces mise in a single transaction -- which is also what keeps omarchy-zsh and omarchy-fish, both of which depend on mise, satisfied through the swap by its provides. * Guard the swap with a conditional instead of an early exit Two-path control flow takes an if, per the style guide; the early exit only made the swap line unreachable from a distance. |
||
|
|
7488eaded4 |
Document remapping the CapsLock compose key (#7091)
* Document remapping the CapsLock compose key * Clarify restoring CapsLock behavior |
||
|
|
33cda8b602 |
Add --gh-keys so sshd setup can run without prompts (#7086)
* Add --gh-keys so sshd setup can run without prompts Grabbing keys from GitHub was reachable only through the interactive menu: pick "Grab key from GitHub", then type the username into a second prompt. So the one path that needs no secret pasted around was also the one path a script could not take, and setting a machine up over ssh or from a provisioning run meant falling back to --key with a key copied by hand. --gh-keys <username> takes the same path the prompt did. The fetch and authorize logic is unchanged and now shared, with the prompt reduced to asking for the username and handing it over. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Reject a missing --gh-keys username before setting anything up The username was only checked for being absent entirely, and only after the server was installed and the firewall opened. So `--gh-keys=` with an unset variable behind it configured the machine and then dropped into the interactive menu, and `--gh-keys --help` took --help as the username and set the server up on its way to failing the fetch -- a help flag that changes the system. Check the value where it is parsed, and reject one that is empty or shaped like an option. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |