Merge pull request #3120 from daboe01/nil-in-cpviewcontroller-fix

fixed: subview's window setting did not happen BEFORE _setSuperview
This commit is contained in:
daboe01 authored and GitHub committed 2025-07-17 19:27:36 +02:00
commit c2d07b7b06
2 files changed
+39 -7

No files matched your search

+7 -6
View File
@@ -602,7 +602,8 @@ var CPViewHighDPIDrawingEnabled = YES;
// We will have to adjust the z-index of all views starting at this index.
var count = _subviews.length,
lastWindow;
lastWindow,
isNewAddOrMove = aSubview._superview !== self;
// Dirty the key view loop, in case the window wants to auto recalculate it
[[self window] _dirtyKeyViewLoop];
@@ -673,6 +674,9 @@ var CPViewHighDPIDrawingEnabled = YES;
if (!_window && lastWindow)
[aSubview _setWindow:nil];
if (isNewAddOrMove)
[aSubview _postViewDidAppearNotification];
// This method might be called before we are fully unarchived, in which case the theme state isn't set up yet
// and none of the below matters anyhow.
if (_themeState)
@@ -735,6 +739,7 @@ var CPViewHighDPIDrawingEnabled = YES;
// If the view is not hidden and one of its ancestors is hidden,
// notify the view that it is now unhidden.
[self _setSuperview:nil];
[self _postViewDidDisappearNotification];
[self _notifyWindowDidResignKey];
[self _notifyViewDidResignFirstResponder];
@@ -1719,11 +1724,7 @@ var CPViewHighDPIDrawingEnabled = YES;
_superview = aSuperview;
if (hasOldSuperview)
[self _postViewDidDisappearNotification];
if (hasNewSuperview)
[self _postViewDidAppearNotification];
// Notifications are now posted manually from _insertSubview and _removeFromSuperview
}
- (void)_recursiveLostHiddenAncestor
+32 -1
View File
@@ -9,7 +9,20 @@ var updateTrackingAreasCalls,
cursorUpdateCalls,
involvedViewForMouseEntered,
involvedViewForMouseExited,
involvedViewForCursorUpdate;
involvedViewForCursorUpdate,
windowPropertyWasNilInViewDidAppear;
@implementation CPTestableViewController : CPViewController
{
}
- (void)viewDidAppear
{
[super viewDidAppear];
windowPropertyWasNilInViewDidAppear = ([self view] && [[self view] window] === nil);
}
@end
@implementation CPViewTest : OJTestCase
{
@@ -39,6 +52,7 @@ var updateTrackingAreasCalls,
methodCalled = [];
updateTrackingAreasCalls = 0;
windowPropertyWasNilInViewDidAppear = NO;
[super setUp];
}
@@ -1661,6 +1675,23 @@ var updateTrackingAreasCalls,
[[CPApplication sharedApplication] sendEvent:anEvent];
}
- (void)testWindowIsSetBeforeViewDidAppear
{
// 1. Create a view controller. This will also create its view.
var viewController = [[CPTestableViewController alloc] init];
var controllerView = [viewController view];
// 2. Add the controller's view to the window's view hierarchy.
// This will trigger the chain of notifications, including _CPViewDidAppearNotification,
// which in turn calls -[CPViewController viewDidAppear].
[[window contentView] addSubview:controllerView];
// 3. Check the flag set by our custom view controller.
// If the fix is correct, the window should have been set before viewDidAppear was called,
// so the flag should be NO.
[self assertFalse:windowPropertyWasNilInViewDidAppear message:@"The view's window property should be set before -[CPViewController viewDidAppear] is called."];
}
@end
@implementation CPTrackingAreaView : CPView