Work around cgo (or Clang dwarf) bug with incorrect struct size

calculation by returning void pointers for NS object constructors.
Expand examples/app to start building menus.
This commit is contained in:
Greg 2019-05-07 14:48:06 -04:00
parent 511f2f1968
commit 8ed05fb451
4 changed files with 84 additions and 7 deletions

View File

@ -1,13 +1,16 @@
package main package main
//go:generate nswrap
import ( import (
"runtime"
"gitlab.wow.st/gmp/nswrap/examples/app/ns" "gitlab.wow.st/gmp/nswrap/examples/app/ns"
) )
func main() { func nsmgr() {
//Lock OS thread because Cocoa uses thread-local storage
runtime.LockOSThread()
a := ns.NSApplicationSharedApplication() a := ns.NSApplicationSharedApplication()
a.SetActivationPolicy(ns.NSApplicationActivationPolicyRegular) a.SetActivationPolicy(ns.NSApplicationActivationPolicyRegular)
//w := ns.NSWindowAlloc()
w := ns.NSWindowAlloc().InitWithContentRect( w := ns.NSWindowAlloc().InitWithContentRect(
ns.NSMakeRect(200,200,600,600), ns.NSMakeRect(200,200,600,600),
ns.NSWindowStyleMaskTitled, ns.NSWindowStyleMaskTitled,
@ -17,6 +20,31 @@ func main() {
) )
w.SetTitle(ns.NSStringWithGoString("Hi World")) w.SetTitle(ns.NSStringWithGoString("Hi World"))
w.MakeKeyAndOrderFront(w) w.MakeKeyAndOrderFront(w)
w.SetAlphaValue(0.85)
m1 := ns.NSMenuAlloc().InitWithTitle(ns.NSStringWithGoString("Main"))
appItem := ns.NSMenuItemAlloc()
fileItem := ns.NSMenuItemAlloc()
m1.AddItem(appItem)
m1.AddItem(fileItem)
appMenu := ns.NSMenuAlloc().InitWithTitle(ns.NSStringWithGoString("App"))
fileMenu := ns.NSMenuAlloc().InitWithTitle(ns.NSStringWithGoString("File"))
m1.SetSubmenu(appMenu, appItem)
m1.SetSubmenu(fileMenu, fileItem)
s := ns.NSStringWithGoString("")
appMenu.AddItemWithTitle(ns.NSStringWithGoString("About"), nil, s)
appMenu.AddItemWithTitle(ns.NSStringWithGoString("Preferences"), nil, s)
a.SetMainMenu(m1)
fileMenu.AddItemWithTitle(ns.NSStringWithGoString("Open"), nil, s)
fileMenu.AddItemWithTitle(ns.NSStringWithGoString("New"), nil, s)
a.SetMainMenu(m1)
a.Run() a.Run()
} }
func main() {
go nsmgr()
select { }
}

View File

@ -19,13 +19,16 @@ Classes = [
"NSApplication", "NSApplication",
"NSBundle", "NSBundle",
"NSApp", "NSApp",
"NSMenu",
"NSMenuItem",
"NSWindow", "NSWindow",
"NSView",
"NSScreen", "NSScreen",
"NSEvent", "NSEvent",
"NSResponder", "NSResponder",
"NSRunLoop",
] ]
Functions = [ Functions = [
"NSApplicationMain",
"NSMake.*", "NSMake.*",
] ]
Enums = [ Enums = [
@ -33,6 +36,8 @@ Enums = [
"NSApplication.*", "NSApplication.*",
"NSBackingStore.*", "NSBackingStore.*",
"NSWindowStyleMask.*", "NSWindowStyleMask.*",
"NSWindowButton",
"NSWindowOrderingMode",
] ]
Frameworks = [ "Foundation", "AppKit", "CoreGraphics" ] Frameworks = [ "Foundation", "AppKit", "CoreGraphics" ]
Pragma = [ 'clang diagnostic ignored "-Wformat-security"' ] Pragma = [ 'clang diagnostic ignored "-Wformat-security"' ]

View File

@ -138,3 +138,31 @@ func (n *Node) _Ctype(ignore map[string]bool) string {
return s return s
} }
func (n *Node) Qualifiers() string {
if n == nil {
return ""
}
ret := []string{}
for _,c := range n.Children {
switch c.Kind {
case "TypeQualifier":
ret = append(ret,c.Content)
}
}
return strings.Join(ret," ")
}
func (n *Node) Annotations() string {
if n == nil {
return ""
}
ret := []string{}
for _,c := range n.Children {
switch c.Kind {
case "NullableAnnotation":
ret = append(ret,c.Content)
}
}
return strings.Join(ret," ")
}

View File

@ -556,6 +556,10 @@ func (w *Wrapper) ProcessMethod(m *Method) {
} }
func (w *Wrapper) ProcessFunction(m *Method) { func (w *Wrapper) ProcessFunction(m *Method) {
if m.Type.Node.IsId() {
//do not wrap functions that return ID because of CGo struct size bug
return
}
w._processMethod(m,true) w._processMethod(m,true)
} }
@ -572,6 +576,7 @@ func (w *Wrapper) _processMethod(m *Method,fun bool) {
case m.Type.GoType() != "*" + m.GoClass: case m.Type.GoType() != "*" + m.GoClass:
gname = m.GoClass + gname gname = m.GoClass + gname
default: default:
//Shorten class method names
lens1 := len(m.Class) lens1 := len(m.Class)
i := 0 i := 0
if len(gname) < len(m.Class) { i = lens1 - len(gname) } if len(gname) < len(m.Class) { i = lens1 - len(gname) }
@ -592,8 +597,19 @@ func (w *Wrapper) _processMethod(m *Method,fun bool) {
if m.Class != "" { if m.Class != "" {
cname = m.Class + "_" + cname cname = m.Class + "_" + cname
} }
var cmtype string
cmtype := m.Type.CTypeAttrib() if m.Type.IsPointer() {
// work around cgo bugs with struct size calculation
cmtype = "void*"
if x := m.Type.Node.Qualifiers(); x != "" {
cmtype = x + " " + cmtype
}
if x := m.Type.Node.Annotations(); x != "" {
cmtype = cmtype + " " + x
}
} else {
cmtype = m.Type.CTypeAttrib()
}
ns,tps,gplist := w.gpntp(m) ns,tps,gplist := w.gpntp(m)
grtype := m.Type.GoType() grtype := m.Type.GoType()
if grtype == "Void" { if grtype == "Void" {
@ -755,11 +771,11 @@ func %sAlloc() *%s {
`,i.GoName,i.GoName,i.GoName,i.Name)) `,i.GoName,i.GoName,i.GoName,i.Name))
w.cCode.WriteString(fmt.Sprintf(` w.cCode.WriteString(fmt.Sprintf(`
%s* void*
%sAlloc() { %sAlloc() {
return [%s alloc]; return [%s alloc];
} }
`, i.Name, i.Name, i.Name)) `, i.Name, i.Name))
//FIXME: sort properties //FIXME: sort properties
for _,p := range i.Properties { for _,p := range i.Properties {