From ded3482067c1ece8f888963181f4fe0658b40bf4 Mon Sep 17 00:00:00 2001 From: Daneel Date: Mon, 23 Feb 2026 10:44:39 +0100 Subject: [PATCH] docs: emacs macOS build guide with UAZoom accessibility patch --- notes/emacs-macos-build.org | 177 ++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 notes/emacs-macos-build.org diff --git a/notes/emacs-macos-build.org b/notes/emacs-macos-build.org new file mode 100644 index 0000000..2366824 --- /dev/null +++ b/notes/emacs-macos-build.org @@ -0,0 +1,177 @@ +#+TITLE: Emacs macOS Build — UAZoom Accessibility Patch +#+AUTHOR: Martin Sukaný +#+DATE: 2026-02-23 +#+STARTUP: overview + +* Emacs macOS Build s macOS Zoom Accessibility + +Návod na buildování GNU Emacs pro macOS s patchem pro =UAZoomChangeFocus=, +který opravuje sledování kurzoru v macOS Zoom "Follow keyboard focus". + +** Kontext + +macOS Zoom "Follow keyboard focus" ve vanilla GNU Emacs nefunguje. Root cause: +Emacs nemá implementovanou NSAccessibility pro vlastní NSView a hlavně +nevolá =UAZoomChangeFocus()= z =HIServices/UniversalAccess.h=. + +Patch je v repozitáři [[https://git.apps.sukany.cz/martin/emacs-doom][martin/emacs-doom]] +v =patches/0001-ns-implement-AXBoundsForRange-for-macOS-Zoom-cursor-.patch=. + +** Prerekvizity + +#+begin_src sh +# Xcode Command Line Tools +xcode-select --install + +# Homebrew závislosti +brew install autoconf libgmp texinfo pkg-config gnutls libxml2 \ + jansson tree-sitter librsvg imagemagick + +# Volitelné ale doporučené +brew install libgccjit # native compilation +#+end_src + +** Stažení zdrojů + +#+begin_src sh +git clone https://github.com/emacs-mirror/emacs.git +cd emacs + +# Doporučená stable větev (aktuálně emacs-30) +git checkout emacs-30 +#+end_src + +** Aplikace accessibility patche + +#+begin_src sh +# Stáhni patch z martin/emacs-doom +git clone https://git.apps.sukany.cz/martin/emacs-doom.git /tmp/emacs-doom-config + +# Aplikuj patch +git am /tmp/emacs-doom-config/patches/0001-ns-implement-AXBoundsForRange-for-macOS-Zoom-cursor-.patch + +# Ověř aplikaci +grep "UAZoomChangeFocus" src/nsterm.m | head -3 +#+end_src + +Patch implementuje: +- =UAZoomChangeFocus()= — přímé volání Zoom API po každém pohybu kurzoru +- =NSAccessibilitySelectedTextChangedNotification= — standardní AX notifikace +- =NSAccessibilityFocusedUIElementChangedNotification= — notifikace při focusu +- =accessibilityBoundsForRange:= — nová NSAccessibilityProtocol API +- =AXBoundsForRange= — starší fallback API +- =NSAccessibilityTextAreaRole= — správná role pro Emacs view + +** Konfigurace a Build + +#+begin_src sh +./autogen.sh + +./configure \ + --with-ns \ + --with-tree-sitter \ + --with-gnutls \ + --with-xml2 \ + --with-json \ + --with-imagemagick \ + --with-rsvg \ + --with-mailutils \ + --without-x \ + --without-dbus \ + CFLAGS="-O2 -g3" + +# Build — -j počet CPU jader +make -j$(sysctl -n hw.ncpu) + +# Vytvoří nextstep/Emacs.app +make install +#+end_src + +*** Volitelně: s native compilation (rychlejší Emacs) + +#+begin_src sh +./configure \ + --with-ns \ + --with-native-compilation=aot \ + --with-tree-sitter \ + --with-gnutls \ + --with-xml2 \ + --with-json \ + --without-x \ + CFLAGS="-O2 -g3" +#+end_src + +** Instalace + +#+begin_src sh +# Přesuň Emacs.app do /Applications +cp -r nextstep/Emacs.app /Applications/Emacs.app + +# Vytvoř wrapper script (NE symlink — Emacs nenajde data přes symlink) +sudo tee /usr/local/bin/emacs << 'EOF' +#!/bin/sh +exec /Applications/Emacs.app/Contents/MacOS/Emacs "$@" +EOF +sudo chmod +x /usr/local/bin/emacs + +# Ověření +emacs --version +#+end_src + +*** Proč wrapper script, ne symlink + +Symlink (/usr/local/bin/emacs → .../Emacs.app/Contents/MacOS/Emacs) nefunguje +správně. Emacs počítá cesty k Lisp souborům z =argv[0]=, ne přes resolved symlink. +Výsledkem jsou chyby: +#+begin_example +Warning: arch-dependent data dir 'Contents/MacOS/libexec/': No such file or directory +Warning: Lisp directory 'Contents/Resources/lisp': No such file or directory +#+end_example + +Wrapper script předává správnou cestu. + +** macOS Accessibility nastavení + +Po každém novém buildu (nový binary) je potřeba znovu udělit permission: + +1. System Settings → Privacy & Security → Accessibility +2. Přidat nové =/Applications/Emacs.app= +3. Zapnout toggle + +Bez tohoto kroku =UAZoomChangeFocus()= neovlivní Zoom viewport. + +** Doom Emacs sync + +#+begin_src sh +# Po instalaci +~/.emacs.d/bin/doom sync + +# Pokud doom hledá emacs v jiné cestě +which emacs # musí vrátit /usr/local/bin/emacs +emacs --version +#+end_src + +** Ověření Zoom funkcionality + +1. System Settings → Accessibility → Zoom → zapnout "Use keyboard shortcut to zoom" +2. Zoom mode: Full Screen nebo Split Screen +3. Advanced → Zoom follows: =Keyboard focus= +4. Otevři Emacs, začni psát +5. Zoom viewport by měl sledovat kurzor + +** Časté problémy + +| Problém | Příčina | Řešení | +|---|---|---| +| doom sync: "emacs not found" | Wrapper script chybí nebo není v PATH | Viz sekce Instalace | +| Zoom nesleduje kurzor | Accessibility permission chybí | Přidat Emacs.app znovu do Privacy & Security | +| Zoom nesleduje kurzor | Patch nebyl aplikován | Ověřit: =grep UAZoomChangeFocus src/nsterm.m= | +| Build selže na nsterm.m | Chybí Xcode CLT nebo závislosti | =xcode-select --install= + brew install | +| "Contents/MacOS/libexec not found" | Symlink místo wrapper scriptu | Nahradit wrapper scriptem | + +** Reference + +- Patch repo: [[https://git.apps.sukany.cz/martin/emacs-doom][martin/emacs-doom]] +- Ghostty issue (stejný problém): https://github.com/nicowillis/Ghostty/issues/4053 +- iTerm2 implementace: =PTYTextView.m:refreshAccessibility= +- Chromium implementace: =render_widget_host_view_mac.mm:OnSelectionBoundsChanged=