diff --git a/AppKit/CPWindow/CPWindow.j b/AppKit/CPWindow/CPWindow.j index c1f8a677e..48ee6c6b8 100644 --- a/AppKit/CPWindow/CPWindow.j +++ b/AppKit/CPWindow/CPWindow.j @@ -2453,6 +2453,22 @@ CPTexturedBackgroundWindowMask return _parentWindow; } +/*! + Return YES if anAncestor is the parent or a higher ancestor of the receiver. + + @ignore +*/ +- (BOOL)_hasAncestorWindow:(CPWindow)anAncestor +{ + if (!_parentWindow || !anAncestor) + return NO; + + if (anAncestor === _parentWindow) + return YES; + + return [_parentWindow _hasAncestorWindow:anAncestor]; +} + - (CPWindow)setParentWindow:(CPWindow)parentWindow { _parentWindow = parentWindow; diff --git a/AppKit/_CPPopoverWindow.j b/AppKit/_CPPopoverWindow.j index d3e2b16e9..914af3b3d 100644 --- a/AppKit/_CPPopoverWindow.j +++ b/AppKit/_CPPopoverWindow.j @@ -569,7 +569,9 @@ var _CPPopoverWindow_shouldClose_ = 1 << 0, var mouseWindow = [anEvent window]; - if (mouseWindow === self) + // Consider clicks in child windows to be "inside". This keeps a transient popover from + // closing if e.g. the window containing the menu of a token field is clicked. + if (mouseWindow === self || [mouseWindow _hasAncestorWindow:self]) [self _trapNextMouseDown]; else {