November 11, 2014
> I guess you have to live using NSObject for now, until I fixed that. But in practice NSObject is the only root class. So far I've seen one other class, NSProxy, that doesn't inherit from NSObject.
>
> Ok, I had a quick look at this issue. It is implemented but it's not working. There is a test but that's only casting from a class to an interface, not the other way around. Either there's an issue in the druntime function "_dobjc_interface_cast" or in the compiler (most likely in the compiler).

OK, I see. I can live with that for now, it's just a bit unfortunate because then I will have to touch the interface headers again once it works. Just stumbled upon this thing once again while trying to use mutableCopy ;)



> It looks like the casting is implemented here [2], or at least parts of it.
> [2] https://github.com/jacob-carlborg/dmd/blob/d-objc/src/e2ir.c#L3843-L3854

whoa, thanks for that look deep into the abyss ;)
November 16, 2014
I am just stumbling over adding class objects to an array:

I get an error when trying to add class objects to an NSArray because e.g. NSString.class does not conform to ObjcObject. There is some functions in the API that require arrays of class objects, e.g. in NSPasteboard:

NSPasteboard pb = NSPasteboard.generalPasteboard() ;
NSArray classes = NSArray.arrayWithObjects(NSString.class, NSAttributedString.class, null) ;
NSString pbItem = cast(NSString) pb.readObjectsForClasses_options(classes, null).lastObject() ;

Sure, there are other functions in NSPasteboard, and readObjectsForClasses_options is not the only way to get the pasteboard items, but a great convenience in given settings.
November 17, 2014
On 2014-11-16 12:16, Christian Schneider wrote:
> I am just stumbling over adding class objects to an array:
>
> I get an error when trying to add class objects to an NSArray because
> e.g. NSString.class does not conform to ObjcObject. There is some
> functions in the API that require arrays of class objects, e.g. in
> NSPasteboard:
>
> NSPasteboard pb = NSPasteboard.generalPasteboard() ;
> NSArray classes = NSArray.arrayWithObjects(NSString.class,
> NSAttributedString.class, null) ;
> NSString pbItem = cast(NSString)
> pb.readObjectsForClasses_options(classes, null).lastObject() ;

Do you get a compile time error or runtime error?

-- 
/Jacob Carlborg
November 18, 2014
> Do you get a compile time error or runtime error?

Compiling using dmd...
source/document.d(79): Error: function foundation.array.NSArray.arrayWithObjects (ObjcObject object, ...) is not callable using argument types (Class, Class, typeof(null))

compile time.

hmm, a class object is of course not an ObjcObject, how could it be. I think here is a limit to what is possible, this is the darn id of Objective-C that makes all this funky convenience possible. Actually, it's not a big deal, there is other methods to get what you want and the above mentioned function in question is by itself just a convenience.

November 18, 2014
I'm wondering how I should deal with overriding "designated initailizers". I really have no clue about the part "self = [super...]. KeyboardView is a subclass of NSView.

@implementation KeyboardView

- (id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code here.
    }
    return self;
}
@end


This is what I came up with so far:

override KeyboardView initWithFrame(NSRect frame) [initWithFrame:] {
    //my stuff
    return cast(KeyboardView) super.initWithFrame(frame) ;
}

This compiles and does not throw any runtime error, but it's a bit against the idea, because in Objective-C the idea is to first call the super class, then adapt and override what is necessary. When calling super in the very end, this of course is no longer guaranteed.
November 18, 2014
Speaking of drawing, I have a very serious problem wit NSView. I cannot call frame() nor bounds() on instances or subclasses and get a valid NSRect. (same goes for NSWindow frame()).

I had similar problems when working with NSAttributedString and NSRange, because NSRange from Chocolat was still 32 bit. After fixing this, it all worked perfectly. The parameter to drawRect, which is a NSRect as well contains correct values. So it seems to me that the NSRect struct declared as is should work just fine.

I am trying to implement drawRect in an NSView subclass (in the Portmidi example, KeyboardView). Everything works fine, NSBezierPath drawing methods etc., but I cannot call this.frame() nor this.bounds() from within that method without triggering a runtime segmentation fault.  Often I see this in the crash log as last "message":

misaligned_stack_error_entering_dyld_stub_binder

Sometimes there is other stuff, but always indicating a memory corruption.

I have not the slightest idea what could be the problem here, it most likely is not a threading issue, as drawRect is anyway called on the main thread, and usually one only has crashes if one tries to update widgets from background threads, which of course is not allowed in Cocoa, as the AppKit is not thread safe.

I just checked back, for any widget it fails. You can easily reproduce it by e.g. opening the SimpleWebBrowser example and add in applicationDidFinishLaunching (this is a good point, because all the UI element should be ready):

NSRect backButtonFrame = backButton.frame() ;
NSLog("frame %f %f %f %f", backButtonFrame.origin.x, backButtonFrame.origin.y, backButtonFrame.size.width, backButtonFrame.size.height) ;

For custom components, if this won't work, it is almost a deal breaker for using Cocoa through D. This is quite a setback, all the rest so far encountered is working so beautifully.

November 18, 2014
On 2014-11-18 09:46, Christian Schneider wrote:

> Compiling using dmd...
> source/document.d(79): Error: function
> foundation.array.NSArray.arrayWithObjects (ObjcObject object, ...) is
> not callable using argument types (Class, Class, typeof(null))
>
> compile time.
>
> hmm, a class object is of course not an ObjcObject, how could it be. I
> think here is a limit to what is possible, this is the darn id of
> Objective-C that makes all this funky convenience possible. Actually,
> it's not a big deal, there is other methods to get what you want and the
> above mentioned function in question is by itself just a convenience.

Hmm, I don't know. Can you use a cast to get around the problem? Perhaps use a variadic template to make the API simpler.

-- 
/Jacob Carlborg
November 18, 2014
On 2014-11-18 10:07, Christian Schneider wrote:
> I'm wondering how I should deal with overriding "designated
> initailizers". I really have no clue about the part "self = [super...].
> KeyboardView is a subclass of NSView.
>
> @implementation KeyboardView
>
> - (id)initWithFrame:(NSRect)frame {
>      self = [super initWithFrame:frame];
>      if (self) {
>          // Initialization code here.
>      }
>      return self;
> }
> @end
>
>
> This is what I came up with so far:
>
> override KeyboardView initWithFrame(NSRect frame) [initWithFrame:] {
>      //my stuff
>      return cast(KeyboardView) super.initWithFrame(frame) ;
> }
>
> This compiles and does not throw any runtime error, but it's a bit
> against the idea, because in Objective-C the idea is to first call the
> super class, then adapt and override what is necessary. When calling
> super in the very end, this of course is no longer guaranteed.

Can't you just call "super" in the beginning of the method and then call return "this" at the end. Something like this:

override KeyboardView initWithFrame(NSRect frame) [initWithFrame:] {
    super.initWithFrame(frame);
    // my stuff
    return this;
}

-- 
/Jacob Carlborg
November 18, 2014
On 2014-11-18 13:47, Christian Schneider wrote:
> Speaking of drawing, I have a very serious problem wit NSView. I cannot
> call frame() nor bounds() on instances or subclasses and get a valid
> NSRect. (same goes for NSWindow frame()).
>
> I had similar problems when working with NSAttributedString and NSRange,
> because NSRange from Chocolat was still 32 bit. After fixing this, it
> all worked perfectly. The parameter to drawRect, which is a NSRect as
> well contains correct values. So it seems to me that the NSRect struct
> declared as is should work just fine.
>
> I am trying to implement drawRect in an NSView subclass (in the Portmidi
> example, KeyboardView). Everything works fine, NSBezierPath drawing
> methods etc., but I cannot call this.frame() nor this.bounds() from
> within that method without triggering a runtime segmentation fault.
> Often I see this in the crash log as last "message":
>
> misaligned_stack_error_entering_dyld_stub_binder
>
> Sometimes there is other stuff, but always indicating a memory corruption.

Could it be this issue [1]? Can you please see if you can reproduce it using just plain C.

https://issues.dlang.org/show_bug.cgi?id=5570

-- 
/Jacob Carlborg
November 18, 2014
>> Compiling using dmd...
>> source/document.d(79): Error: function
>> foundation.array.NSArray.arrayWithObjects (ObjcObject object, ...) is
>> not callable using argument types (Class, Class, typeof(null))
>
> Hmm, I don't know. Can you use a cast to get around the problem? Perhaps use a variadic template to make the API simpler.

Yes, of course, and this is really not an issue! And this convenience function can be rewritten in a few lines of code, if really necessary.