dml@esl.com (Denis Lynch) (03/08/91)
Recently several people have posted comp.sys.next articles about a bug in Text that I've observed for a long time. (I even reported it to bug_next). Since this was interfering with performance on a fairly important app I've been developing, I spent a little more time on it, and even found an appropriate workaround. (That is, one that's easy, avoids the problem, and doesn't cost anything.) So here's the problem: If you modify text (e.g. with setSelFontStyle:) while the Text's window's display is disabled, the Text still tries to highlight (or unhighlight?) the modified text. The visible result of this is highlighted splotches on whatever view happened to be the last one drawn in. That frequently turns out to be a menu, in which case the splotches are there for the rest of the application's life (unless you happen to do the same thing again and exactly reverse the unwanted highlighting). And here's the solution: 1) Before you do disableDisplay to do programmatic things to a Text, lock focus on the Text. 2) After you reenableDisplay, unlockFocus on the Text. 3) Ask the Text to display. If you want to affect scrolling, you can do a scrollSelToVisible while display is disabled. If you do that, or change the size of the text, remember to tell the ScrollView to reflectScroll:. And make sure you do that with display *enabled*. This seems to work in all the cases we've run into, and has all the speed advantages that accrue from batching changes with display disabled. I presume that if you're going to modify several Text's at once, you can just pick any one to lockFocus on. Even though the vicimized Text may get some errant highlights, you're going to completely redisplay it anyway. Here's a little sample of what this looks like: #import <appkit/Text.h> #import <appkit/Window.h> #import <appkit/ScrollView.h> - someMethod { /* scrollText is an IB-style scrolling text widget. */ /* locations is a zero-terminated list of start/end locations to bold. (Not a very good way to do this, but fine for the example. */ Text *t = [scrollText docView]; int *p = locations; [t lockFocus]; [[scrollText window] disableDisplay]; while (*p) { int start = *p++, end = *p++; [t setSel: start : end]; [t setSelFontStyle: NX_BOLD]; } [t scrollSelToVisible]; [[scrollText window] reenableDisplay]; [t unlockFocus]; [t display]; /* reflectScroll doesn't do anything if display is disabled! */ [scrollText reflectScroll: [t superview]]; return self; } This little bit works fine as shown, but causes menu splotches if the lockFocus and unlockFocus are removed. I hope this helps somebody! --Denis Lynch, ESL Inc.