Rewrite autodisplay handling.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@19725 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
alexm 2004-07-12 23:19:14 +00:00
parent 6644d14a43
commit 0df41169fd
2 changed files with 97 additions and 33 deletions

View file

@ -1,3 +1,13 @@
2004-07-13 01:15 Alexander Malmberg <alexander@malmberg.org>
* Source/NSWindow.m (+_handleAutodisplay:, +_addAutodisplayedWindow:,
+_removeAutodisplayedWindow:): New methods.
Rename _handleWindowNeedsDisplay: to -_handleAutodisplay.
([NSWindow +initialize]): Don't initialize modes.
(-dealloc, -orderWindow:relativeTo:): Use +_addAutodisplayedWindow:
and +_removeAutodisplayedWindow: instead of adding/removing a runloop
performer.
2004-07-13 00:23 Alexander Malmberg <alexander@malmberg.org> 2004-07-13 00:23 Alexander Malmberg <alexander@malmberg.org>
* Source/NSSound.m: Only declare the_server if HAVE_AUDIOFILE_H * Source/NSSound.m: Only declare the_server if HAVE_AUDIOFILE_H

View file

@ -79,7 +79,6 @@ static id<GSWindowDecorator> windowDecorator;
BOOL GSViewAcceptsDrag(NSView *v, id<NSDraggingInfo> dragInfo); BOOL GSViewAcceptsDrag(NSView *v, id<NSDraggingInfo> dragInfo);
static NSArray *modes = nil;
@interface NSObject (DragInfoBackend) @interface NSObject (DragInfoBackend)
- (void) dragImage: (NSImage*)anImage - (void) dragImage: (NSImage*)anImage
@ -97,7 +96,9 @@ static NSArray *modes = nil;
* or with other AppKit classes in the case of the _windowView method) * or with other AppKit classes in the case of the _windowView method)
*/ */
@interface NSWindow (GNUstepPrivate) @interface NSWindow (GNUstepPrivate)
- (void) _handleWindowNeedsDisplay: (id)bogus; +(void) _addAutodisplayedWindow: (NSWindow *)w;
+(void) _removeAutodisplayedWindow: (NSWindow *)w;
- (void) _lossOfKeyOrMainWindow; - (void) _lossOfKeyOrMainWindow;
- (NSView *) _windowView; - (NSView *) _windowView;
// Method used to support validation in the toolbar implementation // Method used to support validation in the toolbar implementation
@ -105,11 +106,38 @@ static NSArray *modes = nil;
@implementation NSWindow (GNUstepPrivate) @implementation NSWindow (GNUstepPrivate)
/* Window autodisplay machinery. */
- (void) _handleAutodisplay
{
if (_f.is_autodisplay && _rFlags.needs_display)
{
[self disableFlushWindow];
[self displayIfNeeded];
[self enableFlushWindow];
[self flushWindowIfNeeded];
}
}
static NSArray *modes = nil;
#define GSI_ARRAY_TYPES 0
#define GSI_ARRAY_TYPE NSWindow *
#define GSI_ARRAY_NO_RELEASE 1
#define GSI_ARRAY_NO_RETAIN 1
#ifdef GSIArray
#undef GSIArray
#endif
#include <GNUstepBase/GSIArray.h>
/* Array of windows we might need to handle autodisplay for (in practice
a list of windows that are, wrt. -gui, on-screen). */
static GSIArray_t autodisplayedWindows;
/* /*
This method handles all normal displaying. It is set to be run on each This method handles all normal displaying. It is set to be run on each
runloop iteration for each window that's on-screen. The performer is runloop iteration when the first window is created
added when the window is ordered in and re-added each time it is run.
If the window is ordered out, the performer is cancelled.
The reason why this performer is always added, as opposed to adding it The reason why this performer is always added, as opposed to adding it
when display is needed and not re-adding it here, is that when display is needed and not re-adding it here, is that
@ -120,23 +148,64 @@ events. If the performer were added in a call to another performer, it
wouldn't be called until the next runloop iteration, ie. after the runloop wouldn't be called until the next runloop iteration, ie. after the runloop
has blocked and waited for events. has blocked and waited for events.
*/ */
- (void) _handleWindowNeedsDisplay: (id)bogus +(void) _handleAutodisplay: (id)bogus
{ {
if (_f.is_autodisplay && _rFlags.needs_display) int i;
{ for (i = 0; i < GSIArrayCount(&autodisplayedWindows); i++)
[self disableFlushWindow]; [GSIArrayItemAtIndex(&autodisplayedWindows, i).ext _handleAutodisplay];
[self displayIfNeeded];
[self enableFlushWindow];
[self flushWindowIfNeeded];
}
[[NSRunLoop currentRunLoop] [[NSRunLoop currentRunLoop]
performSelector: @selector(_handleWindowNeedsDisplay:) performSelector: @selector(_handleAutodisplay:)
target: self target: self
argument: nil argument: nil
order: 600000 order: 600000
modes: modes]; modes: modes];
} }
+(void) _addAutodisplayedWindow: (NSWindow *)w
{
int i;
/* If it's the first time we're called, set up the performer and modes
array. */
if (!modes)
{
modes = [[NSArray alloc] initWithObjects: NSDefaultRunLoopMode,
NSModalPanelRunLoopMode,
NSEventTrackingRunLoopMode, nil];
[[NSRunLoop currentRunLoop]
performSelector: @selector(_handleAutodisplay:)
target: self
argument: nil
order: 600000
modes: modes];
GSIArrayInitWithZoneAndCapacity(&autodisplayedWindows,
NSDefaultMallocZone(), 1);
}
/* O(n), but it's much more important that _handleAutodisplay: can iterate
quickly over the array. (_handleAutodisplay: is called once for every
event, this method is only called when windows are ordered in or out.) */
for (i = 0; i < GSIArrayCount(&autodisplayedWindows); i++)
if (GSIArrayItemAtIndex(&autodisplayedWindows, i).ext == w)
return;
GSIArrayAddItem(&autodisplayedWindows, (GSIArrayItem)w);
}
+(void) _removeAutodisplayedWindow: (NSWindow *)w
{
int i;
for (i = 0; i < GSIArrayCount(&autodisplayedWindows); i++)
if (GSIArrayItemAtIndex(&autodisplayedWindows, i).ext == w)
{
GSIArrayRemoveItemAtIndex(&autodisplayedWindows, i);
return;
}
/* This happens eg. if a window is ordered out twice. In such cases,
the window has already been removed from the list, so we don't need
to do anything here. */
}
/* We get here if we were ordered out or miniaturized. In this case if /* We get here if we were ordered out or miniaturized. In this case if
we were the key or main window, go through the list of all windows we were the key or main window, go through the list of all windows
and try to find another window that can take our place as key and try to find another window that can take our place as key
@ -485,9 +554,6 @@ static NSNotificationCenter *nc = nil;
viewClass = [NSView class]; viewClass = [NSView class];
autosaveNames = [NSMutableSet new]; autosaveNames = [NSMutableSet new];
nc = [NSNotificationCenter defaultCenter]; nc = [NSNotificationCenter defaultCenter];
modes = [[NSArray alloc] initWithObjects: NSDefaultRunLoopMode,
NSModalPanelRunLoopMode,
NSEventTrackingRunLoopMode, nil];
} }
} }
@ -589,10 +655,7 @@ many times.
- (void) dealloc - (void) dealloc
{ {
[nc removeObserver: self]; [nc removeObserver: self];
[[NSRunLoop currentRunLoop] [isa _removeAutodisplayedWindow: self];
cancelPerformSelector: @selector(_handleWindowNeedsDisplay:)
target: self
argument: nil];
[NSApp removeWindowsItem: self]; [NSApp removeWindowsItem: self];
[NSApp _windowWillDealloc: self]; [NSApp _windowWillDealloc: self];
@ -1394,10 +1457,7 @@ many times.
/* /*
* Don't keep trying to update the window while it is ordered out * Don't keep trying to update the window while it is ordered out
*/ */
[[NSRunLoop currentRunLoop] [isa _removeAutodisplayedWindow: self];
cancelPerformSelector: @selector(_handleWindowNeedsDisplay:)
target: self
argument: nil];
[self _lossOfKeyOrMainWindow]; [self _lossOfKeyOrMainWindow];
} }
else else
@ -1449,12 +1509,7 @@ many times.
* Once we are ordered back in, we will want to update the window * Once we are ordered back in, we will want to update the window
* whenever there is anything to do. * whenever there is anything to do.
*/ */
[[NSRunLoop currentRunLoop] [isa _addAutodisplayedWindow: self];
performSelector: @selector(_handleWindowNeedsDisplay:)
target: self
argument: nil
order: 600000
modes: modes];
if (_f.has_closed == YES) if (_f.has_closed == YES)
{ {
@ -2289,8 +2344,7 @@ resetCursorRectsForView(NSView *theView)
/* /*
* We must order the miniwindow in so that we will start sending * We must order the miniwindow in so that we will start sending
* it -_handleWindowNeedsDisplay: messages to tell it to display * it messages to tell it to display itsself when neccessary.
* itsself when neccessary.
*/ */
if (_counterpart != 0) if (_counterpart != 0)
{ {