MrNoodle / NoodleKit

Random collection of Cocoa classes and categories, most of which have been featured on my blog: http://www.noodlesoft.com/blog
http://www.noodlesoft.com/blog
388 stars 34 forks source link

NoodleLineNumberView and Lion #1

Open richard-koch opened 13 years ago

richard-koch commented 13 years ago

TeXShop uses NoodleLineNumberView. On Lion, line numbers do not scroll when text content scrolls using overlay scrollers. They do scroll with legacy scrollers. Strangely, line numbers scroll in full screen mode with overlay scrollers. Line numbers correctly appear when a window is opened, and correctly update when a window is resized.

Debugging shows that drawHashMarksAndLabelsInRect is called during scrolling, and tries to draw correct line numbers. It appears that the cliprect is incorrectly set in NSRulerView. Indeed, I can see a small sliver at the bottom of the line number rectangle, about two millimeters high, being correctly written.

This might be incorrect code in TeXShop, but the amount of code I had to add to get line numbers was minuscule. (Thanks for that!)

MrNoodle commented 13 years ago

I'll see if I can wrangle some time to take a look at this but the way you make it sound seems like a Lion bug. Are you able to replicate this using the sample app?

richard-koch commented 13 years ago

Mr Noodle,

Thanks for the magical line numbers. Lots of people thanked me and I just smiled and said "you're welcome." But if they look hard in the credits, they will see who is responsible.

The key to getting Apple's help with this issue is to construct a minimal example. I now have two examples. I packaged them together and you can get them via

http://pages.uoregon.edu/koch/LineNumberLion.zip

This will unzip into two folders, "Line View Test" and "Line View Test 1".

The first is the sample code on the Noodle site. I had to change the Noodle files in it to the latest 64 bit versions, and I had to change one or two XCode configure values. After that it compiles fine in XCode 4.1 on Lion. XCode still lists several warnings. But the significant thing is that SCROLLING LINE NUMBERS WITH AN OVERLAY SCROLLER WORKS.

The second file contains a default NSDocument project built with XCode 4.1. The only change is that I added a NoodleLineNumber view, trying to copy the code in "Line View Test" exactly. This time, I get the TeXShop behavior. Line numbers scroll with a legacy scroller, but not with a virtual scroller.

If you have time, you might glance through this example and see if anything pops out. If not, I'll write Apple, filing a bug report.

(If possible, I'll try to simplify things so a more or less default NSRuler class is used, with maybe just one override. But I thought it was time to write now.)

Dick Koch koch@math.uoregon.edu

On Jul 28, 2011, at 9:27 AM, MrNoodle wrote:

I'll see if I can wrangle some time to take a look at this but the way you make it sound seems like a Lion bug. Are you able to replicate this using the sample app?

Reply to this email directly or view it on GitHub: https://github.com/MrNoodle/NoodleKit/issues/1#issuecomment-1674069

richard-koch commented 13 years ago

Mr. Noodle,

I think I have the definitive example and intend to send a bug report to Apple.

My example is essentially "Line View Test 1" that I sent you earlier. However, instead of adding NoodleLineNumberView, I added my own NewRulerView. This class is a subclass of NSRulerView designed to be as simple as possible. It just colors the ruler scroll bar with two colors in an alternating way. This is enough to show that it works with legacy scrollers, but not with overlay scrollers.

I'm going to send Apple two examples, one with NoodleLineNumberView so they can see what the class actually does, and the other with NewRulerView so they can see that the complexities of NoodleLineNumberView are irrelevant.

To repeat a key discovery from my previous mail, this bug only exhibits itself in an NSDocument based application.


NewRulerView.h:

import <Cocoa/Cocoa.h>

@interface NewRulerView : NSRulerView { NSInteger value; }

@end


NewRulerView.m

import "NewRulerView.h"

@implementation NewRulerView

}

@end

Dick Koch

richard-koch commented 13 years ago

Mr. Noodle,

The zip file

http://pages.uoregon.edu/koch/LineNumberLion.zip

contains the three examples I sent to Apple and the text of the problem description. This is bug 9860102.

Dick Koch

mcastilho commented 13 years ago

Any solution for this bug ?

richard-koch commented 13 years ago

Marcio,

I believe the bug is fixed in the next release of OS X.

In addition, there is a workaround for the bug in TeXShop 3.04 and later, by a colleague of mine in Japan.

Unfortunately, I have a meeting shortly. But when I get back in four hours, I'll check the first assertion and then send you details about the workaround.

Here's the rough idea of the workaround:

a) Record the visibleRegion of text

b) If OS X asks to redraw the line numbers, check if this visibleRegion
has changed. If not, do the regular stuff. But if it changed, then 
move the scroll bar down a pixel and then back up a pixel record 
and then record the new visibleRegion.

When the window resizes, the line numbers correctly draw. That is the idea behind the patch. The "visibleRegion" piece is to insure that you don't get into an infinite redrawing loop.

This patch works well, but I'm looking forward to the day when it can be removed.

Dick Koch

On Sep 27, 2011, at 8:01 PM, Marcio Castilho wrote:

Any solution for this bug ?

Reply to this email directly or view it on GitHub: https://github.com/MrNoodle/NoodleKit/issues/1#issuecomment-2219142

richard-koch commented 13 years ago

Marcio,

Apologies for the delay.

On Sep 27, 2011, at 8:01 PM, Marcio Castilho wrote:

Any solution for this bug ?

Reply to this email directly or view it on GitHub: https://github.com/MrNoodle/NoodleKit/issues/1#issuecomment-2219142

I believe this will be fixed in system 10.7.2.

In the meantime, Yusuke Terada provided a workaround for the problem on TeXShop.

The idea of this patch is that when a NoodleLineNumberView is resized, the clip rect is correctly set and thus the line numbers redraw correctly. So we modify the NoodleLineNumberView drawing code to first check the visible rect. If the visible rect has changed, then a new range of line numbers needs to be drawn. So we resize the NoodleLineNumberView by a pixel and then reset it back and record the new visible rect. Then we draw as usual.

This resizing will trigger yet another drawing, but then the visible Rect won't change, so we don't get into an infinite loop.

Here is the patch in detail. TeXShop has a NoodleLineNumberView for each open document, and NSDocument is it's code to handle that document.

a) In the NSDocument header

NSRect lastDocumentVisibleRect;  // added by Terada (for Lion bug)

b) In the NSDocument code

// FIX RULER SCROL [lineNumberView setDocument:self]; // added by Terada (for Lion bug) // END FIX RULER SCROLL

// FIX RULER SCROLL

} // END FIX RULER SCROLL

c) In the NoodleLineNumberView header instance variables

// FIX RULER SCROLL

TSDocument *_document; // END FIX RULER SCROLL

d) In the NoodleLineNumberView header methods

// FIX RULER SCROLL

e) In the NoodleLineNumberView code

// FIX RULER SCROLL

f) In the NoodleLineNumberView code for drawHashMarksAndLabelsInRect

    bounds = [self bounds];
view = [self clientView];

// FIX RULER SCROLL if ([SUD boolForKey:FixLineNumberScrollKey]) [_document redrawLineNumbers:view]; // END FIX RULER SCROLL

if (_backgroundColor != nil)
{
    [_backgroundColor set];
                .