diff --git a/AppKit/CPApplication.j b/AppKit/CPApplication.j index f3783c75a..90d87c5c3 100644 --- a/AppKit/CPApplication.j +++ b/AppKit/CPApplication.j @@ -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]; } diff --git a/AppKit/CPWindow/CPWindow.j b/AppKit/CPWindow/CPWindow.j index f770fc642..baafd32a4 100644 --- a/AppKit/CPWindow/CPWindow.j +++ b/AppKit/CPWindow/CPWindow.j @@ -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]) { diff --git a/Tests/Manual/AttachedSheet2/SheetWindowController.j b/Tests/Manual/AttachedSheet2/SheetWindowController.j index 096beec68..41866b38f 100644 --- a/Tests/Manual/AttachedSheet2/SheetWindowController.j +++ b/Tests/Manual/AttachedSheet2/SheetWindowController.j @@ -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]; }