Fixed: unable to chain sheet in a window

Previously when chaining sheet on the same window, Cappuccino crashed.
Now chaining a sheet in the delegate method of the method endSheet: will open the next sheet.

Now when opening a sheet, we check if another sheet is currently closing. If yes, we wait till we get the notification of the closing of the previous sheet. And then we open the next sheet.

Fixed #2159

Test app in Tests/Manual/AttachedSheet2/SheetWindowController.j
This commit is contained in:
Alexandre Wilhelm
2014-10-29 15:04:55 -07:00
parent 90345addce
commit ba20936c17
3 changed files with 51 additions and 13 deletions
+3 -1
View File
@@ -986,7 +986,9 @@ var CPMainCibFile = @"CPMainCibFile",
return;
}
[aSheet._windowView _enableSheet:YES inWindow:aWindow];
if (![aWindow attachedSheet])
[aSheet._windowView _enableSheet:YES inWindow:aWindow];
[aWindow _attachSheet:aSheet modalDelegate:aModalDelegate didEndSelector:didEndSelector contextInfo:contextInfo];
}
+40 -9
View File
@@ -2679,6 +2679,23 @@ CPTexturedBackgroundWindowMask
[attachedSheet setFrame:sheetFrame display:YES animate:NO];
}
- (void)_previousSheetIsClosedNotification:(CPNotification)aNotification
{
[[CPNotificationCenter defaultCenter] removeObserver:self name:CPWindowDidEndSheetNotification object:self];
var sheet = _sheetContext[@"nextSheet"],
modalDelegate =_sheetContext[@"nextModalDelegate"],
endSelector = _sheetContext[@"nextEndSelector"],
contextInfo = _sheetContext[@"nextContextInfo"];
// Needed, becauwe when the notification CPWindowDidEndSheetNotification is sent, the sheetContext is not up to date...
setTimeout(function()
{
[sheet._windowView _enableSheet:YES inWindow:self];
[self _attachSheet:sheet modalDelegate:modalDelegate didEndSelector:endSelector contextInfo:contextInfo];
}, 0)
}
/*
Starting point for sheet session, called from CPApplication beginSheet:
*/
@@ -2687,9 +2704,24 @@ CPTexturedBackgroundWindowMask
{
if (_sheetContext)
{
[CPException raise:CPInternalInconsistencyException
reason:@"The target window of beginSheet: already has a sheet, did you forget orderOut: ?"];
return;
// Here we wait till the current sheet is closed
if (_sheetContext[@"isClosing"])
{
// Here we save the next sheet to open
_sheetContext[@"nextSheet"] = aSheet;
_sheetContext[@"nextModalDelegate"] = aModalDelegate;
_sheetContext[@"nextEndSelector"] = didEndSelector;
_sheetContext[@"nextContextInfo"] = contextInfo;
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_previousSheetIsClosedNotification:) name:CPWindowDidEndSheetNotification object:self];
return;
}
else
{
[CPException raise:CPInternalInconsistencyException
reason:@"The target window of beginSheet: already has a sheet, did you forget orderOut: ?"];
return;
}
}
_sheetContext = {
@@ -2741,7 +2773,12 @@ CPTexturedBackgroundWindowMask
*/
- (void)_detachSheetWindow
{
if (_sheetContext["isClosing"])
return;
_sheetContext["isAttached"] = NO;
_sheetContext["isClosing"] = YES;
_sheetContext["opened"] = NO;
// A timer seems to be necessary for the animation to work correctly.
// It would be ideal to block here and spin the event loop, until attach is complete.
@@ -2874,12 +2911,6 @@ CPTexturedBackgroundWindowMask
return;
}
if (_sheetContext["isClosing"])
return;
_sheetContext["opened"] = NO;
_sheetContext["isClosing"] = YES;
// The parent window can be orderedOut to disable the sheet animate out, as in Cocoa
if ([self isVisible])
{
@@ -399,9 +399,6 @@
_returnCode = 77;
[CPApp endSheet:[self window] returnCode:_returnCode];
if (orderOutAfter)
[[self window] orderOut:nil];
}
//
@@ -519,7 +516,15 @@
// test sheet chaining. it should be possible to start another sheet from didEndSheet,
// but only if we orderOut: the sheet before we called endSheet: This is how cocoa works too.
if (returnCode == 77)
{
var orderOutAfter = [_orderOutAfterCheckbox state];
if (orderOutAfter)
[[self window] orderOut:self];
[self runSheetForWindow:parentWindow];
}
//[self runAlertSheet:parentWindow];
}