% Created 2026-02-23 Mon 15:25 % Intended LaTeX compiler: pdflatex \documentclass[a4paper,11pt]{report} \usepackage[utf8]{inputenc} \usepackage[T1]{fontenc} \usepackage{graphicx} \usepackage{longtable} \usepackage{wrapfig} \usepackage{rotating} \usepackage[normalem]{ulem} \usepackage{amsmath} \usepackage{amssymb} \usepackage{capt-of} \usepackage{hyperref} \usepackage{tabularx} \usepackage[czech, english]{babel} \usepackage[T1]{fontenc} \usepackage[utf8]{inputenc} \usepackage{microtype} \sloppy \usepackage{helvet} \renewcommand{\familydefault}{\sfdefault} \usepackage[a4paper,margin=2.2cm]{geometry} \usepackage[table,x11names]{xcolor} \definecolor{kyndrylRed}{RGB}{196,0,0} \definecolor{linkcolor}{RGB}{196,0,0} \definecolor{tableOdd}{RGB}{252,252,252} \definecolor{tableEven}{RGB}{237,237,237} \usepackage{hyperref} \hypersetup{colorlinks=true,linkcolor=linkcolor,urlcolor=linkcolor,citecolor=linkcolor} \usepackage{xurl} \usepackage{graphicx} \usepackage{array} \usepackage{tabularx} \usepackage{longtable} \usepackage{ltablex} \keepXColumns \usepackage{booktabs} \usepackage{colortbl} \usepackage{etoolbox} \usepackage{ragged2e} \AtBeginEnvironment{longtable}{\rowcolors{1}{tableOdd}{tableEven}} \AtBeginEnvironment{tabularx}{\rowcolors{1}{tableOdd}{tableEven}} \AtBeginEnvironment{tabular}{\rowcolors{1}{tableOdd}{tableEven}} \newcolumntype{Y}{>{\RaggedRight\arraybackslash}X} \newcolumntype{Z}{>{\Centering\arraybackslash}X} \newcolumntype{R}{>{\RaggedLeft\arraybackslash}X} \usepackage{fancyhdr} \pagestyle{fancy} \fancyhf{} \lhead{\small\nouppercase{\leftmark}} \rhead{\small\thepage} \renewcommand{\headrulewidth}{0.4pt} \renewcommand{\headrule}{\hbox to\headwidth{\color{kyndrylRed}\leaders\hrule height \headrulewidth\hfill}} \usepackage{listings} \lstset{backgroundcolor=\color{yellow!20},basicstyle=\ttfamily\small,breaklines=true,frame=single} \usepackage{titling} \renewcommand{\maketitle}{% \begin{titlepage}\centering\vspace*{\fill}% {\LARGE\bfseries\thetitle\par}\vspace{1em}% {\large\theauthor\par}\vspace{2em}% {\normalsize\itshape\thedate\par}\vspace{2em}% \includegraphics[width=0.30\textwidth]{~/org/templates/logo.png}\par% \vspace*{\fill}\end{titlepage}} \author{Martin Sukaný Martin Sukany} \date{2026-02-23 \today} \title{Emacs macOS Build — UAZoom Accessibility Patch} \hypersetup{ pdfauthor={Martin Sukaný Martin Sukany}, pdftitle={Emacs macOS Build — UAZoom Accessibility Patch}, pdfkeywords={}, pdfsubject={}, pdfcreator={Emacs 31.0.50 (Org mode 9.7.11)}, pdflang={English}} \usepackage{biblatex} \begin{document} \maketitle \setcounter{tocdepth}{2} \tableofcontents \part{Emacs macOS Build s macOS Zoom Accessibility} \label{sec:orgbc265a8} Návod na buildování GNU Emacs pro macOS s patchem pro \texttt{UAZoomChangeFocus}, který opravuje sledování kurzoru v macOS Zoom ``Follow keyboard focus''. \begin{center} \includegraphics[width=.9\linewidth]{./attachments/image-20260223-145400.png} \end{center} \chapter{Kontext} \label{sec:orgedb4055} macOS Zoom ``Follow keyboard focus'' ve vanilla GNU Emacs nefunguje. Root cause: Emacs nemá implementovanou NSAccessibility pro vlastní NSView a hlavně nevolá \texttt{UAZoomChangeFocus()} z \texttt{HIServices/UniversalAccess.h}. Patch je v repozitáři \href{https://git.apps.sukany.cz/martin/emacs-doom}{martin/emacs-doom} v \texttt{patches/0001-ns-implement-AXBoundsForRange-for-macOS-Zoom-cursor-.patch}. \chapter{Prerekvizity} \label{sec:org4f3757f} \begin{verbatim} # 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{verbatim} \chapter{Stažení zdrojů} \label{sec:org89bef97} \begin{verbatim} 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{verbatim} \chapter{Aplikace accessibility patche} \label{sec:orgc3ebf97} \begin{verbatim} # 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{verbatim} Patch implementuje: \begin{itemize} \item \texttt{UAZoomChangeFocus()} — přímé volání Zoom API po každém pohybu kurzoru \item \texttt{NSAccessibilitySelectedTextChangedNotification} — standardní AX notifikace \item \texttt{NSAccessibilityFocusedUIElementChangedNotification} — notifikace při focusu \item \texttt{accessibilityBoundsForRange:} — nová NSAccessibilityProtocol API \item \texttt{AXBoundsForRange} — starší fallback API \item \texttt{NSAccessibilityTextAreaRole} — správná role pro Emacs view \end{itemize} \chapter{Konfigurace a Build} \label{sec:orga135a39} \begin{verbatim} ./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{verbatim} \section{Volitelně: s native compilation (rychlejší Emacs)} \label{sec:orgc6ab781} \begin{verbatim} ./configure \ --with-ns \ --with-native-compilation=aot \ --with-tree-sitter \ --with-gnutls \ --with-xml2 \ --with-json \ --without-x \ CFLAGS="-O2 -g3" \end{verbatim} \chapter{Instalace} \label{sec:org41b25a4} \begin{verbatim} # 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{verbatim} \section{Proč wrapper script, ne symlink} \label{sec:orgaf28f28} Symlink (/usr/local/bin/emacs → \ldots{}/Emacs.app/Contents/MacOS/Emacs) nefunguje správně. Emacs počítá cesty k Lisp souborům z \texttt{argv[0]}, ne přes resolved symlink. Výsledkem jsou chyby: \begin{verbatim} 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{verbatim} Wrapper script předává správnou cestu. \chapter{macOS Accessibility nastavení} \label{sec:org8c7a25a} Po každém novém buildu (nový binary) je potřeba znovu udělit permission: \begin{enumerate} \item System Settings → Privacy \& Security → Accessibility \item Přidat nové \texttt{/Applications/Emacs.app} \item Zapnout toggle \end{enumerate} Bez tohoto kroku \texttt{UAZoomChangeFocus()} neovlivní Zoom viewport. \chapter{Doom Emacs sync} \label{sec:orgc761c2d} \begin{verbatim} # 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{verbatim} \chapter{Ověření Zoom funkcionality} \label{sec:org958f18c} \begin{enumerate} \item System Settings → Accessibility → Zoom → zapnout ``Use keyboard shortcut to zoom'' \item Zoom mode: Full Screen nebo Split Screen \item Advanced → Zoom follows: \texttt{Keyboard focus} \item Otevři Emacs, začni psát \item Zoom viewport by měl sledovat kurzor \end{enumerate} \chapter{Časté problémy} \label{sec:orge650202} \begin{center} \begin{tabularx}{\linewidth}{lYY} Problém & Příčina & Řešení\\ \hline 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: \texttt{grep UAZoomChangeFocus src/nsterm.m}\\ Build selže na nsterm.m & Chybí Xcode CLT nebo závislosti & \texttt{xcode-select -{}-{}install} + brew install\\ ``Contents/MacOS/libexec not found'' & Symlink místo wrapper scriptu & Nahradit wrapper scriptem\\ \end{tabularx} \end{center} \chapter{Reference} \label{sec:org4660c16} \begin{itemize} \item Patch repo: \href{https://git.apps.sukany.cz/martin/emacs-doom}{martin/emacs-doom} \item Ghostty issue (stejný problém): \url{https://github.com/nicowillis/Ghostty/issues/4053} \item iTerm2 implementace: \texttt{PTYTextView.m:refreshAccessibility} \item Chromium implementace: \texttt{render\_widget\_host\_view\_mac.mm:OnSelectionBoundsChanged} \end{itemize} \end{document}