From 1ed7fe89eacec86ea940ffa300129374890834a9 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 31 Aug 2026 23:44:24 +0000 Subject: [PATCH 1/3] Add PCSX2 and Dolphin to wolf.sh's auto-download emulators MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Factored the existing Azahar-only download block into a reusable _wolf_download_emulator_appimage() helper (same fetch-latest-release- and-find-.AppImage-asset logic, parameterized), then reused it for: - PCSX2 (PS2) — officially publishes Linux AppImages via GitHub Releases (PCSX2/pcsx2), same pattern as Azahar. - Dolphin (GameCube/Wii) — dolphin-emu.org's own Linux distribution is Flatpak-only, no official AppImage at all. Uses the well-regarded community AppImage build (pkgforge-dev/Dolphin-emu-AppImage) instead, with explicit warnings before the prompt and in the generated README that this is a third-party build, not an official Dolphin release — so the user can decide knowingly rather than this silently substituting an unofficial build for what looks like an official option. Motivated by a live "could not write to/read from Wii system memory" error — GameCube/Wii isn't handled by a RetroArch libretro core in any stable way (Dolphin's libretro core is unstable for Wii specifically), so ES-DE needs a real standalone Dolphin binary to hand those systems off to, the same way it already does for 3DS via Azahar. Also updated the DRY-RUN summary and the generated README's emulators section to describe all three instead of just Azahar. --- services/wolf.sh | 126 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 87 insertions(+), 39 deletions(-) diff --git a/services/wolf.sh b/services/wolf.sh index 04259c5..5cf6aa4 100644 --- a/services/wolf.sh +++ b/services/wolf.sh @@ -205,6 +205,45 @@ fi register_service wolf gaming "Cloud gaming via Moonlight (Games-on-Whales Wolf)" 47989 +# Downloads the latest GitHub-released AppImage for a standalone emulator into +# $EMU_DIR (skipped if a matching file is already there). AppImages dropped +# there are found automatically by ES-DE's app finder (it checks +# ~/Applications inside the container, mounted from emulators/) — this covers +# every system ES-DE hands off to a standalone frontend instead of a +# RetroArch libretro core (3DS, GameCube/Wii, PS2, ...). Same shape as the +# original Azahar-only download this was factored out of, just parameterized +# so PCSX2/Dolphin/anything else reuse the same fetch-latest-release logic +# instead of copy-pasting it per emulator. +_wolf_download_emulator_appimage() { + local _display_name="$1" _owner_repo="$2" _existing_glob="$3" _dir="$4" + if ls "$_dir"/$_existing_glob 2>/dev/null | grep -q .; then + log_info "$_display_name already present in $_dir/" + return 0 + fi + local _get="" + echo "" + log_info "$_display_name can be auto-downloaded." + prompt_yn "Download $_display_name AppImage now? (y/n):" "y" _get + [[ "$_get" =~ ^[Yy]$ ]] || return 0 + + log_info "Fetching latest $_display_name release from GitHub..." + local _url + _url=$(curl -fsSL "https://api.github.com/repos/${_owner_repo}/releases/latest" \ + | python3 -c "import sys,json; r=json.load(sys.stdin); \ + print(next((a['browser_download_url'] for a in r['assets'] \ + if a['name'].endswith('.AppImage')), ''))" 2>/dev/null) + if [[ -z "$_url" ]]; then + log_warning "Could not resolve download URL — get it manually from https://github.com/${_owner_repo}/releases" + return 1 + fi + local _file="$_dir/$(basename "$_url")" + curl -fL --progress-bar -o "$_file" "$_url" \ + && chmod +x "$_file" \ + && chown "$ACTUAL_USER:$ACTUAL_USER" "$_file" \ + && log_success "$_display_name downloaded: $_file" \ + || log_warning "Download failed — get it manually from https://github.com/${_owner_repo}/releases" +} + install_wolf() { require_docker || return 1 @@ -237,6 +276,8 @@ EOF echo " - Open Moonlight UFW ports: TCP ${WOLF_PORTS_TCP[*]} / UDP ${WOLF_PORTS_UDP[*]}" echo " - Start Wolf and inject Steam + EmulationStation app profiles" echo " - Create bios/ + retroarch/{cores,shaders,overlays}/ on the game drive and pre-download RetroArch cores (~1.5 GB)" + echo " - Offer to auto-download standalone emulator AppImages into emulators/:" + echo " Azahar (3DS), PCSX2 (PS2), Dolphin (GameCube/Wii — unofficial community build)" return 0 fi @@ -771,37 +812,33 @@ UDEV log_success "Storage layout: $GAME_STORAGE_DIR/{roms//,steam,saves,media,emulators,...}" log_info "ES-DE ROM directories pre-created. Drop ROMs in the matching subfolder." - # ── Optional: download Azahar (3DS emulator) ───────────────────────────── - # Azahar is an open-source Citra fork — the recommended legal 3DS emulator - # for ES-DE. AppImages dropped in emulators/ are found automatically by - # ES-DE's app finder (checks ~/Applications inside the container). - local _AZAHAR_DIR="$GAME_STORAGE_DIR/emulators" - if ! ls "$_AZAHAR_DIR"/azahar*.AppImage 2>/dev/null | grep -q .; then - local _get_az="" - echo "" - log_info "3DS emulation: Azahar (open-source Citra fork) can be auto-downloaded." - prompt_yn "Download Azahar 3DS emulator AppImage now? (y/n):" "y" _get_az - if [[ "$_get_az" =~ ^[Yy]$ ]]; then - log_info "Fetching latest Azahar release from GitHub..." - local _AZ_URL - _AZ_URL=$(curl -fsSL "https://api.github.com/repos/azahar-emu/azahar/releases/latest" \ - | python3 -c "import sys,json; r=json.load(sys.stdin); \ - print(next((a['browser_download_url'] for a in r['assets'] \ - if a['name'].endswith('.AppImage')), ''))" 2>/dev/null) - if [[ -n "$_AZ_URL" ]]; then - local _AZ_FILE="$_AZAHAR_DIR/$(basename "$_AZ_URL")" - curl -fL --progress-bar -o "$_AZ_FILE" "$_AZ_URL" \ - && chmod +x "$_AZ_FILE" \ - && chown "$ACTUAL_USER:$ACTUAL_USER" "$_AZ_FILE" \ - && log_success "Azahar downloaded: $_AZ_FILE" \ - || log_warning "Download failed — get it manually from https://github.com/azahar-emu/azahar/releases" - else - log_warning "Could not resolve download URL — get it manually from https://github.com/azahar-emu/azahar/releases" - fi - fi - else - log_info "Azahar already present in $GAME_STORAGE_DIR/emulators/" + # ── Optional: download standalone emulator AppImages ───────────────────── + # AppImages dropped in emulators/ are found automatically by ES-DE's app + # finder (checks ~/Applications inside the container). These are the + # systems ES-DE hands off to a standalone frontend rather than a + # RetroArch libretro core (Dolphin's libretro core in particular is + # unstable for Wii — confirmed live: "could not write to/read from Wii + # system memory" errors go away once a real standalone Dolphin build is + # present instead). + local _EMU_DIR="$GAME_STORAGE_DIR/emulators" + _wolf_download_emulator_appimage \ + "Azahar (3DS — open-source Citra fork)" "azahar-emu/azahar" "azahar*.AppImage" "$_EMU_DIR" + _wolf_download_emulator_appimage \ + "PCSX2 (PS2)" "PCSX2/pcsx2" "pcsx2*.AppImage" "$_EMU_DIR" + + # Dolphin itself ships no official Linux AppImage — dolphin-emu.org's own + # Linux distribution is Flatpak-only. pkgforge-dev/Dolphin-emu-AppImage is + # a well-regarded THIRD-PARTY community build, not an official Dolphin + # release — flagged explicitly rather than silently offered as if it were + # one, so skip it and grab Dolphin's own Flatpak/build by hand instead if + # you'd rather not run an unofficial build. + if ! ls "$_EMU_DIR"/*[Dd]olphin*.AppImage 2>/dev/null | grep -q .; then + log_warning "Dolphin (GameCube/Wii) has no official Linux AppImage (dolphin-emu.org ships Flatpak only)." + log_warning "The option below is a well-regarded but THIRD-PARTY community build (pkgforge-dev), not" + log_warning "an official Dolphin release." fi + _wolf_download_emulator_appimage \ + "Dolphin (GameCube/Wii, community AppImage build)" "pkgforge-dev/Dolphin-emu-AppImage" "*[Dd]olphin*.AppImage" "$_EMU_DIR" # ── App selection ───────────────────────────────────────────────────────── echo "" @@ -3055,7 +3092,7 @@ Two things live on the game drive (\`$GAME_STORAGE_DIR\`): - \`retroarch/shaders/\` → ~/.config/retroarch/shaders (shaders/CRT filters — persist) - \`retroarch/overlays/\` → ~/.config/retroarch/overlays (bezels/overlays — persist) - \`saves/\` → /mnt/games/saves (RetroArch saves & states) -- \`emulators/\` → /mnt/games/emulators + ~/Applications (Azahar 3DS AppImage, etc.) +- \`emulators/\` → /mnt/games/emulators + ~/Applications (Azahar/PCSX2/Dolphin AppImages) **2. \`wolf-state/\`** — Wolf's entire state folder (\`WOLF_STATE_DIR\` in \`.env\`). This is the key to keeping games off the OS drive: it holds @@ -3096,14 +3133,25 @@ ES-DE is usable the moment you launch it; only ROMs and BIOS are yours to add. - **Exit a game** back to ES-DE: Start+Select opens the RetroArch menu → Quit, or use the Wolf hotkey START+UP+RB (Ctrl+Alt+Shift+W on a keyboard). -## 3DS emulation -Azahar (open-source Citra fork) AppImage lives in \`emulators/\` → mounted at -\`/mnt/games/emulators\` and \`~/Applications\` (where ES-DE's app finder looks). -Point ES-DE's 3DS system at it via Alternative Emulators if it isn't -auto-detected. Re-download with: -\`\`\`bash -cd $WOLF_DIR && ./manage.sh apps -\`\`\` +## Standalone emulators (3DS / PS2 / GameCube+Wii) +RetroArch's own libretro cores handle these systems poorly or not at all +(Dolphin's libretro core in particular is unstable for Wii), so ES-DE hands +them off to standalone AppImages instead: + +- **Azahar** (3DS, open-source Citra fork) — official releases +- **PCSX2** (PS2) — official releases +- **Dolphin** (GameCube/Wii) — Dolphin itself ships no official Linux + AppImage (dolphin-emu.org's own Linux distribution is Flatpak-only); this + uses a well-regarded but **third-party** community AppImage build + (pkgforge-dev) instead. Skip it and install Dolphin's own Flatpak by hand + if you'd rather not run an unofficial build. + +All three live in \`emulators/\` → mounted at \`/mnt/games/emulators\` and +\`~/Applications\` (where ES-DE's app finder looks). Point ES-DE's +3DS/PS2/GameCube/Wii systems at one via Alternative Emulators if it isn't +auto-detected. Missing ones get offered again on a fresh install +(\`sudo ./setup.sh wolf\`); to grab just one by hand, download its AppImage +into \`emulators/\`, \`chmod +x\` it. ## Troubleshooting: app exits immediately ("Permission denied") If a launcher (Steam, etc.) closes the moment it opens, its Wolf-managed home From f087984526c28ec5a1ad4386e737825bd0617c18 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 1 Sep 2026 02:24:29 +0000 Subject: [PATCH 2/3] Add AntiMicroX plumbing for a universal controller-combo hotkey MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wires up the infrastructure for RetroArch's own hotkeys (global across every libretro core already) to be matched by an equivalent for Dolphin/PCSX2/Azahar, none of which support gamepad-bound hotkeys natively (confirmed open feature requests: PCSX2/pcsx2#1082, azahar-emu/azahar#722; Dolphin's are hardcoded to keyboard only). AntiMicroX watches Wolf's virtual gamepad directly — a real uinput device per Wolf's own "inputtino" docs, not a proprietary channel — and injects whatever keyboard shortcut the focused emulator actually expects. Mechanism: GoW's own stock Sway config (baked into the esde/retroarch images) has a deliberate first-line extension point, `include /home/retro/.config/sway/custom-cfg` (confirmed by reading it directly out of a running container). Since /home/retro/.config is already the retro-home mount added earlier this session, writing a file to $GAME_STORAGE_DIR/retro-home/sway/custom-cfg on the host lands exactly there in both containers — zero changes to GoW's own image or scripts needed. Deliberately scoped to plumbing only: download AntiMicroX (reusing the _wolf_download_emulator_appimage helper added for PCSX2/Dolphin), add the Sway launch hook (floating window, not hidden, so it's reachable through the Moonlight stream), and document the actual one-time setup flow in the generated README. The button mapping itself, including AntiMicroX's own per-application Auto Profile switching, is built through its real GUI rather than a hand-authored .gamecontroller.amgp this repo can't verify blind. Marked experimental throughout (install prompt defaults to n, DRY-RUN summary, README) — this is unverified against a live session. --- services/wolf.sh | 101 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/services/wolf.sh b/services/wolf.sh index 5cf6aa4..5ebde07 100644 --- a/services/wolf.sh +++ b/services/wolf.sh @@ -278,6 +278,9 @@ EOF echo " - Create bios/ + retroarch/{cores,shaders,overlays}/ on the game drive and pre-download RetroArch cores (~1.5 GB)" echo " - Offer to auto-download standalone emulator AppImages into emulators/:" echo " Azahar (3DS), PCSX2 (PS2), Dolphin (GameCube/Wii — unofficial community build)" + echo " - Offer to set up AntiMicroX (universal controller-combo hotkey, experimental —" + echo " downloads it and wires a Sway launch hook; the button mapping itself is" + echo " built later through AntiMicroX's own GUI)" return 0 fi @@ -840,6 +843,72 @@ UDEV _wolf_download_emulator_appimage \ "Dolphin (GameCube/Wii, community AppImage build)" "pkgforge-dev/Dolphin-emu-AppImage" "*[Dd]olphin*.AppImage" "$_EMU_DIR" + # ── Optional: AntiMicroX for a universal controller-combo hotkey ───────── + # RetroArch's own hotkeys (Settings -> Input -> Input Hotkey Binds) are + # global across every libretro core, but Dolphin/PCSX2/Azahar each run as + # standalone apps ES-DE launches directly and none of the three support + # gamepad-bound hotkeys natively (confirmed open feature requests: + # PCSX2/pcsx2#1082, azahar-emu/azahar#722; Dolphin's hotkeys are + # hardcoded to keyboard only). AntiMicroX bridges this by watching the + # real controller device (Wolf's virtual gamepad is a genuine uinput + # device — see games-on-whales/wolf's own docs on "inputtino" — so this + # is a real input device AntiMicroX can open, not a proprietary channel) + # and injecting whatever keyboard shortcut each app actually expects. + # + # GoW's own stock Sway config (/cfg/sway/config, baked into the esde and + # retroarch images — same one both apps' `launcher()` call copies) has a + # deliberate extension point at its very first line: + # include /home/retro/.config/sway/custom-cfg + # Since /home/retro/.config is already our own retro-home mount (see the + # esde/retroarch CATALOG mounts above), just writing a file to + # $GAME_STORAGE_DIR/retro-home/sway/custom-cfg on the host lands exactly + # there in the container, for both apps, with zero changes to GoW's own + # image or scripts needed. + # + # This only wires up the plumbing (download AntiMicroX, launch it + # visibly as a floating window every session). The actual button + # mapping — including AntiMicroX's own per-application "Auto Profile" + # switching (Options -> Settings -> Auto Profile in its GUI) needed to + # send a different key to each emulator from the same physical combo — + # has to be built once through AntiMicroX's own GUI while it's running; + # hand-authoring its .gamecontroller.amgp profile XML blind isn't + # something to guess at. Whatever gets saved there persists automatically + # (same retro-home mount), so it's a one-time setup. + local _AMX_DIR="$GAME_STORAGE_DIR/retro-home/antimicrox" + local _SWAY_CFG_DIR="$GAME_STORAGE_DIR/retro-home/sway" + mkdir -p "$_AMX_DIR" "$_SWAY_CFG_DIR" + + echo "" + log_info "AntiMicroX lets you map one controller combo (e.g. Select+Start) to a" + log_info "different real keyboard shortcut per emulator — RetroArch's own hotkeys" + log_info "already cover every RetroArch-driven system; this is for Dolphin/PCSX2/" + log_info "Azahar, none of which support gamepad hotkeys natively. EXPERIMENTAL:" + log_info "the actual button mapping has to be built once through its own GUI." + local _GET_AMX="" + prompt_yn "Set up AntiMicroX for a universal controller hotkey? (y/n):" "n" _GET_AMX + if [[ "$_GET_AMX" =~ ^[Yy]$ ]]; then + _wolf_download_emulator_appimage \ + "AntiMicroX" "AntiMicroX/antimicrox" "antimicrox*.AppImage" "$_AMX_DIR" + local _AMX_APP + _AMX_APP=$(ls "$_AMX_DIR"/antimicrox*.AppImage 2>/dev/null | head -1) + if [[ -n "$_AMX_APP" ]]; then + backup_if_exists "$_SWAY_CFG_DIR/custom-cfg" + cat > "$_SWAY_CFG_DIR/custom-cfg" << CFGEOF +# Written by services/wolf.sh — AntiMicroX: universal controller-combo hotkey. +# Launched as a normal floating window (not hidden) so its own GUI is +# reachable through the Moonlight stream for one-time profile setup — +# see ~/docker/wolf/README.md for how to build the actual button mapping. +for_window [app_id="antimicrox"] floating enable, resize set 480 360, move position 20 20 +exec /home/retro/.config/antimicrox/$(basename "$_AMX_APP") --appimage-extract-and-run & +CFGEOF + chown -R 1000:1000 "$_AMX_DIR" "$_SWAY_CFG_DIR" 2>/dev/null || true + log_success "AntiMicroX will launch (as a small floating window) alongside ES-DE/RetroArch." + log_info "First session: open its window, map your combo, save — it persists from then on." + else + log_warning "AntiMicroX download didn't produce a usable AppImage — skipping the Sway launch hook." + fi + fi + # ── App selection ───────────────────────────────────────────────────────── echo "" echo "═══════════════════════════════════════════════════════" @@ -3153,6 +3222,38 @@ auto-detected. Missing ones get offered again on a fresh install (\`sudo ./setup.sh wolf\`); to grab just one by hand, download its AppImage into \`emulators/\`, \`chmod +x\` it. +## AntiMicroX — universal controller-combo hotkey (experimental) +RetroArch's own hotkeys (Settings -> Input -> Input Hotkey Binds) already +cover every RetroArch-driven system, but Dolphin/PCSX2/Azahar don't support +gamepad-bound hotkeys natively — AntiMicroX watches the controller directly +and injects whatever keyboard shortcut each app actually expects, so one +physical combo (e.g. hold Select, press Start) can mean "exit" — or save +state, or anything else — everywhere. + +If you said yes to the AntiMicroX prompt during install, it launches +automatically as a small floating window every time ES-DE or RetroArch +starts. **Building the actual mapping is a one-time step, done through its +own GUI, not something this installer can pre-configure:** + +1. Start ES-DE (or RetroArch) from Moonlight as normal — AntiMicroX's small + window appears floating in the corner alongside it. +2. In AntiMicroX: set up your controller under its device list, then create + a profile — click a button in its UI, press the real combo on your + gamepad, assign it the keyboard key the target emulator expects for that + action (see each emulator's own Settings -> Input/Hotkeys for its actual + bindings — Dolphin/PCSX2 defaults are commonly F1-F4-range keys). +3. For a **different translation per emulator** from the same physical + combo, use AntiMicroX's own **Options -> Settings -> Auto Profile** — + add a rule per application (matched by window class/title) so e.g. + Select+Start sends Esc when Dolphin has focus but F4 when RetroArch does. +4. Save. It's written under \`~/.config/antimicrox/\` inside the container, + which is the same \`retro-home/\` mount everything else here persists + through — it'll auto-load on every future session with no further setup. + +To change the mapping later, just reopen AntiMicroX the same way. To remove +it entirely, delete \`retro-home/sway/custom-cfg\` and \`retro-home/antimicrox/\` +on the host and re-run \`sudo ./setup.sh wolf\`. + ## Troubleshooting: app exits immediately ("Permission denied") If a launcher (Steam, etc.) closes the moment it opens, its Wolf-managed home dir has root-owned files the in-container user (uid 1000) can't write. Fix: From bef88e654d3b73ac49199848523ec65d6a3f8055 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 1 Sep 2026 02:32:45 +0000 Subject: [PATCH 3/3] Fix two bugs in the AntiMicroX plumbing before it ever runs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Glob case mismatch that would have silently no-op'd the whole feature: the real GitHub release asset is AntiMicroX-x86_64.AppImage (capitalized) — confirmed against the actual release, not assumed. Both the helper's own already-downloaded check and this file's own post-download lookup used a lowercase-only "antimicrox*.AppImage" glob (copied from Azahar's/PCSX2's pattern, which really are lowercase). Linux glob matching is case-sensitive, so _AMX_APP would have come back empty even after a successful download, hitting the "didn't produce a usable AppImage" branch and silently skipping the Sway launch hook with the AppImage sitting there unused. 2. Sway match criteria used app_id, which only matches native Wayland clients. AntiMicroX is a Qt5/X11 app running under XWayland here — same as ES-DE and Steam already are in this exact stock config, which is why their own for_window rules use [class="..."], not app_id. Switched to class (and title as a fallback, in case the exact WM_CLASS AntiMicroX registers differs), with a (?i) case- insensitive prefix — confirmed sway uses PCRE2 for criteria matching and (?i) is the documented syntax for exactly this, not assumed. Neither bug was fatal to Wolf itself (both fail quietly rather than crashing anything), but both would have cost real troubleshooting time for something that looked like it should just work. --- services/wolf.sh | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/services/wolf.sh b/services/wolf.sh index 5ebde07..5629dac 100644 --- a/services/wolf.sh +++ b/services/wolf.sh @@ -887,10 +887,15 @@ UDEV local _GET_AMX="" prompt_yn "Set up AntiMicroX for a universal controller hotkey? (y/n):" "n" _GET_AMX if [[ "$_GET_AMX" =~ ^[Yy]$ ]]; then + # Real release asset is "AntiMicroX-x86_64.AppImage" (capitalized) — + # confirmed against the actual GitHub release, not assumed. A plain + # lowercase glob (like Azahar's/PCSX2's, which really are lowercase) + # would silently never match this one, on both the helper's own + # already-downloaded check and the lookup below. _wolf_download_emulator_appimage \ - "AntiMicroX" "AntiMicroX/antimicrox" "antimicrox*.AppImage" "$_AMX_DIR" + "AntiMicroX" "AntiMicroX/antimicrox" "[Aa]nti[Mm]icro[Xx]*.AppImage" "$_AMX_DIR" local _AMX_APP - _AMX_APP=$(ls "$_AMX_DIR"/antimicrox*.AppImage 2>/dev/null | head -1) + _AMX_APP=$(ls "$_AMX_DIR"/[Aa]nti[Mm]icro[Xx]*.AppImage 2>/dev/null | head -1) if [[ -n "$_AMX_APP" ]]; then backup_if_exists "$_SWAY_CFG_DIR/custom-cfg" cat > "$_SWAY_CFG_DIR/custom-cfg" << CFGEOF @@ -898,7 +903,14 @@ UDEV # Launched as a normal floating window (not hidden) so its own GUI is # reachable through the Moonlight stream for one-time profile setup — # see ~/docker/wolf/README.md for how to build the actual button mapping. -for_window [app_id="antimicrox"] floating enable, resize set 480 360, move position 20 20 +# +# AntiMicroX is a Qt5/X11 app running under XWayland here, same as ES-DE and +# Steam in this same stock config (see their own [class="..."] rules above) — +# app_id only matches native Wayland clients and would never match this one. +# Matched on both class and title as a fallback in case the exact WM_CLASS +# AntiMicroX registers turns out to differ from what's assumed here. +for_window [class="(?i)antimicrox"] floating enable, resize set 480 360, move position 20 20 +for_window [title="(?i)antimicrox"] floating enable, resize set 480 360, move position 20 20 exec /home/retro/.config/antimicrox/$(basename "$_AMX_APP") --appimage-extract-and-run & CFGEOF chown -R 1000:1000 "$_AMX_DIR" "$_SWAY_CFG_DIR" 2>/dev/null || true