[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: |
Sun, 19 Aug 2007 23:14:55 +0200 |
User-agent: |
Thunderbird 1.5.0.12 (X11/20060911) |
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.
Fred