[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: View hierarchy problem
From: |
Fred Kiefer |
Subject: |
Re: View hierarchy problem |
Date: |
Mon, 20 Aug 2007 15:51:43 +0200 |
User-agent: |
Thunderbird 1.5.0.12 (X11/20060911) |
Fred Kiefer wrote:
> Andreas Höschler wrote:
>> Hi Fred,
>>
>>> Andreas Höschler wrote:
>>>> Hello all,
>>>>
>>>> I have an application with a shelf view that has a bunch of subviews
>>>> (icons representing applications). In windowDidBecomeKey: I reload the
>>>> shelf, meaning that I do removeFromSuperviewWithoutNeedingDisplay for
>>>> all these subviews and then rebuild the shelf (recreate all the
>>>> subviews). Doubleclicking on one of these subviews launches or activates
>>>> the represented application.
>>>>
>>>> From time to time I get a core dump when doubleclicking from one app to
>>>> the next on the shelf. By backtracing I found out that
>>>>
>>>> [NSWindow makeFirstResponder:];
>>>>
>>>> is called with a previoulsy removed (and released) view (one of the
>>>> views that have been recreated earlier in windowDidBecomeKey:). Here is
>>>> a pseudo backtrace of this
>>>>
>>>> [NSWindow makeFistResponder:] <--------
>>>> [NSWindow sendEvent:];
>>>> [NSApplication sendEvent:]
>>>> [NSApplication run]
>>>>
>>>> I realized some code in [NSView removeSubview:] that is obviously meant
>>>> to remove the to be removed view from teh view hierachy, but it seems it
>>>> is still retained by some event circling around in the event loop and
>>>> then causes the malfunction.
>>>>
>>>> Any idea how this error can be prevented or further tracked down?
>>>>
>>> No, really no idea how this could happen. The view used in sendEvent for
>>> makeFristResponder comes from a hit test on the window view (_wv). This
>>> means your removed and released view must still be in the window
>>> hierarchy.
>>> Ah, now I see the issue: this view gets cached in sendEvent: before
>>> makeKeyAndOrderFront: gets called. We just need to move the detection of
>>> this view a few lines down. Could you please test this, before I make
>>> this change?
>> I have tried the following:
>>
>> v = nil;// [_wv hitTest:[theEvent locationInWindow]];
>> if (_f.is_key == NO && _windowLevel != NSDesktopWindowLevel)
>> {
>> /* NSPanel modification: check becomesKeyOnlyIfNeeded. */
>> if (![self becomesKeyOnlyIfNeeded]
>> || [v needsPanelToBecomeKey])
>> [self makeKeyAndOrderFront: self];
>> }
>> v = [_wv hitTest:[theEvent locationInWindow]];
>> /* Activate the app *after* making the receiver key, as app
>> activation tries to make the previous key window key. */
>> if ([NSApp isActive] == NO && self != [NSApp iconWindow])
>> {
>> [NSApp activateIgnoringOtherApps: YES];
>> }
>> if (_firstResponder != v)
>> {
>> [self makeFirstResponder: v];
>> }
>>
>> This solves the issue. The app no longer dies. However, what do we do
>> with [v needsPanelToBecomeKey]?
>>
>
> True, this really is a problem and to call htiText: twice each time, in
> most cases with the same result sounds wrong to me. We could retain the
> view and add a test if the found view is still a descendent of the
> content view. But even in that case the view could have been moved
> around by the activation code. I am really not sure if we should support
> rearranging views in the activation, but if Apple does, we may have to.
>
I found a way that seems OK to me. Please give it a try.
Fred