bugGNUstep - Bugs: bug #34764, XIB loading: "Custom...


bug #34764: XIB loading: "Custom class" set in Interface Builder ignored

Submitted by:  julian <julian_>
Submitted on:  Mon 07 Nov 2011 12:45:44 AM UTC
Category:  Gui/AppKit Severity:  4 - Important
Item Group:  Bug Status:  Fixed
Privacy:  Public Assigned to:  gcasa
Open/Closed:  Closed
* Mandatory Fields

Add a New Comment (Rich Markup)

Comment Type & Canned Response:


( Jump to the original submission )

Fri 30 Oct 2020 12:27:53 PM UTC, comment #13: 

Loading of the custom class works, per Fred's comment.  This was the original purpose of this bug.  I am, therefore, closing it.  If the mouseUp: not getting called is still a problem, please open a bug for that.

Gregory John Casamento <gcasa>
Project Administrator
Sat 23 Mar 2013 07:50:15 PM UTC, comment #12: 

The loading of the custom class now works correctly. But in GNUstep the mouseUp: method never gets called.
This may need a rewrite of the mouse tracking code in NSControl and NSCell to work.

Fred Kiefer <FredKiefer>
Project Member
Sun 09 Sep 2012 06:21:06 PM UTC, comment #11: 

sorry i don't have a linux installation anymore. should be trivial to verify the fix with the sample i attached though.

julian <julian_>
Fri 07 Sep 2012 08:13:50 PM UTC, comment #10: 

Greggory implemented a solution to this problem. Could you please upgrade gui to current SVN and give it a try?

Fred Kiefer <FredKiefer>
Project Member
Sat 31 Mar 2012 05:50:14 PM UTC, comment #9: 

I didn't think hard enougth when making the last suggestion. The complicated bit was the one in brackets "(plus the ids of the objects they belong to)". Outside the decoder itself we never deal with these ids, the only thing we have are the objectIDs in the IBObjectRecord amd the objects there.

Eric's idea of haveing a decoder mode where we get back the ids when decoding references might help here. This time I will try to think harder before making a new suggestion.

Fred Kiefer <FredKiefer>
Project Member
Fri 30 Mar 2012 08:02:11 PM UTC, comment #8: 

Thank you to both of you for your ideas. I am sure that we will crack this, if we work together on it. Your ideas may already be partial solutions here. But as usual things are a bit more difficult. The objects we try to decode show up at least in two places in the XIB file. One is the IBObjectContainer (key "IBDocument.Objects") and the other the NSMutableArray (key "IBDocument.RootObjects"). The later is far better suited for decoding, as objects show up here in a top down order. But only in the former do we have the flattened properties.

I think we should change the decoding order around. Get the IBObjectContainer first, but try not to decode the objects for IBObjectRecords. Maybe just get the flattenedProperties and the half decoded objectRecords. For these we would try to extract the id of the object, this is mostly stored as a reference, but in rare cases we have real objects as well.
We would then loop over all these IBObjectRecords and see whether we have some properties for an objectID. In that case we store these in the decoder for the id.

Hmm, thinking all this over, it seems easier to me to do the whole decoding twice.
In loadModelData:externalNameTable:withZone: we could create a decoder, get the flattened properties (plus the ids of the objects they belong to) from it and throw it away. Then we create another decoder, set up the properties there and do the real decoding.

This may be a slower solution, but seems a lot cleaner to me, as we don't have to fiddle around with too much decoder internals.
As far as I see the only property we are currently interested in is the custom class name, we could handle that in the method decodeObjectForXib:forClassName:withID:

What do you think about this approach?

Fred Kiefer <FredKiefer>
Project Member
Thu 29 Mar 2012 04:47:46 PM UTC, comment #7: 

That is an rather interesting puzzle, and somehow I cannot restrain myself from adding my very own two cents to this:

Maybe we could make -[IBObjectRecord initWithCoder:] do a partial decoding by default, keep the coder around and then (ab)use the -unarchiverDidFinish: delegate method on the IBObjectContainer to trigger a complete decoding of the IBObjectRecords. But here I'm assuming that IBObjectRecords only ever occur in IBObjectContainers...

But then on the other hand, I might be way off here.



Niels Grewe <thebeing>
Project Member
Wed 28 Mar 2012 08:46:37 PM UTC, comment #6: 

Sure, Fred, I'll try to help. I had another look today.

I think we must determine the final class name before instantiating the object. As you, say there are too many problems with trying to change the class after decoding it.

For Julain's example, the custom class name is stored in the flattenedProperties dictionary under the objectID of the IBObjectRecord for the NSImageView object.

So the problem is: when we are in  -[GSXibKeyedUnarchiver decodeObjectForXib:forClassName:withID:], we need to be able to look up the IBObjectRecord which contains the current object; in other words, the IBObjectContainer needs to be fully decoded.

The tricky thing is controlling the order of decoding. We need to decode the IBObjectContainer (with the flattened properties, and object records) before decoding any of the regular objects, but this is not possible since decoding an object record will trigger decoding the object it references.

The only thing I can come up with is a bit of a hack. We add a flag to GSXibKeyedUnarchiver, -setDecodesReferencesAsStrings: (BOOL). When this is YES, calling -decodeObjectForKey: will give you an NSString with the object's ID, rather than actually decoding it.  Then, we turn on this flag when decoding IBObjectContainer, so any references from the object container to the main XIB object graph are just string ID's, and hence the main object graph will remain undecoded.

As far as I can see this is the only way to do it… I have no idea why the format is designed like it is. AFAIK Xcode compiles xibs to nibs and AppKit doesn't load them directly, so Apple can probably with oddities like this more easily.

Eric Wasylishen <ericw>
Project Member
Wed 28 Mar 2012 04:27:21 PM UTC, comment #5: 

Maybe we could work together in solving this problem?

Decoding the flattenedProperties isn't to complicated itself. I already added that some time ago to get the visibleAtLaunch property for windows. The real problem is that at the time we use these properties the object is already decode and in case of the image view, placed into the view hierarchy. We could move this code before the setting of connections, which would help a bit. But for the view hierarchy it might be rather tricky to replace one view with another. Not to mention the problem of bringing over all decoded properties.

My initial idea here was to have the class name available at the time of object creation, as we would have with NSCustomView, but I couldn't figure out a way to do so.

Fred Kiefer <FredKiefer>
Project Member
Tue 27 Mar 2012 11:03:02 PM UTC, comment #4: 

I changed the title of this bug.

Fred: it may be stored awkwardly, but this is certainly a bug in XIB loading, and in my experience a critical one as I use this feature in any non-trivial xib/nib. I made one attempt a few months ago at reading the flattendProperties dictionary but couldn't get it to work.

Eric Wasylishen <ericw>
Project Member
Mon 14 Nov 2011 06:07:08 PM UTC, comment #3: 

actually the title of the bug is true too. if i change the custom class to be a "NSCustomView" in IB so gnustep can decode it from the XIB.... the subclass still won't get mouseUp: events. it gets the mouseDown: events though, so there is an easy workaround ;)

julian <julian_>
Mon 07 Nov 2011 02:39:07 PM UTC, comment #2: 

ok thanks so the bug here seems to be that custom classes don't get decoded properly from XIB files at all and nothing about NSImageView subclasses and events.

if i add a custom view to IB instead i can't set its properties at all from IB (i.e. the image and its properties - you can't even set the tag for customviews) and have to setup outlets and add setup-code so i'd rather not receive the mouse clicks for the time being - its doesn't break an important feature ;-)

julian <julian_>
Mon 07 Nov 2011 02:25:31 PM UTC, comment #1: 

There is no chance that your method will ever be called as the XIB file has the class of the view as NSImageView. Your ClickableImageView gets only mentioned in the flattendProperties as the CustomClassName for that view.

There surely is a way to test for each object that we decode whether there are any additional values set in the flattendProperties dictionary, but I really don't want to implement this stupid behaviour.

I think for now it is best if you recreate your XIB file with a custom view instead of an NSImageView.

Fred Kiefer <FredKiefer>
Project Member
Mon 07 Nov 2011 12:45:44 AM UTC, original submission:  

NSImageView subclasses don't get mouseUp: events when being clicked

( even when )awakeFromNib calls    [self setRefusesFirstResponder:NO]; )

sample project attached. on cocoa you can click the image and the subclass intercepts mouseUp and throws an dialog up

julian <julian_>


(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:

Attached Files
file #24316:  gnustepbug-imageview.zip added by julian_ (220KiB - application/zip)


Depends on the following items: None found

Items that depend on this one: None found


Carbon-Copy List
  • -email is unavailable- added by gcasa (Posted a comment)
  • -email is unavailable- added by thebeing (Posted a comment)
  • -email is unavailable- added by ericw (Posted a comment)
  • -email is unavailable- added by FredKiefer (Posted a comment)
  • -email is unavailable- added by julian_ (Submitted the item)

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only logged-in users can vote.





    Follow 10 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2020-10-30 gcasa StatusConfirmed => Fixed
        Assigned toNone => gcasa
        Open/ClosedOpen => Closed
    2012-03-27 ericw Severity3 - Normal => 4 - Important
        Item GroupChange Request => Bug
        SummaryNSImageView subclasses don\'t get mouseUp: events when being clicked => XIB loading: "Custom class" set in Interface Builder ignored
    2011-11-07 FredKiefer CategoryNone => Gui/AppKit
        Item GroupNone => Change Request
        StatusNone => Confirmed
    2011-11-07 julian_ Attached File- => Added gnustepbug-imageview.zip, #24316

    Back to the top

    Powered by Savane 3.9