Fix to stop runModalSession: from blocking.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@17990 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
CaS 2003-10-28 11:33:04 +00:00
parent c5fd555cd5
commit e8275452b1
2 changed files with 44 additions and 36 deletions

View file

@ -6,6 +6,12 @@
(-getEventMatchingMask:beforeDate:inMode:dequeue:) fix incorrect (-getEventMatchingMask:beforeDate:inMode:dequeue:) fix incorrect
termination ... should terminate when limit date has passed, termination ... should terminate when limit date has passed,
irrespective of the state of any input sources. irrespective of the state of any input sources.
* Source/NSApplication.m: ([-runModalForWindow:]) wait for new events
between calls to ([-runModalSession:])
([-runModalSession:]) rewritten to handle multiple events, but only
those events which are available ... ie don't wait for more.
Requires latest base library from CVS to get modified/corrected
runloop behavior.
2003-10-26 15:18 Alexander Malmberg <alexander@malmberg.org> 2003-10-26 15:18 Alexander Malmberg <alexander@malmberg.org>
Matt Rice <ratmice@yahoo.com> Matt Rice <ratmice@yahoo.com>

View file

@ -1194,11 +1194,28 @@ static NSCell* tileCell = nil;
NS_DURING NS_DURING
{ {
NSDate *limit;
GSDisplayServer *srv;
theSession = [self beginModalSessionForWindow: theWindow]; theSession = [self beginModalSessionForWindow: theWindow];
limit = [NSDate distantFuture];
srv = GSCurrentServer();
while (code == NSRunContinuesResponse) while (code == NSRunContinuesResponse)
{ {
/*
* Try to handle events for this session, discarding others.
*/
code = [self runModalSession: theSession]; code = [self runModalSession: theSession];
if (code == NSRunContinuesResponse)
{
/*
* Wait until there are more events to handle.
*/
DPSPeekEvent(srv, NSAnyEventMask, limit, NSDefaultRunLoopMode);
}
} }
[self endModalSession: theSession]; [self endModalSession: theSession];
} }
NS_HANDLER NS_HANDLER
@ -1223,12 +1240,14 @@ static NSCell* tileCell = nil;
/** /**
<p> <p>
Processes one event for a modal session described by the theSession Processes any events for a modal session described by the theSession
variable. Before processing the event, it makes the session window key variable. Before processing the events, it makes the session window key
and orders the window front, so there is no need to do this and orders the window front, so there is no need to do this
separately. When finished, it returns the state of the session (i.e. separately. When finished, it returns the state of the session (i.e.
whether it is still running or has been stopped, etc) whether it is still running or has been stopped, etc)
</p> </p>
<p>If there are no pending events for the session, this method returns
immediately.
<p> <p>
See Also: -runModalForWindow: See Also: -runModalForWindow:
</p> </p>
@ -1237,7 +1256,7 @@ See Also: -runModalForWindow:
{ {
NSAutoreleasePool *pool; NSAutoreleasePool *pool;
GSDisplayServer *srv; GSDisplayServer *srv;
BOOL found = NO; BOOL done = NO;
NSEvent *event; NSEvent *event;
NSDate *limit; NSDate *limit;
@ -1259,42 +1278,18 @@ See Also: -runModalForWindow:
[theSession->window makeMainWindow]; [theSession->window makeMainWindow];
} }
RELEASE (pool);
// Use the default context for all events. // Use the default context for all events.
srv = GSCurrentServer(); srv = GSCurrentServer();
/* // Only handle input which is already available.
* Set a limit date in the distant future so we wait until we get an limit = [NSDate distantPast];
* event. We discard events that are not for this window. When we
* find one for this window, we push it back at the start of the queue.
*/
limit = [NSDate distantFuture];
do
{
event = DPSGetEvent(srv, NSAnyEventMask, limit, NSDefaultRunLoopMode);
if (event != nil)
{
NSWindow *eventWindow = [event window];
if (eventWindow == theSession->window || [eventWindow worksWhenModal])
{
DPSPostEvent(srv, event, YES);
found = YES;
}
else if ([event type] == NSAppKitDefined)
{
/* Handle resize and other window manager events now */
[self sendEvent: event];
}
}
}
while (found == NO && theSession->runState == NSRunContinuesResponse);
RELEASE (pool);
/* /*
* Deal with the events in the queue. * Deal with the events in the queue.
*/ */
while (done == NO && theSession->runState == NSRunContinuesResponse)
while (found == YES && theSession->runState == NSRunContinuesResponse)
{ {
IF_NO_GC(pool = [arpClass new]); IF_NO_GC(pool = [arpClass new]);
@ -1303,21 +1298,28 @@ See Also: -runModalForWindow:
{ {
NSWindow *eventWindow = [event window]; NSWindow *eventWindow = [event window];
if (eventWindow == theSession->window || [eventWindow worksWhenModal]) /*
* We handle events for the session window, events for any
* window which works when modal, and any window management
* events. All others are ignored/discarded.
*/
if (eventWindow == theSession->window
|| [eventWindow worksWhenModal] == YES
|| [event type] == NSAppKitDefined)
{ {
ASSIGN(_current_event, event); ASSIGN(_current_event, event);
} }
else else
{ {
found = NO; event = nil; // Ignore/discard this event.
} }
} }
else else
{ {
found = NO; done = YES; // No more events pending.
} }
if (found == YES) if (event != nil)
{ {
NSEventType type = [_current_event type]; NSEventType type = [_current_event type];