Calaf
Calaf

Reputation: 10817

Emacs Scrolling Bug on OS X

Update

This problem disappeared after upgrading from Mountain Lion to Mavericks, while also updating Emacs from 23.4 to 24.3.

End-update

With a .emacs file containing

(set-foreground-color "white")
(set-background-color "black")

(setq mouse-wheel-scroll-amount '(1 ((shift) . 1) ((control) . nil)))
(setq mouse-wheel-progressive-speed nil)

as I scroll up or down with the reduced step, I see the strange patterns

vertical lines

Magnifying one of the patterns reveals

magnified one vertical line

This problem has been present in Emacs 22, 23, and now 24 for several versions of OSX—up to and including Mountain Lion. Is it a known rendering bug? Is there a fix?

Neither the suggestion to modify fringes nor linum works for me. Where else can I look?

If I use the default white background and black foreground, these lines either do not appear or are imperceptible (to me).

What is most pesky about this problem is that redrawing (C-l) does not result in clean text.

Upvotes: 4

Views: 870

Answers (1)

Calaf
Calaf

Reputation: 10817

The problem is related to the interaction between OS X's LCD Font Smoothing algorithm and the algorithm that emacs uses to implement scrolling.

The figure below shows font smoothing turned off (left) and on (right). You will find this setting in System Preferences \ general. In both cases I scrolled the program by one line. When OS X draws the "@" with font smoothing turned on, it does not only use the pixels dedicated to the "@" but also uses the blue pixels of the adjacent (blank) character.

When emacs scrolls, it only modifies the characters that it believes need to be modified. If the character is blank and will remain blank after scrolling, it does not modify it. This optimization remains valid in 2013. In other words, testing that two characters are blank is still cheaper than drawing one character. But this optimization is hardly necessary today, and it results in the buggy display.

If the hypothesis above holds, the sequel question becomes whether one can turn off the optimization. Is it possible to ask emacs to redraw the full screen at each scroll or to at least redraw characters that remain blank if they were adjacent to a non-blank character.

Font smoothing off (left) and on (right)

One could of course simply turn off font smoothing. The magnified image may even suggest that the non-smoothed image is better. In practice, when the fonts appear in their natural (unmagnified) size, smoothing makes the characters far more legible, eliminating the need to use larger fonts.

The pattern on either side of "c();" in the image below is consistent with the bug. OS X uses blue pixels on the left side and red/tan pixels on the right (possibly this is related to the RGB pattern on the display). The vertical lines left over when scrolling are either blue or red/tan/brick, depending on whether they have dropped out of the left or right side of scrolled characters.

blue hints on the left; red hints on the right

Update

The problem is now solved in this nightly. The magnified c(); produced by Emacs 24.3.50.1 shows that the font smoothing remains identical to that produced by Emacs 24.3.1. But the output is not identical. There is at least one extra horizontal line of pixels between each two lines of text.

Upvotes: 1

Related Questions