Fix tracking rect bug

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@23711 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2006-10-02 12:07:35 +00:00
parent 154961d6a3
commit f51a1085b8
4 changed files with 85 additions and 30 deletions

View file

@ -1,3 +1,12 @@
2006-10-01 Richard Frith-Macdonald <rfm@gnu.org>
* Source/GSTrackingRect.m:
* Source/NSView.m:
* Headers/AppKit/NSView.h:
Fix tracking rect bug ... the owner of the rectangle should not
be retained by a tracking rect (but should be retained by a cursor
rect). Updated documentation to clearly state what mis retained.
2006-10-01 Richard Frith-Macdonald <rfm@gnu.org> 2006-10-01 Richard Frith-Macdonald <rfm@gnu.org>
* Source/GSTheme.m: Add rudimentary inspector. * Source/GSTheme.m: Add rudimentary inspector.

View file

@ -328,14 +328,41 @@ typedef enum _NSFocusRingType {
event: (NSEvent *)theEvent; event: (NSEvent *)theEvent;
#endif #endif
/* /**
* Managing the Cursor * Adds a cursor rectangle. This provides for automatic update of the
* cursor to be anObject while the mouse is in aRect.<br />
* The cursor (anObject) is retained until the cursor rectangle is
* removed or discarded.<br />
* Generally your subviews should call this in their implementation of
* the -resetCursorRects method.<br />
* It is your responsibility to ensure that aRect lies within your veiw's
* visible rectangle.
*/ */
- (void) addCursorRect: (NSRect)aRect - (void) addCursorRect: (NSRect)aRect
cursor: (NSCursor*)anObject; cursor: (NSCursor*)anObject;
/**
* Removes all the cursor rectancles which have been set up for the
* receiver. This is equivalent to calling -removeCursorRect:cursor:
* for all cursor rectangles which have been set up.<br />
* This is called automatically before the system calls -resetCursorRects
* so you never need to call it.
*/
- (void) discardCursorRects; - (void) discardCursorRects;
/**
* Removes the cursor rectangle which was set up for the specified
* rectangle and cursor.
*/
- (void) removeCursorRect: (NSRect)aRect - (void) removeCursorRect: (NSRect)aRect
cursor: (NSCursor*)anObject; cursor: (NSCursor*)anObject;
/** <subclass-override />
* This is called to establish a new set of cursor rectangles whenever
* the receiver needs to do so (eg the view has been resized). The default
* implementation does nothing, but subclasses should use it to make
* calls to -addCursorRect:cursor: to establish their new cursor rectangles.
*/
- (void) resetCursorRects; - (void) resetCursorRects;
#ifndef STRICT_OPENSTEP #ifndef STRICT_OPENSTEP
@ -351,10 +378,26 @@ typedef enum _NSFocusRingType {
- (NSString *) toolTip; - (NSString *) toolTip;
#endif #endif
/* /**
* Tracking rectangles * Removes a tracking rectangle which was previously established using the
* -addTrackingRect:owner:userData:assumeInside: method.<br />
* The value of tag must be the value returned by the method used to add
* the rectangle.
*/ */
- (void) removeTrackingRect: (NSTrackingRectTag)tag; - (void) removeTrackingRect: (NSTrackingRectTag)tag;
/**
* Adds a tracking rectangle to monitor mouse movement and generate
* mouse-entered and mouse-exited events.<br />
* The event messages are sent to anObject, which is <em>not</em>
* retained and must therefore be sure to remove any tracking rectangles
* using it before it is deallocated.<br />
* The value of data is supplied as the user data in the event objects
* generated.<br />
* If flag is YES then the mouse is assumed to be inside the tracking
* rectangle and the first event generated will therefore be a mouse exit,
* if it is NO then the first event generated will be a mouse entry.
*/
- (NSTrackingRectTag) addTrackingRect: (NSRect)aRect - (NSTrackingRectTag) addTrackingRect: (NSRect)aRect
owner: (id)anObject owner: (id)anObject
userData: (void*)data userData: (void*)data

View file

@ -51,10 +51,6 @@
rectangle = aRect; rectangle = aRect;
tag = aTag; tag = aTag;
owner = anObject; owner = anObject;
if (owner != nil)
{
RETAIN(owner);
}
user_data = theData; user_data = theData;
flags.inside = flag; flags.inside = flag;
flags.isValid = YES; flags.isValid = YES;
@ -63,7 +59,6 @@
- (void) dealloc - (void) dealloc
{ {
TEST_RELEASE(owner);
[super dealloc]; [super dealloc];
} }
@ -103,10 +98,6 @@
{ {
flags.isValid = NO; flags.isValid = NO;
flags.checked = NO; flags.checked = NO;
if (owner != nil)
{
DESTROY(owner);
}
} }
} }
@ -134,7 +125,7 @@
rectangle = [aDecoder decodeRect]; rectangle = [aDecoder decodeRect];
[aDecoder decodeValueOfObjCType: @encode(NSTrackingRectTag) at: &tag]; [aDecoder decodeValueOfObjCType: @encode(NSTrackingRectTag) at: &tag];
[aDecoder decodeValueOfObjCType: @encode(id) at: &owner]; owner = [aDecoder decodeObject];
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &inside]; [aDecoder decodeValueOfObjCType: @encode(BOOL) at: &inside];
flags.inside = inside; flags.inside = inside;
} }

View file

@ -557,6 +557,10 @@ GSSetDragTypes(NSView* obj, NSArray *types)
RELEASE(_boundsMatrix); RELEASE(_boundsMatrix);
TEST_RELEASE(_sub_views); TEST_RELEASE(_sub_views);
TEST_RELEASE(_tracking_rects); TEST_RELEASE(_tracking_rects);
if (_rFlags.has_currects != 0)
{
[self discardCursorRects]; // Handle release of cursors
}
TEST_RELEASE(_cursor_rects); TEST_RELEASE(_cursor_rects);
[self unregisterDraggedTypes]; [self unregisterDraggedTypes];
[self releaseGState]; [self releaseGState];
@ -2610,7 +2614,7 @@ Returns YES iff any scrolling was done.
m = [rectClass allocWithZone: NSDefaultMallocZone()]; m = [rectClass allocWithZone: NSDefaultMallocZone()];
m = [m initWithRect: aRect m = [m initWithRect: aRect
tag: 0 tag: 0
owner: anObject owner: RETAIN(anObject)
userData: NULL userData: NULL
inside: YES]; inside: YES];
[_cursor_rects addObject: m]; [_cursor_rects addObject: m];
@ -2624,17 +2628,18 @@ Returns YES iff any scrolling was done.
{ {
if (_rFlags.has_currects != 0) if (_rFlags.has_currects != 0)
{ {
if (_rFlags.valid_rects != 0) unsigned count = [_cursor_rects count];
{
unsigned count = [_cursor_rects count]; if (count > 0)
if (count > 0) {
GSTrackingRect *rects[count];
[_cursor_rects getObjects: rects];
if (_rFlags.valid_rects != 0)
{ {
GSTrackingRect *rects[count];
NSPoint loc = ((struct NSWindow_struct *)_window)->_lastPoint; NSPoint loc = ((struct NSWindow_struct *)_window)->_lastPoint;
unsigned i; unsigned i;
[_cursor_rects getObjects: rects];
for (i = 0; i < count; ++i) for (i = 0; i < count; ++i)
{ {
GSTrackingRect *r = rects[i]; GSTrackingRect *r = rects[i];
@ -2644,10 +2649,14 @@ Returns YES iff any scrolling was done.
} }
[r invalidate]; [r invalidate];
} }
_rFlags.valid_rects = 0;
} }
_rFlags.valid_rects = 0; while (count-- > 0)
{
RELEASE([rects[count] owner]);
}
[_cursor_rects removeAllObjects];
} }
[_cursor_rects removeAllObjects];
_rFlags.has_currects = 0; _rFlags.has_currects = 0;
} }
} }
@ -2677,6 +2686,7 @@ Returns YES iff any scrolling was done.
_rFlags.has_currects = 0; _rFlags.has_currects = 0;
_rFlags.valid_rects = 0; _rFlags.valid_rects = 0;
} }
RELEASE(c);
break; break;
} }
else else
@ -4091,13 +4101,15 @@ static NSView* findByTag(NSView *view, int aTag, unsigned *level)
_rFlags.flipped_view = [self isFlipped]; _rFlags.flipped_view = [self isFlipped];
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &_is_rotated_from_base];
[aDecoder decodeValueOfObjCType: @encode(BOOL) [aDecoder decodeValueOfObjCType: @encode(BOOL)
at: &_is_rotated_or_scaled_from_base]; at: &_is_rotated_from_base];
[aDecoder decodeValueOfObjCType: @encode(BOOL)
at: &_is_rotated_or_scaled_from_base];
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &_post_frame_changes]; [aDecoder decodeValueOfObjCType: @encode(BOOL) at: &_post_frame_changes];
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &_autoresizes_subviews]; [aDecoder decodeValueOfObjCType: @encode(BOOL)
at: &_autoresizes_subviews];
[aDecoder decodeValueOfObjCType: @encode(unsigned int) [aDecoder decodeValueOfObjCType: @encode(unsigned int)
at: &_autoresizingMask]; at: &_autoresizingMask];
[self setNextKeyView: [aDecoder decodeObject]]; [self setNextKeyView: [aDecoder decodeObject]];
[[aDecoder decodeObject] setNextKeyView: self]; [[aDecoder decodeObject] setNextKeyView: self];
@ -4109,9 +4121,9 @@ static NSView* findByTag(NSView *view, int aTag, unsigned *level)
while ((sub = [e nextObject]) != nil) while ((sub = [e nextObject]) != nil)
{ {
NSAssert([sub window] == nil, NSAssert([sub window] == nil,
NSInternalInconsistencyException); NSInternalInconsistencyException);
NSAssert([sub superview] == nil, NSAssert([sub superview] == nil,
NSInternalInconsistencyException); NSInternalInconsistencyException);
[sub viewWillMoveToWindow: _window]; [sub viewWillMoveToWindow: _window];
[sub viewWillMoveToSuperview: self]; [sub viewWillMoveToSuperview: self];
[sub setNextResponder: self]; [sub setNextResponder: self];