Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ concurrency:
jobs:
test:
name: Test
runs-on: macos-15
runs-on: macos-26
timeout-minutes: 30

steps:
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ help:
doctor:
@[[ "$$(uname -s)" == Darwin ]] || { echo 'error: macOS is required' >&2; exit 1; }
@[[ "$$(uname -m)" == arm64 ]] || { echo 'error: an Apple Silicon Mac is required' >&2; exit 1; }
@major=$$(sw_vers -productVersion | cut -d. -f1); (( major >= 15 )) || { echo 'error: macOS 15 or newer is required' >&2; exit 1; }
@major=$$(sw_vers -productVersion | cut -d. -f1); (( major >= 26 )) || { echo 'error: macOS 26 or newer is required' >&2; exit 1; }
@for tool in curl docker pkg-config python3 swift xcrun; do command -v "$$tool" >/dev/null || { echo "error: $$tool is required" >&2; exit 1; }; done
@docker info >/dev/null 2>&1 || { echo 'error: Docker is installed but not running' >&2; exit 1; }
@printf 'Toolchain ready: %s (%s)\n' "$$(sw_vers -productVersion)" "$$(uname -m)"
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ safety floor.
## Requirements

- Apple Silicon Mac (`arm64`)
- macOS 15 or newer
- macOS 26 or newer
- At least 8 GB free initially

On M3 and newer Apple Silicon, Try Omarchy also exposes ARM EL2 to Linux, so
Expand Down Expand Up @@ -458,7 +458,7 @@ brew install pkg-config
```

`make doctor` performs the basic preflight. `make runtime` downloads a
checksum-pinned `arm64_sequoia` dependency set, builds QEMU for macOS 15.0,
checksum-pinned dependency set, builds QEMU for macOS 26.0,
and rejects any runtime image that raises that minimum or strongly imports an
API unavailable on the declared platform. Installed Homebrew library versions
are never copied into the app.
Expand Down
66 changes: 66 additions & 0 deletions docs/alacritty-migration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Enable accelerated Alacritty in an existing guest

New factory images use the packaged Alacritty binary directly. An existing VM
may still contain the factory `/usr/local/bin/alacritty` wrapper that forces
software rendering. Updating the Mac app does not replace files in an existing
VM, so retiring that wrapper is a one-time, opt-in step. No factory reset or
package removal is needed.

The migration helper only runs when the current boot advertises
`omarchy.virgl_dual_source=1`, which the launcher supplies with the fixed VirGL
runtime. This marker identifies that specific fix; it is not a claim that every
OpenGL application is compatible. Kitty's separate workaround is unaffected.

## Copy the helper from the installed app

On the Mac, choose the actual location of the updated application, then copy its
bundled helper to a folder you share with the VM. For example, with Downloads
selected as the VM's shared folder:

```sh
APP="/Applications/Try Omarchy.app"
cp -n "$APP/Contents/Resources/scripts/try-omarchy-migrate-alacritty" "$HOME/Downloads/"
```

Restart the VM using the updated app so it receives the runtime marker. Inside
Omarchy, run the copied helper from the shared folder:

```sh
sudo /usr/bin/python3 -I /mnt/mac/try-omarchy-migrate-alacritty
```

Alternatively, copy the same bundled file into the guest using an existing SSH
connection and run it with `sudo /usr/bin/python3 -I /path/to/try-omarchy-migrate-alacritty`.
SSH access and sharing are not enabled automatically by this migration.

## What the helper changes

The helper recognizes the exact factory wrapper by its SHA-256 digest
`9f2da34ccfbbf5402233c1e19ca09197c03c8a7fda3369e4adaaff2d5df7c67e`.
It preserves the original file and its metadata as
`/usr/local/bin/.alacritty.try-omarchy-software-backup`, then removes only the
`/usr/local/bin/alacritty` PATH entry. An existing backup is never overwritten.

Custom contents, symbolic links, hard-linked files, and unprotected files or
directories are left unchanged. A repeated successful run is a no-op. A
“Preserved” result means no wrapper was removed; inspect the reported condition
before making any manual change.

Close and reopen Alacritty afterward. Existing terminal processes keep the
environment they started with. This helper does not change terminal selection,
Alacritty configuration, or the packaged `/usr/bin/alacritty` executable.

The new factory image also includes a marker-gated service that invokes the
helper before the graphical login manager. That service is **not automatically
installed into older guests**; the one-time copied helper is the existing-guest
migration path.

If reverting to an older host runtime, the retained wrapper can be restored
without overwriting a newly created custom wrapper:

```sh
sudo mv -n -- /usr/local/bin/.alacritty.try-omarchy-software-backup /usr/local/bin/alacritty
```

The factory service will retire an exact restored wrapper again on a subsequent
boot with the fixed-runtime marker.
2 changes: 1 addition & 1 deletion docs/releasing.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Releasing

Releases are Apple Silicon-only and require macOS 15 or newer.
Releases are Apple Silicon-only and require macOS 26 or newer.

## Build and verify

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[Unit]
Description=Retire the factory Alacritty software-rendering workaround
ConditionKernelCommandLine=omarchy.virgl_dual_source=1
After=local-fs.target
Before=sddm.service display-manager.service

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/try-omarchy-migrate-alacritty

[Install]
WantedBy=multi-user.target
93 changes: 93 additions & 0 deletions guest/native-overlay/usr/local/sbin/try-omarchy-migrate-alacritty
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#!/usr/bin/python3 -I
"""Retire the known factory workaround after the host enables fixed VirGL."""

import errno
import hashlib
import os
from pathlib import Path
import stat
import sys

MARKER = "omarchy.virgl_dual_source=1"
WRAPPER_SHA256 = "9f2da34ccfbbf5402233c1e19ca09197c03c8a7fda3369e4adaaff2d5df7c67e"
WRAPPER_SIZE = 688
BACKUP = ".alacritty.try-omarchy-software-backup"


def open_directory(path):
descriptor = os.open("/", os.O_RDONLY | os.O_DIRECTORY)
try:
for part in Path(path).parts[1:]:
child = os.open(part, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW,
dir_fd=descriptor)
os.close(descriptor)
descriptor = child
return descriptor
except OSError:
os.close(descriptor)
raise


def migrate(cmdline=Path("/proc/cmdline"), directory=Path("/usr/local/bin"), trusted_uid=0):
if MARKER not in cmdline.read_text().split():
return "Skipped: this boot does not advertise the fixed VirGL runtime."

parent = open_directory(directory)
try:
info = os.fstat(parent)
if info.st_uid != trusted_uid or info.st_mode & 0o022:
return "Preserved: the wrapper directory is not protected."
try:
source = os.open("alacritty", os.O_RDONLY | os.O_NOFOLLOW | os.O_NONBLOCK,
dir_fd=parent)
except FileNotFoundError:
return "No migration needed: no Alacritty wrapper is installed."
except OSError as error:
if error.errno == errno.ELOOP:
return "Preserved: the Alacritty wrapper is a symbolic link."
raise
try:
original = os.fstat(source)
if (not stat.S_ISREG(original.st_mode) or original.st_uid != trusted_uid
or original.st_mode & 0o022 or original.st_nlink != 1):
return "Preserved: the Alacritty wrapper is not an unmodified factory file."
content = os.read(source, WRAPPER_SIZE + 1)
if hashlib.sha256(content).hexdigest() != WRAPPER_SHA256:
return "Preserved: the Alacritty wrapper has custom contents."
try:
# An exclusive hard link preserves the original bytes and metadata
# before removing the PATH entry, without overwriting any backup.
os.link("alacritty", BACKUP, src_dir_fd=parent, dst_dir_fd=parent,
follow_symlinks=False)
except FileExistsError:
return "Preserved: an Alacritty migration backup already exists."
for name in ("alacritty", BACKUP):
current = os.stat(name, dir_fd=parent, follow_symlinks=False)
if (current.st_dev, current.st_ino) != (original.st_dev, original.st_ino):
raise RuntimeError("Wrapper changed during migration; no PATH entry was removed.")
os.unlink("alacritty", dir_fd=parent)
os.fsync(parent)
return "Migrated: the factory Alacritty wrapper was backed up; accelerated rendering is enabled."
finally:
os.close(source)
finally:
os.close(parent)


def main():
if len(sys.argv) != 1:
print("Usage: sudo try-omarchy-migrate-alacritty", file=sys.stderr)
return 2
if os.geteuid() != 0:
print("Run this migration with sudo.", file=sys.stderr)
return 1
try:
print(migrate())
except (OSError, RuntimeError) as error:
print(f"Alacritty migration failed: {error}", file=sys.stderr)
return 1
return 0


if __name__ == "__main__":
sys.exit(main())
6 changes: 3 additions & 3 deletions guest/packages.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -398,8 +398,8 @@
"libzip": "1.11.4-1",
"licenses": "20240728-1",
"lilv": "0.28.0-1",
"linux-aarch64": "7.2.3-2",
"linux-aarch64-headers": "7.2.3-2",
"linux-aarch64": "7.2.4-1",
"linux-aarch64-headers": "7.2.4-1",
"linux-api-headers": "7.2-1",
"llhttp": "9.3.1-1",
"llvm-libs": "22.1.8-2",
Expand Down Expand Up @@ -453,7 +453,7 @@
"openssh": "10.5p1-1",
"openssl": "3.6.4-1",
"opus": "1.6.1-1",
"orc": "0.4.43-1",
"orc": "0.4.44-1",
"osinfo-db": "20260812-1",
"p11-kit": "0.26.5-1",
"pacman": "7.1.0.r9.g54d9411-2",
Expand Down
2 changes: 1 addition & 1 deletion guest/scripts/configure-rootfs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ chmod 0755 \
"$root/usr/bin/omarchy-audio-input-set-default" \
"$root/usr/bin/omarchy-screensaver" \
"$root/usr/bin/omarchy-theme-bg-switcher" \
"$root/usr/local/bin/alacritty" \
"$root/usr/local/bin/xdg-terminal-exec" \
"$root/usr/local/bin/kitty" \
"$root/usr/local/bin/omarchy-arch-aarch64" \
Expand All @@ -92,6 +91,7 @@ chmod 0755 \
"$root/usr/local/bin/try-omarchy-touch-id-test" \
"$root/usr/local/lib/try-omarchy/native-authentication-broker" \
"$root/usr/local/sbin/try-omarchy-touch-id-control" \
"$root/usr/local/sbin/try-omarchy-migrate-alacritty" \
"$root/usr/local/sbin/try-omarchy-touch-id-enroll" \
"$root/usr/local/lib/try-omarchy/install-vivaldi-arm64" \
"$root/usr/lib/systemd/system-generators/try-omarchy-ssh-access"
Expand Down
1 change: 1 addition & 0 deletions guest/scripts/finalize-rootfs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ printf '%s %s\n' "$expected_vivaldi_key_sha256" "$vivaldi_key" | sha256sum -c -
systemctl enable omarchy-provision-owner.service
systemctl enable sddm.service
systemctl enable omarchy-native-mac-share.service
systemctl enable try-omarchy-migrate-alacritty.service

# The app expands only the writable APFS clone to 24 GiB. Grow ext4 online so
# Omarchy's update-safety check sees that working capacity.
Expand Down
File renamed without changes.
Loading
Loading