From 67b2671dad5398eda845a9b3d2e9542e3182f07d Mon Sep 17 00:00:00 2001 From: Klaas Pieter Annema Date: Thu, 15 Sep 2011 16:39:24 +0200 Subject: [PATCH] improve key view loops - include the window's content view at the start of the key view loop - set the initial first responder to the window's content view (and keep it that way unless it is explicitly changed) - CPWindow should return NO from acceptsFirstResponder (Cocoa compliance). - change the type of setInitialFirstResponder, this is compliant with Cocoa. The new key view loop code will break if initial first responder is anything but a view - change the implementation of selectNextKeyView:, selectPreviousKeyView:, selectKeyViewFollowingView: and selectKeyViewPrecedingView: to follow to Cocoa's documentation --- AppKit/CPWindow/CPWindow.j | 73 +++++++++++++++++++++++++++++++------- 1 file changed, 61 insertions(+), 12 deletions(-) diff --git a/AppKit/CPWindow/CPWindow.j b/AppKit/CPWindow/CPWindow.j index 2bed398b6..1e2b05ab2 100644 --- a/AppKit/CPWindow/CPWindow.j +++ b/AppKit/CPWindow/CPWindow.j @@ -426,6 +426,7 @@ CPTexturedBackgroundWindowMask // Create a generic content view. [self setContentView:[[CPView alloc] initWithFrame:CGRectMakeZero()]]; + [self setInitialFirstResponder:[self contentView]]; _firstResponder = self; @@ -950,6 +951,12 @@ CPTexturedBackgroundWindowMask var bounds = CGRectMake(0.0, 0.0, CGRectGetWidth(_frame), CGRectGetHeight(_frame)); + // During init the initial first responder is set to the contentView + // if it hasn't changed in the mean time we need to update that reference + // to the new contentView + if ([self initialFirstResponder] === _contentView) + [self setInitialFirstResponder:aView]; + _contentView = aView; [_contentView setFrame:[self contentRectForFrameRect:bounds]]; @@ -1274,17 +1281,17 @@ CPTexturedBackgroundWindowMask - (BOOL)acceptsFirstResponder { - return YES; + return NO; } -- (id)initialFirstResponder +- (CPView)initialFirstResponder { return _initialFirstResponder; } -- (void)setInitialFirstResponder:(id)aResponder +- (void)setInitialFirstResponder:(CPView)aView { - _initialFirstResponder = aResponder; + _initialFirstResponder = aView; } /*! @@ -2487,30 +2494,70 @@ CPTexturedBackgroundWindowMask - (void)selectNextKeyView:(id)sender { + if (_keyViewLoopIsDirty && [self autorecalculatesKeyViewLoop]) + [self recalculateKeyViewLoop]; + + var nextValidKeyView = nil; + if ([_firstResponder isKindOfClass:[CPView class]]) - [self selectKeyViewFollowingView:_firstResponder]; + nextValidKeyView = [_firstResponder nextValidKeyView]; + + if (!nextValidKeyView) + { + var initialFirstResponder = [self initialFirstResponder]; + + if ([initialFirstResponder acceptsFirstResponder]) + nextValidKeyView = initialFirstResponder; + else + nextValidKeyView = [initialFirstResponder nextValidKeyView]; + } + + [self makeFirstResponder:nextValidKeyView]; } - (void)selectPreviousKeyView:(id)sender { + if (_keyViewLoopIsDirty && [self autorecalculatesKeyViewLoop]) + [self recalculateKeyViewLoop]; + + var previousValidKeyView = nil; + if ([_firstResponder isKindOfClass:[CPView class]]) - [self selectKeyViewPrecedingView:_firstResponder]; + previousValidKeyView = [_firstResponder previousValidKeyView]; + + if (!previousValidKeyView) + { + var initialFirstResponder = [self initialFirstResponder]; + + if ([initialFirstResponder acceptsFirstResponder]) + previousValidKeyView = initialFirstResponder; + else + previousValidKeyView = [initialFirstResponder previousValidKeyView]; + } + + [self makeFirstResponder:previousValidKeyView]; } - (void)selectKeyViewFollowingView:(CPView)aView { - if (_keyViewLoopIsDirty) + if (_keyViewLoopIsDirty && [self autorecalculatesKeyViewLoop]) [self recalculateKeyViewLoop]; - [self makeFirstResponder:[aView nextValidKeyView]]; + var nextValidKeyView = [aView nextValidKeyView]; + + if ([nextValidKeyView isKindOfClass:[CPView class]]) + [self makeFirstResponder:nextValidKeyView]; } - (void)selectKeyViewPrecedingView:(CPView)aView { - if (_keyViewLoopIsDirty) + if (_keyViewLoopIsDirty && [self autorecalculatesKeyViewLoop]) [self recalculateKeyViewLoop]; - [self makeFirstResponder:[aView previousValidKeyView]]; + var previousValidKeyView = [aView previousValidKeyView]; + + if ([previousValidKeyView isKindOfClass:[CPView class]]) + [self makeFirstResponder:previousValidKeyView]; } /*! @@ -2598,9 +2645,11 @@ CPTexturedBackgroundWindowMask var allViews = function(aWindow) { - var views = [[aWindow contentView] subviews], - index = 0; + var views = [CPArray arrayWithObject:[aWindow contentView]]; + [views addObjectsFromArray:[[aWindow contentView] subviews]]; + + var index = 0; for (; index < views.length; ++index) views = views.concat([views[index] subviews]);