bug#81585: 31.0.91 and 32.0.50; Crash on macos hiding header-line with pixel-scroll-precision-mode
Alan Third <[email protected]>
| Newsgroups | gmane.emacs.bugs |
|---|---|
| Message-ID | <[email protected]> |
On Wed, Aug 12, 2026 at 11:24:46AM +0100, Alan Third wrote: > On Wed, Aug 12, 2026 at 12:58:46AM -0400, Corwin Kerr wrote: > > > Honestly, I don't know if redisplay should be sending negative values > > > to *_scroll_run, but just in case I've tried changing copyRect:to: so > > > it can handle negative values. > > The patch stops the crash for me as well. Thanks! > > > > The crash might be a symptom of another bug because some other > > scrolling weirdness occurs. > > > > In both Emacs 30.2 and the patched build with the same minimal.el: > > > file minimal.el > > > ;; -*- lexical-binding: t; -*- > > > (pixel-scroll-precision-mode) > > > (defun toggle-header () > > > (interactive) > > > (setq header-line-format > > > (unless header-line-format "Pixel scroll, then press C-t to crash"))) > > > (toggle-header) > > > (bind-key "C-t" #'toggle-header) > > > > 1. emacs -Q --load minimal.el > > 2. C-x 2 and click in lower buffer. > > 3. Scroll in lower buffer. > > Let x = fractional part of number of lines scrolled. > > 4. C-t to toggle off header-line. > > 5. The lower x fraction of header-line covers the lower x fraction of the > > mode-line of the upper buffer. > > (And in Emacs 32.0.50 if mode-line-invisible-mode is on, the bottom > > line of the buffer text is covered.) Does the attached fix it? -- Alan Third
v2-0001-Fix-crash-in-NS-scroll-code-bug-81585.patch
(text/plain, 2 KB)
From 0fb078de845a0ef9a3e7d6cd1616a6399d90d474 Mon Sep 17 00:00:00 2001 From: Alan Third <[email protected]> Date: Sun, 9 Aug 2026 19:22:57 +0100 Subject: [PATCH v2] Fix crash in NS scroll code (bug#81585) There may be a problem in the core redisplay code that it can send negative values to the *_scroll_run functions, but this fixes the problem at the actual scrolling code. * src/nsterm.m (ns_scroll_run) ([EmacsView copyRect:to:]): If the destination is negative, fix the source and destination to keep everything positive. --- src/nsterm.m | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/nsterm.m b/src/nsterm.m index 20967b7581f..f53eafd5841 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -2857,7 +2857,6 @@ Hide the window (X11 semantics) NSTRACE ("ns_scroll_run"); - /* begin copy from other terms */ /* Get frame-relative bounding box of the text display area of W, without mode lines. Include in this box the left and right fringe of W. */ @@ -2875,6 +2874,15 @@ Hide the window (X11 semantics) height = bottom_y - from_y; else height = run->height; + + /* If the destination is off the top of the current window, don't + draw over the window above. */ + if (to_y < y) { + int d = y - to_y; + height -= d; + to_y += d; + from_y += d; + } } else { @@ -2885,7 +2893,6 @@ Hide the window (X11 semantics) else height = run->height; } - /* end copy from other terms */ if (height == 0) return; @@ -9316,6 +9323,16 @@ - (void)copyRect:(NSRect)srcRect to:(NSPoint)dest NSTRACE_RECT ("Source", srcRect); NSTRACE_POINT ("Destination", dest); + /* If the destination is off the top of the pixel buffer, fix the + source and destination to copy only to y = 0. */ + if (dest.y < 0) + { + int d = dest.y; + dest.y = 0; + srcRect.origin.y -= d; + srcRect.size.height += d; + } + NSRect dstRect = NSMakeRect (dest.x, dest.y, NSWidth (srcRect), NSHeight (srcRect)); -- 2.55.0