bug#81510: 31.0.90; NS (macOS): clicking a disabled (:enable nil) tab-bar item crases Emacs
Stéphane Marks <[email protected]>
| Newsgroups | gmane.emacs.bugs |
|---|---|
| Message-ID | <CAN+1Hbpoj5+kqHubK-c19GGBN83YkKzsXdpcphdBS3wVQsdJrQ@mail.gmail.com> |
On Tue, Jul 28, 2026 at 11:31 AM Al Haji-Ali <[email protected]> wrote: > > Clicking a tab-bar menu-item that has an explicit `:enable nil' property > (i.e. a disabled item) crashes Emacs outright on the NS (macOS) port. > > Minimal recipe: > > emacs -Q -l repro.el > > where repro.el contains: > > (defun repro-tab-bar-format () > '((disabled-item menu-item "disabled item -- click me" ignore > :enable nil))) > (setq tab-bar-format '(repro-tab-bar-format)) > (tab-bar-mode 1) > > Then click on the "disabled item -- click me" text in the tab bar and > note the crash. > > Backtrace (macOS crash report, Thread 0): > > 0 libsystem_kernel.dylib __pthread_kill + 8 > 1 libsystem_pthread.dylib pthread_kill + 296 > 2 libsystem_c.dylib raise + 32 > 3 Emacs terminate_due_to_signal + 228 > 4 Emacs emacs_abort + 20 > 5 Emacs kbd_buffer_store_buffered_event + 652 > 6 Emacs ns_read_socket_1 + 112 > 7 Emacs gobble_input + 264 > ... > -[EmacsView mouseDown:] > > Root cause, as far as I can tell from reading src/xdisp.c, > src/keyboard.c and src/nsterm.m: > > 1. keyboard.c's parse_tab_bar_item defaults TAB_BAR_ITEM_ENABLED_P to t, > and an explicit `:enable FORM' property overrides it. > > 2. xdisp.c's handle_tab_bar_click returns nil on a disabled item, rather > than (Fcons (Qtab_bar, Qnil)) like a missed clicked. > > 3. nsterm.m's -[EmacsView mouseDown:] does: > > if (!(tab_bar_p && NILP (tab_bar_arg))) > emacs_event->kind = MOUSE_CLICK_EVENT; > ... > EV_TRAILER (theEvent); > > For a disabled item, emacs_event->kind is never assigned -- it's left > at its default, NO_EVENT. EV_TRAILER then calls > kbd_buffer_store_event_hold. > > 4. keyboard.c's kbd_buffer_store_buffered_event opens with: > > if (event->kind == NO_EVENT) > emacs_abort (); > > I have not tested on X11/w32, so I am not sure if they have the same > issue. > > Possible minimal fix: make handle_tab_bar_click's disabled-item > branch return (Fcons (Qtab_bar, Qnil)) instead of bare Qnil, matching > the "click missed" case, which nsterm.m (and presumably the other > ports) already handle correctly as a harmless plain click. I haven't > verified this doesn't have side effects for other callers of > handle_tab_bar_click across the X11/w32 ports. > > ------------------ > > In GNU Emacs 31.0.90 (build 1, aarch64-apple-darwin25.5.0, NS > appkit-2685.60 Version 26.5.1 (Build 25F80)) of 2026-07-12 built on > HW-R9XXWKPJ4D > Windowing system distributor 'Apple', version 10.3.2685 > System Description: macOS 26.5.2 > > Configured using: > 'configure --disable-dependency-tracking --disable-silent-rules > --enable-locallisppath=/opt/homebrew/share/emacs/site-lisp > --infodir=/opt/homebrew/Cellar/emacs-plus@31/31.0.90/share/info/emacs > --prefix=/opt/homebrew/Cellar/emacs-plus@31/31.0.90 > --with-native-compilation=aot --with-xml2 --with-gnutls > --without-compress-install 'CFLAGS=-DFD_SETSIZE=10000 > -DDARWIN_UNLIMITED_SELECT -I/opt/homebrew/opt/sqlite/include > -I/opt/homebrew/opt/gcc/include -I/opt/homebrew/opt/libgccjit/include' > --without-dbus --without-imagemagick --with-modules --with-rsvg > --with-webp --with-ns --disable-ns-self-contained > 'LDFLAGS=-L/opt/homebrew/opt/sqlite/lib -L/opt/homebrew/lib/gcc/16 > -Wl,-rpath,/opt/homebrew/lib/gcc/16'' > > Configured features: > ACL GIF GLIB GMP GNUTLS JPEG LCMS2 LIBXML2 MODULES NATIVE_COMP NOTIFY > KQUEUE NS PDUMPER PNG RSVG SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS > TREE_SITTER WEBP XIM ZLIB > > Important settings: > value of $LANG: en_GB.UTF-8 > locale-coding-system: utf-8-unix > > Major mode: Lisp Interaction > > Minor modes in effect: > tooltip-mode: t > global-eldoc-mode: t > eldoc-mode: t > show-paren-mode: t > electric-indent-mode: t > mouse-wheel-mode: t > tool-bar-mode: t > menu-bar-mode: t > file-name-shadow-mode: t > global-font-lock-mode: t > font-lock-mode: t > blink-cursor-mode: t > minibuffer-nonselected-mode: t > minibuffer-regexp-mode: t > line-number-mode: t > indent-tabs-mode: t > transient-mark-mode: t > auto-composition-mode: t > auto-encryption-mode: t > auto-compression-mode: t > > Load-path shadows: > None found. > > Features: > (shadow sort mail-extr comp-run bytecomp byte-compile comp-common rx > emacsbug lisp-mnt message mailcap yank-media puny dired dired-loaddefs > rfc822 mml mml-sec password-cache epa derived epg rfc6068 epg-config > gnus-util text-property-search time-date subr-x mm-decode mm-bodies > mm-encode mailabbrev gmm-utils mailheader cl-loaddefs cl-lib sendmail > mail-parse rfc2231 rfc2047 rfc2045 ietf-drums mm-util mail-prsvr > mail-utils rmc iso-transl tooltip cconv eldoc paren electric uniquify > ediff-hook vc-hooks lisp-float-type elisp-mode mwheel term/ns-win ns-win > ucs-normalize mule-util term/common-win tool-bar dnd fontset image > regexp-opt fringe tabulated-list replace newcomment text-mode lisp-mode > prog-mode register page tab-bar menu-bar rfn-eshadow isearch easymenu > timer select scroll-bar mouse jit-lock font-lock syntax font-core > term/tty-colors frame minibuffer nadvice seq simple cl-generic > indonesian philippine cham georgian utf-8-lang misc-lang vietnamese > tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek > romanian slovak czech european ethiopic indian cyrillic chinese > composite emoji-zwj charscript charprop case-table epa-hook > jka-cmpr-hook help abbrev obarray oclosure cl-preloaded button loaddefs > theme-loaddefs faces cus-face macroexp files window text-properties > overlay sha1 md5 base64 format env code-pages mule custom widget keymap > hashtable-print-readable backquote threads kqueue cocoa ns lcms2 > multi-tty make-network-process tty-child-frames native-compile emacs) > > Memory information: > ((conses 16 56258 9223) (symbols 48 6141 0) (strings 32 15274 1404) > (string-bytes 1 530642) (vectors 16 9719) > (vector-slots 8 134388 10017) (floats 8 22 2) (intervals 56 266 0) > (buffers 1064 10)) > + other people Good catch. At first glance, your proposal looks right. diff --git a/src/xdisp.c b/src/xdisp.c index 5377d5e8ada..81dcbb543be 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -15321,7 +15321,7 @@ handle_tab_bar_click (struct frame *f, int x, int y, bool down_p, /* If item is disabled, do nothing. */ enabled_p = AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_ENABLED_P); if (NILP (enabled_p)) - return Qnil; + return Fcons (Qtab_bar, Qnil); if (down_p) { Let's see what others think. -Stéphane