gnustep-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Issues with nextKeyView chain


From: Nicola Pero
Subject: Re: Issues with nextKeyView chain
Date: Fri, 9 Apr 2010 10:53:02 +0100

But it appears to me that the code could be cleaned up and simplified quite a bit if everyone agrees with my assertion that a view should only have one (or zero) nextKeyView. To begin with, the _nextKeyView ivar could be turned into a direct pointer to the next key view rather than a GSIArray. Also, the code is not well encapsulated right now, as it makes direct changes to ivars of other objects.

Does anyone see any reason not to change nextKeyView to a single object? Would someone familiar with that code like to make the change? (In particular, I'm unsure whether there may be other classes besides NSView that might be impacted…)

I think you are misunderstanding the code here. Each view already has at most one next and previous key view, which is saved in the first element of the respective arrays. The remaining elements of the arrays are used to keep track of those views that refer to this view as their next and previous key view, respectively. For instance, given the statements
 [P1 setNextKeyView: V];
 [P2 setNextKeyView: V];
 [P3 setNextKeyView: V];
 [V setNextKeyView: N1];
 [V setNextKeyView: N2];
 [V setNextKeyView: N3];
you will end up with the following situation (sorry for the poor ASCII art, you'll need a fixed pitch font to view this correctly):

                      +-- nextKV ->---\
    P1 -- nextKV ->-+ | +-<- prevKV -- N3
                     \|/
    P2 -- nextKV ->-- V --<- prevKV -- N2
                     /|\
    P3 -- nextKV ->-+ | +-<- prevKV -- N1
       \--<- prevKV --+

Note that the previous key view of V is P3 and the next key view is N3. The pointers to P1, P2, N1, and N2 must be kept in the previous key and next key view arrays so that the nextKV pointers of P1, P2, and P3 and the prevKV pointers of N1, N2, and N3 can be reset when V is deallocated, which is necessary to prevent crashes of the sort you were experiencing.

Thanks Wolfgang

interesting ... good point and great explanation :-)

But what you describe (multiple views with the next key view set to the same view) seems like a programming (and user interface) error, so is it worth complicating the implementation to support it - wouldn't we rather have the implementation try to fix it and keep the next key
view "loop"  consistent ? :-)

The next key view loop that you describe is problematic for the user when navigating. If you are on P2 and hit 'TAB' to go from P2 to V, then when you hit 'shift-TAB' to go back to P2, the system would unexpectedly send you back to another view (P3 if I read your diagram correctly). That's not good. Really, 'shift-TAB' must undo exactly the navigation action that 'TAB' did, so if TAB goes from P2 to V, then 'shift-TAB' must go from V to P2. I personally use TABs often and get upset when I'm hit by this problem which is typical of low-quality Windowish user interfaces - typically you TAB quickly to get to the view you want, but then often you hit one TAB more than needed and get past it, so you then try to go back to it by hitting 'shift-TAB' and are irritatingly sent to some place totally unrelated in the window. As 'shift-TAB' produces unpredictable results, the only way to get back to where you want to be in a predictable time is then to hit TAB again and again and again hoping that the window loop is closed and after TABbing long enough you'll get back to the start of the window and can then TAB your way back to the view you want (and being careful not to miss it again else you'll have to frantically TAB your way out again). Irritating. :-(

I seem to remember that the API was built in such a way as to prevent this from ever happening. IIRC calling setNextKeyView: seems so innocent and "localized", but it actually does quite a bit of work in other views to keep the next key view loop consistent. And IIRC 'setPreviousKeyView:' was removed by Apple at some point - that makes it even more obvious that 'setNextKeyView:' is expected to modify things in other views to keep the key view loop consistent. :-)

So the situation you describe could (should ?) be made impossible - when you call [P2 setNextKeyView: V];, that would completely undo what [P1 setNextKeyView: V]; did. It would detect that V already has a previous key view, and would terminate that by setting both (V->PreviousKeyView)->NextKeyView and V->PreviousKeyView to nil before starting to configure the new next key view. Then any 'TAB' action would always be undoable by using 'shift-TAB', and the memory management is simpler :-)

And I agree with Doug that this thing about views editing internals of other views is not that inspiring/beautiful. An alternative (better ?) API would have the 'next key view' as an NSArray instance variable of the NSWindow, and NSWindow would have the methods to manipulate it. The implementation would then be quite simple and clear, but have obviously a different feeling as information on the next key view loop would be taken out of the specific views and become part of the window, with all the consequences
eg for NIBs etc.

Thanks



reply via email to

[Prev in Thread] Current Thread [Next in Thread]