Profiles: machines, roles and shared layers
The repo was one machine's capture. It is now a set of profiles built from layers under profiles/: machines/ hp-laptop, macbook-air-m2, coder-desktop roles/ developer, devops, ai-agents features/ handoff (lan-mouse) shared base, personal, personal-desktop A profile resolves to its includes (depth first), any --roles, then itself; for a path several layers provide, the last wins. install.sh --show prints the layers and which one owns each file. Hyprland settings no longer share a file: base's hyprland.lua loads ~/.config/hypr/layers/*.lua with Omarchy's own require_all, and bindings.lua stays stock so nothing binds twice. Verified with Hyprland 0.56.2 --verify-config for all three profiles, plus a broken probe layer to prove the directory is loaded. packages.txt gains per-line arch (Arch Linux ARM lacks opencode, codex, mise, shellcheck) and cmd= (skip when dotfiles' ~/.local/bin already provides the command), and an [ignore] section that replaces capture.sh's hard-coded list. Tab-separated records would have collapsed empty fields under read, so package records use the unit separator. hp-laptop: re-captured. monitors.lua catch-all scale is now 1, shell.json has four new plugins, fix-stuck-displays has its connector-name fix, navbar-cat is gone, plugin-manager and omarchy-phone are pinned, the herdr-hud working tree is re-diffed and bin/herdr-web rides along. Its handoff peer is now the Air (192.168.1.49); the old default list was the HP's own addresses, written from the Air's side. macbook-air-m2: captured read-only over SSH as it is (no themes, plugins or bar changes). Its LAN_MOUSE_POINTER_SCALE=0.7 moves from the shared unit into a lan-mouse.service.d drop-in in its own layer. coder-desktop: the Omarchy settings covert-cloud's image used to patch in by hand (Virtual-1 at 1920x1080, no animations, stay-awake, Retro 82 once), for the image to apply at a pinned commit. Roles reach it per workspace via install.sh --roles ... --no-clobber. capture.sh writes each file back into the layer that owns it, and refuses to run before the first layered install unless --force, since the old file shapes would land in shared layers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0153egowV1Xw2RNjZnSyZicc
This commit is contained in:
+53
@@ -0,0 +1,53 @@
|
||||
#!/bin/bash
|
||||
# Release display pipes the kernel left enabled on unplugged connectors.
|
||||
#
|
||||
# After suspend/resume (or unplugging a USB-C display) i915 can leave a
|
||||
# connector "disconnected" but still "enabled" on a pipe that Hyprland has
|
||||
# forgotten. That pipe then blocks every other external output from
|
||||
# modesetting (black screens, or a ~5 s re-modeset loop).
|
||||
#
|
||||
# Fix: force the connector on so Hyprland sees it, disable it from Hyprland
|
||||
# (which releases the pipe), force it off, then return it to auto-detect.
|
||||
# Never `hyprctl reload` here: a reload re-enables the connector while it is
|
||||
# forced on and re-sticks the pipe.
|
||||
|
||||
log() { echo "fix-stuck-displays: $*"; logger -t fix-stuck-displays -- "$*"; }
|
||||
|
||||
wait_for() { # wait_for <seconds> <command...>
|
||||
local n=$(( $1 * 4 )); shift
|
||||
for _ in $(seq "$n"); do "$@" && return 0; sleep 0.25; done
|
||||
return 1
|
||||
}
|
||||
|
||||
stuck=()
|
||||
for d in /sys/class/drm/card*-*; do
|
||||
[[ -f $d/status && -f $d/enabled ]] || continue
|
||||
[[ $d == *eDP* ]] && continue
|
||||
[[ $(<"$d/status") == disconnected && $(<"$d/enabled") == enabled ]] && stuck+=("$d")
|
||||
done
|
||||
|
||||
if (( ${#stuck[@]} == 0 )); then
|
||||
log "no stuck connectors"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
systemctl --user stop hyprmoncfgd
|
||||
|
||||
for d in "${stuck[@]}"; do
|
||||
out=${d##*/}; out=${out#card*-}
|
||||
log "releasing $out"
|
||||
echo on | sudo -n tee "$d/status" >/dev/null
|
||||
wait_for 5 sh -c "hyprctl monitors all | grep -q '^Monitor $out '" || log "$out never appeared in Hyprland"
|
||||
hyprctl eval "hl.monitor({ output = \"$out\", disabled = true })" >/dev/null
|
||||
wait_for 5 grep -qx disabled "$d/enabled" || log "$out still enabled after disable"
|
||||
echo off | sudo -n tee "$d/status" >/dev/null
|
||||
sleep 1
|
||||
echo detect | sudo -n tee "$d/status" >/dev/null
|
||||
log "$out now $(<"$d/status") $(<"$d/enabled")"
|
||||
done
|
||||
|
||||
# Drop any low-refresh fallback hyprmoncfgd wrote while outputs were failing.
|
||||
rm -f ~/.config/hyprmoncfg/display-fallbacks.json
|
||||
|
||||
# hyprmoncfgd re-applies the matching profile (modes, positions) on startup.
|
||||
systemctl --user start hyprmoncfgd
|
||||
@@ -0,0 +1,28 @@
|
||||
general.import = [ "~/.local/state/omarchy/current/theme/alacritty.toml" ]
|
||||
|
||||
[env]
|
||||
TERM = "xterm-256color"
|
||||
|
||||
[terminal]
|
||||
osc52 = "CopyPaste"
|
||||
|
||||
[font]
|
||||
normal = { family = "JetBrainsMono Nerd Font", style = "Regular" }
|
||||
bold = { family = "JetBrainsMono Nerd Font", style = "Bold" }
|
||||
italic = { family = "JetBrainsMono Nerd Font", style = "Italic" }
|
||||
size = 8
|
||||
|
||||
[window]
|
||||
padding.x = 14
|
||||
padding.y = 14
|
||||
decorations = "None"
|
||||
|
||||
[keyboard]
|
||||
bindings = [
|
||||
{ key = "Insert", mods = "Shift", action = "Paste" },
|
||||
{ key = "Insert", mods = "Control", action = "Copy" },
|
||||
# Send Shift+Return as CSI-u so TUIs can distinguish it from Return without treating it as Alt+Return.
|
||||
{ key = "Return", mods = "Shift", chars = "\u001B[13;2u" },
|
||||
# Legacy encoding sends Alt+Shift+Return the same as Alt+Return; send CSI-u so tmux can match M-S-Enter.
|
||||
{ key = "Return", mods = "Alt|Shift", chars = "\u001B[13;4u" }
|
||||
]
|
||||
@@ -0,0 +1,26 @@
|
||||
[main]
|
||||
include=~/.local/state/omarchy/current/theme/foot.ini
|
||||
term=xterm-256color
|
||||
font=JetBrainsMono Nerd Font:size=8
|
||||
pad=14x14
|
||||
initial-window-mode=windowed
|
||||
workers=0
|
||||
|
||||
[scrollback]
|
||||
lines=10000
|
||||
multiplier=7.0
|
||||
|
||||
[cursor]
|
||||
style=block
|
||||
blink=no
|
||||
|
||||
[key-bindings]
|
||||
clipboard-copy=Control+Insert Control+Shift+c XF86Copy
|
||||
primary-paste=none
|
||||
clipboard-paste=Shift+Insert Control+Shift+v XF86Paste
|
||||
|
||||
[text-bindings]
|
||||
# Send Shift+Return as CSI-u so TUIs can distinguish it from Return.
|
||||
\x1b[13;2u=Shift+Return
|
||||
# Send Alt+Shift+Return as CSI-u so tmux can match M-S-Enter.
|
||||
\x1b[13;4u=Mod1+Shift+Return
|
||||
@@ -0,0 +1,41 @@
|
||||
# Dynamic theme colors
|
||||
config-file = ?"~/.local/state/omarchy/current/theme/ghostty.conf"
|
||||
|
||||
# Font
|
||||
font-family = "JetBrainsMono Nerd Font"
|
||||
font-style = Regular
|
||||
font-size = 12
|
||||
|
||||
# Window
|
||||
window-theme = ghostty
|
||||
window-padding-x = 14
|
||||
window-padding-y = 14
|
||||
confirm-close-surface=false
|
||||
resize-overlay = never
|
||||
gtk-toolbar-style = flat
|
||||
|
||||
# Cursor styling
|
||||
cursor-style = "block"
|
||||
cursor-style-blink = false
|
||||
|
||||
# Cursor styling + SSH session terminfo
|
||||
# (all shell integration options must be passed together)
|
||||
shell-integration-features = no-cursor,ssh-env
|
||||
|
||||
# Keyboard bindings
|
||||
keybind = shift+insert=paste_from_clipboard
|
||||
keybind = control+insert=copy_to_clipboard
|
||||
# Send Shift+Enter as CSI-u so TUIs can distinguish it from Enter.
|
||||
keybind = shift+enter=csi:13;2u
|
||||
# Legacy encoding sends Alt+Shift+Enter the same as Alt+Enter; send CSI-u so tmux can match M-S-Enter.
|
||||
keybind = alt+shift+enter=csi:13;4u
|
||||
keybind = super+control+shift+alt+arrow_down=resize_split:down,100
|
||||
keybind = super+control+shift+alt+arrow_up=resize_split:up,100
|
||||
keybind = super+control+shift+alt+arrow_left=resize_split:left,100
|
||||
keybind = super+control+shift+alt+arrow_right=resize_split:right,100
|
||||
|
||||
# Slowdown mouse scrolling
|
||||
mouse-scroll-multiplier = 0.95
|
||||
|
||||
# Fix general slowness on hyprland (https://github.com/ghostty-org/ghostty/discussions/3224)
|
||||
async-backend = epoll
|
||||
@@ -0,0 +1,10 @@
|
||||
-- Extra autostart processes.
|
||||
-- o.launch_on_start("my-service")
|
||||
|
||||
-- Keyboard/mouse sharing with the other Omarchy laptop (lan-mouse).
|
||||
-- Runs as a daemon; input only crosses the screen edge once the peer is
|
||||
-- activated, so starting it here is inert until Handoff is toggled on.
|
||||
-- Superseded by the lan-mouse.service systemd user unit (journald logging,
|
||||
-- ordering after the portal, Restart=on-failure). launch_on_start sent both
|
||||
-- output streams to /dev/null, which hid every pairing failure.
|
||||
-- o.launch_on_start("lan-mouse daemon")
|
||||
@@ -0,0 +1,72 @@
|
||||
-- Keep only your personal input overrides here. Uncommented settings below
|
||||
-- replace Omarchy's defaults.
|
||||
|
||||
-- Keyboard layout and options.
|
||||
-- See https://wiki.hypr.land/Configuring/Basics/Variables/#input
|
||||
-- hl.config({
|
||||
-- input = {
|
||||
-- -- Use multiple keyboard layouts and switch between them with Left Alt + Right Alt.
|
||||
-- kb_layout = "us,dk,eu",
|
||||
-- kb_options = "compose:caps,shift:both_capslock_cancel,grp:alts_toggle",
|
||||
--
|
||||
-- -- Use a specific keyboard variant if needed (e.g. intl for international keyboards).
|
||||
-- kb_variant = "intl",
|
||||
--
|
||||
-- -- Change speed of keyboard repeat.
|
||||
-- repeat_rate = 40,
|
||||
-- repeat_delay = 250,
|
||||
--
|
||||
-- -- Start with numlock on by default.
|
||||
-- numlock_by_default = true,
|
||||
--
|
||||
-- -- Increase sensitivity for mouse/trackpad (default: 0).
|
||||
-- sensitivity = 0.35,
|
||||
--
|
||||
-- -- Turn off mouse acceleration (default: adaptive).
|
||||
-- accel_profile = "flat",
|
||||
--
|
||||
-- touchpad = {
|
||||
-- -- Use natural (inverse) scrolling.
|
||||
-- natural_scroll = true,
|
||||
--
|
||||
-- -- Use two-finger clicks for right-click instead of lower-right corner.
|
||||
-- clickfinger_behavior = true,
|
||||
--
|
||||
-- -- Control the speed of your scrolling.
|
||||
-- scroll_factor = 0.4,
|
||||
--
|
||||
-- -- Enable the touchpad while typing.
|
||||
-- disable_while_typing = false,
|
||||
--
|
||||
-- -- Left-click-and-drag with three fingers.
|
||||
-- drag_3fg = 1,
|
||||
-- },
|
||||
-- },
|
||||
-- })
|
||||
|
||||
-- App-specific touchpad scroll speeds.
|
||||
-- o.window("(Alacritty|kitty|foot)", { scroll_touchpad = 1.5 })
|
||||
-- o.window("com.mitchellh.ghostty", { scroll_touchpad = 0.2 })
|
||||
|
||||
-- Enable touchpad gestures for changing workspaces.
|
||||
-- See https://wiki.hypr.land/Configuring/Advanced-and-Cool/Gestures/
|
||||
hl.gesture({ fingers = 3, direction = "horizontal", action = "workspace" })
|
||||
|
||||
-- Enable touchpad gestures for moving focus (helpful on scrolling layout).
|
||||
-- hl.gesture({ fingers = 3, direction = "left", action = function() hl.dispatch(hl.dsp.focus({ direction = "l" })) end })
|
||||
-- hl.gesture({ fingers = 3, direction = "right", action = function() hl.dispatch(hl.dsp.focus({ direction = "r" })) end })
|
||||
|
||||
-- lan-mouse (omarchy-handoff) virtual pointer: kill the SECOND acceleration pass.
|
||||
-- lan-mouse forwards RELATIVE deltas that the SENDING compositor has already
|
||||
-- accelerated. Omarchy leaves accel_profile unset (adaptive), so the receiver
|
||||
-- amplifies them again and the pointer arrives hypersensitive while the local
|
||||
-- trackpad feels normal. "flat" applies no curve, so a forwarded delta moves
|
||||
-- exactly as far as the sender intended.
|
||||
-- The name is "unknown-device" because wlr-virtual-pointer gives Hyprland no
|
||||
-- name (virtual KEYBOARDS get named, pointers don't). Verified on this machine
|
||||
-- with `lan-mouse test-emulation` + `hyprctl devices`: no real device here is
|
||||
-- named unknown-device* (real pointers are elan0138:*, mouse-passthrough*,
|
||||
-- dp-3-1), so this rule cannot touch the trackpad. Two entries because the
|
||||
-- daemon may hold more than one virtual pointer at a time.
|
||||
hl.device({ name = "unknown-device", sensitivity = 0, accel_profile = "flat" })
|
||||
hl.device({ name = "unknown-device-1", sensitivity = 0, accel_profile = "flat" })
|
||||
@@ -0,0 +1,48 @@
|
||||
-- BEGIN hyprmoncfg wake settings
|
||||
-- Shared with Omarchy while hyprmoncfg manages displays.
|
||||
hl.monitor({ output = "eDP-1", mode = "preferred", position = "0x0", scale = 1.25 })
|
||||
-- END hyprmoncfg wake settings
|
||||
-- See https://wiki.hypr.land/Configuring/Basics/Monitors/
|
||||
-- List current monitors and supported resolutions with: hyprctl monitors all
|
||||
--
|
||||
-- SINGLE SOURCE OF TRUTH for display config.
|
||||
-- Do not add monitor rules anywhere else (hyprland.lua, a hyprmoncfg-generated
|
||||
-- file, etc.) -- overlapping rules from several files were what made external
|
||||
-- displays unrecoverable before.
|
||||
|
||||
local omarchy_gdk_scale = 1
|
||||
local omarchy_monitor_scale = 1
|
||||
|
||||
hl.env("GDK_SCALE", tostring(omarchy_gdk_scale))
|
||||
|
||||
-- Catch-all: anything not named below gets its EDID-preferred mode.
|
||||
hl.monitor({ output = "", mode = "preferred", position = "auto", scale = omarchy_monitor_scale })
|
||||
|
||||
-- Built-in laptop panel.
|
||||
hl.monitor({
|
||||
output = "desc:Chimei Innolux Corporation 0x1642",
|
||||
mode = "1920x1200@60",
|
||||
position = "auto",
|
||||
scale = 1.25,
|
||||
})
|
||||
|
||||
-- LG IPS236 on the laptop's own HDMI port.
|
||||
hl.monitor({
|
||||
output = "desc:LG Electronics IPS236 105NDLS5A720",
|
||||
mode = "1920x1080@60",
|
||||
position = "auto",
|
||||
scale = 1,
|
||||
})
|
||||
|
||||
-- LG TV via the Anker USB-C dock.
|
||||
-- Deliberately NOT forced to 3840x2160@60: the dock negotiates DP alt-mode
|
||||
-- with only 2 lanes (pin assignment D), which leaves no bandwidth headroom at
|
||||
-- 4K60. Forcing it produced a "monitor has no mode" loop. "preferred" is
|
||||
-- 3840x2160@30 here, which links reliably. Use 1920x1080@120 instead if you
|
||||
-- want high refresh over this dock.
|
||||
hl.monitor({
|
||||
output = "desc:LG Electronics LG TV SSCR2 0x01010101",
|
||||
mode = "preferred",
|
||||
position = "auto",
|
||||
scale = 1.25,
|
||||
})
|
||||
@@ -0,0 +1,23 @@
|
||||
# Remove the include below to disconnect Kitty from Omarchy's theming system.
|
||||
include ~/.local/state/omarchy/current/theme/kitty.conf
|
||||
|
||||
# Settings below override Omarchy's defaults in /etc/xdg/kitty/kitty.conf.
|
||||
# Learn more: https://sw.kovidgoyal.net/kitty/conf/
|
||||
|
||||
# Font
|
||||
# font_family JetBrainsMono Nerd Font
|
||||
# font_size 12
|
||||
|
||||
# Window padding
|
||||
# window_padding_width 14
|
||||
|
||||
# Unmap a shortcut, passing it through to the terminal application
|
||||
# map ctrl+insert
|
||||
|
||||
# Set or replace a shortcut
|
||||
# map ctrl+shift+c copy_to_clipboard
|
||||
|
||||
# Remove all inherited shortcuts, including Kitty's built-in shortcuts
|
||||
# clear_all_shortcuts yes
|
||||
|
||||
font_size 8.0
|
||||
@@ -0,0 +1,48 @@
|
||||
# HP laptop (omarchy-laptop) packages beyond the Omarchy 4.x baseline and the
|
||||
# packages its other layers already list.
|
||||
#
|
||||
# Format (every layer's packages.txt): "name [arch...] [cmd=command] # why".
|
||||
# arch only install on these architectures (x86_64, aarch64)
|
||||
# cmd=X skip when command X is already on PATH (e.g. a dotfiles shim)
|
||||
# Sections:
|
||||
# [repo] official repos + the omarchy repo -> omarchy pkg add
|
||||
# [aur] AUR only -> omarchy pkg aur add
|
||||
# [optional] installed here, not required for the desktop to work
|
||||
# [ignore] installed here on purpose but not managed (capture.sh stays quiet)
|
||||
|
||||
[repo]
|
||||
# --- hardware: Intel + an Anker USB-C dock ---
|
||||
linux-omarchy # kernel this install actually boots
|
||||
linux-omarchy-headers # needed to build out-of-tree modules against it
|
||||
intel-ucode # CPU microcode
|
||||
vulkan-intel # Intel Vulkan driver
|
||||
lib32-vulkan-intel # 32-bit Vulkan, for Steam/Proton
|
||||
sof-firmware # Sound Open Firmware - required for this laptop's audio
|
||||
thermald # Intel thermal daemon; without it the CPU throttles hard
|
||||
zram-generator # compressed swap in RAM
|
||||
|
||||
# --- audio: full PipeWire stack with the Pulse/JACK/ALSA shims ---
|
||||
pipewire-pulse
|
||||
pipewire-alsa
|
||||
pipewire-jack
|
||||
libpulse
|
||||
gst-plugin-pipewire
|
||||
|
||||
# --- desktop / input ---
|
||||
python-evdev # input tooling used while debugging lan-mouse (not required by it)
|
||||
wayland-utils # wayland-info, used when debugging outputs
|
||||
ghostty # terminal (alongside Omarchy's default)
|
||||
|
||||
# --- apps ---
|
||||
1password
|
||||
1password-cli # `op`, which the dotfiles repo's secrets module uses
|
||||
bun-bin
|
||||
|
||||
[optional]
|
||||
steam # games; pulls a large 32-bit dependency tree
|
||||
|
||||
[ignore]
|
||||
# toolchain/base, present on any Omarchy install or pulled in as a dependency
|
||||
base base-devel sudo omarchy mkinitcpio linux-firmware efibootmgr devtools cmake ninja
|
||||
# the remote-access stack, out of this repo's scope
|
||||
wayvnc sunshine freerdp remmina omarchy-remote-desktop-backend pipewire-debug
|
||||
@@ -0,0 +1,8 @@
|
||||
# HP laptop (omarchy-laptop): Intel, an Anker USB-C dock, the LG IPS236 on HDMI
|
||||
# and the LG TV through the dock. The machine this repo was first captured from.
|
||||
description="HP laptop (omarchy-laptop): Intel, Anker dock, LG displays"
|
||||
include=(base personal personal-desktop features/handoff roles/developer roles/devops roles/ai-agents)
|
||||
hostnames=(omarchy-laptop)
|
||||
arch=x86_64
|
||||
# The peer for omarchy-handoff is the Air (Wi-Fi only).
|
||||
handoff_peer_ips=(192.168.1.49)
|
||||
@@ -0,0 +1 @@
|
||||
options hid_apple fnmode=2
|
||||
@@ -0,0 +1,9 @@
|
||||
# Two NICs (Wi-Fi wlo1, dock ethernet enp0s13f0u3u4u3) share 192.168.1.0/24.
|
||||
# With the defaults (arp_ignore=0/arp_announce=0) the host answers ARP for any
|
||||
# local address on any interface, so the subnet's mapping collapses onto
|
||||
# whichever NIC replied last -- traffic aimed at the Wi-Fi IP lands on the dock,
|
||||
# and the Wi-Fi path silently never gets exercised.
|
||||
# 1 = only answer ARP for addresses configured on the receiving interface.
|
||||
# 2 = always use the best local address for the target subnet when announcing.
|
||||
net.ipv4.conf.all.arp_ignore = 1
|
||||
net.ipv4.conf.all.arp_announce = 2
|
||||
Reference in New Issue
Block a user