Optimisation of handling of mouse movement.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@4221 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
richard 1999-05-07 11:06:37 +00:00
parent 01d09ad926
commit 2a22d6ee9f
4 changed files with 191 additions and 111 deletions

View file

@ -1,3 +1,12 @@
Fri May 7 12:16:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* Headers/AppKit/GSTrackingRect.h: Add a couple of ivars and make
them public.
* Source/GSTrackingRect.m: Set ivars to say what methods the owner
responds to.
* Source/NSWindow.m: Rewrite of ([-_checkTrackingRectangles:forEvent])
and ([-_checkCursorRectangles:forEvent:])
1999-05-05 Adam Fedor <fedor@gnu.org> 1999-05-05 Adam Fedor <fedor@gnu.org>
* Headers/gnustep/gui/NSGraphicsContext.h: New lock focus methods * Headers/gnustep/gui/NSGraphicsContext.h: New lock focus methods

View file

@ -33,13 +33,15 @@
@interface GSTrackingRect : NSObject <NSCoding> @interface GSTrackingRect : NSObject <NSCoding>
{ {
// Attributes @public
NSRect rectangle; NSRect rectangle;
NSTrackingRectTag tag; NSTrackingRectTag tag;
id owner; id owner;
void *user_data; void *user_data;
BOOL inside; BOOL inside;
BOOL isValid; BOOL isValid;
BOOL ownerRespondsToMouseEntered;
BOOL ownerRespondsToMouseExited;
} }
// Instance methods // Instance methods
@ -51,7 +53,7 @@
- (NSRect) rectangle; - (NSRect) rectangle;
- (NSTrackingRectTag) tag; - (NSTrackingRectTag) tag;
- owner; - (id) owner;
- (void*) userData; - (void*) userData;
- (BOOL) inside; - (BOOL) inside;
@ -61,8 +63,8 @@
// //
// NSCoding protocol // NSCoding protocol
// //
- (void) encodeWithCoder: aCoder; - (void) encodeWithCoder: (NSCoder*)aCoder;
- initWithCoder: aDecoder; - (id) initWithCoder: (NSCoder*)aDecoder;
@end @end

View file

@ -58,7 +58,13 @@
tag = aTag; tag = aTag;
owner = anObject; owner = anObject;
if (owner) if (owner)
[owner retain]; {
[owner retain];
if ([owner respondsToSelector: @selector(mouseEntered:)])
ownerRespondsToMouseEntered = YES;
if ([owner respondsToSelector: @selector(mouseExited:)])
ownerRespondsToMouseExited = YES;
}
user_data = theData; user_data = theData;
inside = flag; inside = flag;
isValid = YES; isValid = YES;
@ -111,6 +117,8 @@
{ {
[owner release]; [owner release];
owner = nil; owner = nil;
ownerRespondsToMouseEntered = NO;
ownerRespondsToMouseExited = NO;
} }
} }
} }

View file

@ -34,6 +34,7 @@
#include <Foundation/NSString.h> #include <Foundation/NSString.h>
#include <Foundation/NSCoder.h> #include <Foundation/NSCoder.h>
#include <Foundation/NSArray.h> #include <Foundation/NSArray.h>
#include <Foundation/NSGeometry.h>
#include <Foundation/NSNotification.h> #include <Foundation/NSNotification.h>
#include <Foundation/NSValue.h> #include <Foundation/NSValue.h>
#include <Foundation/NSException.h> #include <Foundation/NSException.h>
@ -87,6 +88,14 @@
@implementation NSWindow @implementation NSWindow
/*
* Class variables
*/
static SEL ccSel = @selector(_checkCusrorRectangles:forEvent:);
static SEL ctSel = @selector(_checkTrackingRectangles:forEvent:);
static IMP ccImp;
static IMP ctImp;
// //
// Class methods // Class methods
// //
@ -96,6 +105,8 @@
{ {
NSDebugLog(@"Initialize NSWindow class\n"); NSDebugLog(@"Initialize NSWindow class\n");
[self setVersion: 2]; [self setVersion: 2];
ccImp = [self instanceMethodForSelector: ccSel];
ctImp = [self instanceMethodForSelector: ctSel];
} }
} }
@ -1058,130 +1069,180 @@
accepts_mouse_moved = flag; accepts_mouse_moved = flag;
} }
- (void) checkTrackingRectangles: (NSView *)theView - (void) _checkTrackingRectangles: (NSView *)theView
forEvent: (NSEvent *)theEvent forEvent: (NSEvent *)theEvent
{ {
NSArray *tr = [theView trackingRectangles]; NSArray *tr = [theView trackingRectangles];
NSArray *sb = [theView subviews]; NSArray *sb = [theView subviews];
GSTrackingRect *r; unsigned count;
unsigned i, j;
BOOL last, now;
NSEvent *e;
j = [tr count]; // Loop through the tracking /*
for (i = 0; i < j; ++i) // rectangles * Loop through the tracking rectangles
*/
count = [tr count];
if (count > 0)
{ {
r = (GSTrackingRect *)[tr objectAtIndex: i]; GSTrackingRect *rects[count];
// Check mouse at last point NSPoint loc = [theEvent locationInWindow];
last = [theView mouse: last_point inRect: [r rectangle]]; BOOL flipped = [theView isFlipped];
// Check mouse at current point unsigned i;
now = [theView mouse: [theEvent locationInWindow] inRect: [r rectangle]];
if ((!last) && (now)) // Mouse entered event [tr getObjects: rects];
for (i = 0; i < count; ++i)
{ {
id owner = [r owner]; BOOL last;
BOOL now;
GSTrackingRect *r = rects[i];
if ([owner respondsToSelector: @selector(mouseEntered:)]) /* Check mouse at last point */
last = NSMouseInRect(last_point, r->rectangle, flipped);
/* Check mouse at current point */
now = NSMouseInRect(loc, r->rectangle, flipped);
if ((!last) && (now)) // Mouse entered event
{ {
e = [NSEvent enterExitEventWithType: NSMouseEntered if (r->ownerRespondsToMouseEntered)
location: [theEvent locationInWindow] {
modifierFlags: [theEvent modifierFlags] NSEvent *e;
timestamp: 0
windowNumber: [theEvent windowNumber] e = [NSEvent enterExitEventWithType: NSMouseEntered
context: NULL location: loc
eventNumber: 0 modifierFlags: [theEvent modifierFlags]
trackingNumber: [r tag] timestamp: 0
userData: [r userData]]; windowNumber: [theEvent windowNumber]
[owner mouseEntered: e]; context: NULL
eventNumber: 0
trackingNumber: r->tag
userData: r->user_data];
[r->owner mouseEntered: e];
}
} }
}
if ((last) && (!now)) // Mouse exited event if ((last) && (!now)) // Mouse exited event
{
id owner = [r owner];
if ([owner respondsToSelector: @selector(mouseExited:)])
{ {
e = [NSEvent enterExitEventWithType: NSMouseExited if (r->ownerRespondsToMouseExited)
location: [theEvent locationInWindow] {
modifierFlags: [theEvent modifierFlags] NSEvent *e;
timestamp: 0
windowNumber: [theEvent windowNumber] e = [NSEvent enterExitEventWithType: NSMouseExited
context: NULL location: loc
eventNumber: 0 modifierFlags: [theEvent modifierFlags]
trackingNumber: [r tag] timestamp: 0
userData: [r userData]]; windowNumber: [theEvent windowNumber]
[owner mouseExited: e]; context: NULL
eventNumber: 0
trackingNumber: r->tag
userData: r->user_data];
[r->owner mouseExited: e];
}
} }
} }
} }
j = [sb count]; // Check tracking rectangles /*
for (i = 0; i < j; ++i) // for the subviews * Check tracking rectangles for the subviews
[self checkTrackingRectangles: [sb objectAtIndex: i] forEvent: theEvent]; */
count = [sb count];
if (count > 0)
{
NSView *subs[count];
unsigned i;
[sb getObjects: subs];
for (i = 0; i < count; ++i)
(*ctImp)(self, ctSel, subs[i], theEvent);
}
} }
- (void) checkCursorRectangles: (NSView *)theView forEvent: (NSEvent *)theEvent - (void) _checkCursorRectangles: (NSView *)theView forEvent: (NSEvent *)theEvent
{ {
NSArray *tr = [theView cursorRectangles]; NSArray *tr = [theView cursorRectangles];
NSArray *sb = [theView subviews]; NSArray *sb = [theView subviews];
GSTrackingRect *r; unsigned count;
unsigned i, j;
BOOL last, now;
NSEvent *e;
NSPoint loc = [theEvent locationInWindow];
NSPoint lastPointConverted;
NSPoint locationConverted;
NSRect rect;
// Loop through cursor rectangles // Loop through cursor rectangles
j = [tr count]; count = [tr count];
for (i = 0; i < j; ++i) if (count > 0)
{ {
r = (GSTrackingRect *)[tr objectAtIndex: i]; GSTrackingRect *rects[count];
NSPoint loc = [theEvent locationInWindow];
NSPoint lastConv;
NSPoint locConv;
BOOL flipped = [theView isFlipped];
unsigned i;
if ([r isValid] == NO) /*
continue; * Convert points from window to view coordinates.
lastPointConverted = [theView convertPoint: last_point fromView: nil]; */
locationConverted = [theView convertPoint: loc fromView: nil]; lastConv = [theView convertPoint: last_point fromView: nil];
locConv = [theView convertPoint: loc fromView: nil];
rect = [r rectangle]; // Check mouse's last point [tr getObjects: rects];
last = [theView mouse: lastPointConverted inRect: rect];
now = [theView mouse: locationConverted inRect: rect]; for (i = 0; i < count; ++i)
// Mouse entered
if ((!last) && (now))
{ {
e = [NSEvent enterExitEventWithType: NSCursorUpdate GSTrackingRect *r = rects[i];
location: loc BOOL last;
modifierFlags: [theEvent modifierFlags] BOOL now;
timestamp: 0
windowNumber: [theEvent windowNumber] if ([r isValid] == NO)
context: [theEvent context] continue;
eventNumber: 0
trackingNumber: (int)YES /*
userData: (void *)r]; * Check for presence of point in rectangle.
[self postEvent: e atStart: YES]; */
} last = NSMouseInRect(lastConv, r->rectangle, flipped);
// Mouse exited now = NSMouseInRect(locConv, r->rectangle, flipped);
if ((last) && (!now))
{ // Mouse entered
e = [NSEvent enterExitEventWithType: NSCursorUpdate if ((!last) && (now))
location: loc {
modifierFlags: [theEvent modifierFlags] NSEvent *e;
timestamp: 0
windowNumber: [theEvent windowNumber] e = [NSEvent enterExitEventWithType: NSCursorUpdate
context: [theEvent context] location: loc
eventNumber: 0 modifierFlags: [theEvent modifierFlags]
trackingNumber: (int)NO timestamp: 0
userData: (void *)r]; windowNumber: [theEvent windowNumber]
[self postEvent: e atStart: YES]; context: [theEvent context]
eventNumber: 0
trackingNumber: (int)YES
userData: (void *)r];
[self postEvent: e atStart: YES];
}
// Mouse exited
if ((last) && (!now))
{
NSEvent *e;
e = [NSEvent enterExitEventWithType: NSCursorUpdate
location: loc
modifierFlags: [theEvent modifierFlags]
timestamp: 0
windowNumber: [theEvent windowNumber]
context: [theEvent context]
eventNumber: 0
trackingNumber: (int)NO
userData: (void *)r];
[self postEvent: e atStart: YES];
}
} }
} }
// Check cursor rectangles for the subviews /*
j = [sb count]; * Check cursor rectangles for the subviews
for (i = 0; i < j; ++i) */
[self checkCursorRectangles: [sb objectAtIndex: i] forEvent: theEvent]; count = [sb count];
if (count > 0)
{
NSView *subs[count];
unsigned i;
[sb getObjects: subs];
for (i = 0; i < count; ++i)
(*ccImp)(self, ccSel, subs[i], theEvent);
}
} }
- (void) sendEvent: (NSEvent *)theEvent - (void) sendEvent: (NSEvent *)theEvent
@ -1256,14 +1317,14 @@
// We need to go through all of the views, and if there is any with // We need to go through all of the views, and if there is any with
// a tracking rectangle then we need to determine if we should send // a tracking rectangle then we need to determine if we should send
// a NSMouseEntered or NSMouseExited event. // a NSMouseEntered or NSMouseExited event.
[self checkTrackingRectangles: content_view forEvent: theEvent]; (*ctImp)(self, ctSel, content_view, theEvent);
if (is_key) if (is_key)
{ {
// We need to go through all of the views, and if there is any with // We need to go through all of the views, and if there is any with
// a cursor rectangle then we need to determine if we should send a // a cursor rectangle then we need to determine if we should send a
// cursor update event. // cursor update event.
[self checkCursorRectangles: content_view forEvent: theEvent]; (*ccImp)(self, ccSel, content_view, theEvent);
} }
last_point = [theEvent locationInWindow]; last_point = [theEvent locationInWindow];