summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bleh_darwin.m20
-rw-r--r--delegate_darwin.go12
-rw-r--r--doc.go3
-rw-r--r--init.go11
-rw-r--r--objc_darwin.go18
-rw-r--r--objc_darwin.h4
-rw-r--r--test/main.go3
7 files changed, 65 insertions, 6 deletions
diff --git a/bleh_darwin.m b/bleh_darwin.m
index 8f77b84..6094eeb 100644
--- a/bleh_darwin.m
+++ b/bleh_darwin.m
@@ -20,6 +20,7 @@ though this is not always the case.
#include <AppKit/NSGraphics.h>
#include <AppKit/NSBitmapImageRep.h>
#include <AppKit/NSCell.h>
+#include <AppKit/NSApplication.h>
/* used by listbox_darwin.go; requires NSString */
id *_NSObservedObjectKey = (id *) (&NSObservedObjectKey);
@@ -241,7 +242,8 @@ static void __areaView_drawRect(id self, SEL sel, NSRect r)
void *_areaView_drawRect = (void *) __areaView_drawRect;
-/* the only objective-c feature you'll see here
+/*
+this and one below it are the only objective-c feature you'll see here
unfortunately NSRect both varies across architectures and is passed as just a structure, so its encoding has to be computed at compile time
because @encode() is NOT A LITERAL, we're going to just stick it all the way back in objc_darwin.go
@@ -327,3 +329,19 @@ void objc_setFont(id what, unsigned int csize)
objc_msgSend(what, s_setFont,
objc_msgSend(c_NSFont, s_systemFontOfSize, size));
}
+
+/*
+-[NSApplicationDelegate applicationShouldTerminate] used to return a BOOL, but now returns a NSApplicationTerminateReply, which is a NSUInteger; hence, here.
+*/
+
+extern void appDelegate_applicationShouldTerminate();
+
+static NSApplicationTerminateReply __appDelegate_applicationShouldTerminate(id self, SEL sel)
+{
+ appDelegate_applicationShouldTerminate();
+ return NSTerminateCancel; // don't quit
+}
+
+void *_appDelegate_applicationShouldTerminate = (void *) __appDelegate_applicationShouldTerminate;
+
+char *encodedTerminateReply = @encode(NSApplicationTerminateReply);
diff --git a/delegate_darwin.go b/delegate_darwin.go
index 00bdf6e..a8140e2 100644
--- a/delegate_darwin.go
+++ b/delegate_darwin.go
@@ -12,6 +12,7 @@ This creates a class goAppDelegate that will be used as the delegate for /everyt
- handles window close events (windowShouldClose:)
- handles window resize events (windowDidResize:)
- handles button click events (buttonClicked:)
+ - handles the application-global Quit event (such as from the Dock) (applicationShouldTerminate)
*/
// #cgo LDFLAGS: -lobjc -framework Foundation -framework AppKit
@@ -45,6 +46,8 @@ var appDelegateSels = []selector{
"handling window resize events"},
selector{"buttonClicked:", uintptr(C.appDelegate_buttonClicked), sel_bool_id,
"handling button clicks"},
+ selector{"applicationShouldTerminate", uintptr(C._appDelegate_applicationShouldTerminate), sel_terminatereply,
+ "handling Quit menu items (such as from the Dock)/the AppQuit channel"},
}
func mkAppDelegate() error {
@@ -94,3 +97,12 @@ func appDelegate_buttonClicked(self C.id, sel C.SEL, button C.id) {
sysData := getSysData(button)
sysData.signal()
}
+
+//export appDelegate_applicationShouldTerminate
+func appDelegate_applicationShouldTerminate() {
+ // asynchronous so as to return control to the event loop
+ go func() {
+ AppQuit <- struct{}{}
+ }()
+ // xxx in bleh_darwin.m tells Cocoa not to quit
+}
diff --git a/doc.go b/doc.go
index a0a1b01..8a545fd 100644
--- a/doc.go
+++ b/doc.go
@@ -20,6 +20,7 @@ Here is a simple, complete program that asks the user for their name and greets
func myMain() {
w := ui.NewWindow("Hello", 400, 100)
+ ui.AppQuit = w.Closing // treat quitting the application like closing the main window
nameField := ui.NewLineEdit("Enter Your Name Here")
button := ui.NewButton("Click Here For a Greeting")
err := w.Open(ui.NewVerticalStack(nameField, button))
@@ -29,7 +30,7 @@ Here is a simple, complete program that asks the user for their name and greets
for {
select {
- case <-w.Closing: // user tries to close the window
+ case <-w.Closing: // user tries to close the window or quit the program
return
case <-button.Clicked: // user clicked the button
ui.MsgBox("Hello, " + nameField.Text() + "!", "")
diff --git a/init.go b/init.go
index b4214ac..9349713 100644
--- a/init.go
+++ b/init.go
@@ -14,3 +14,14 @@ package ui
func Go(main func()) error {
return ui(main)
}
+
+// AppQuit is pulsed when the user decides to quit the program if their operating system provides a facility for quitting an entire application, rather than merely close all windows (for instance, Mac OS X via the Dock icon).
+// You should assign one of your Windows's Closing to this variable so the user choosing to quit the application is treated the same as closing that window.
+// If you do not respond to this signal, nothing will happen.
+// Do not merely check this channel alone; it is not guaranteed to be pulsed on all systems or in all conditions.
+var AppQuit chan struct{}
+
+func init() {
+ // don't expose this in the documentation
+ AppQuit = newEvent()
+}
diff --git a/objc_darwin.go b/objc_darwin.go
index d7e8f7a..b4b44e8 100644
--- a/objc_darwin.go
+++ b/objc_darwin.go
@@ -71,14 +71,16 @@ const (
sel_bool_id
sel_bool
sel_void_rect
+ sel_terminatereply
nitypes
)
var itypes = [nitypes][]C.char{
- sel_void_id: []C.char{'v', '@', ':', '@', 0},
- sel_bool_id: []C.char{'c', '@', ':', '@', 0},
- sel_bool: []C.char{'c', '@', ':', 0},
- sel_void_rect: nil, // see init() below
+ sel_void_id: []C.char{'v', '@', ':', '@', 0},
+ sel_bool_id: []C.char{'c', '@', ':', '@', 0},
+ sel_bool: []C.char{'c', '@', ':', 0},
+ sel_void_rect: nil, // see init() below
+ sel_terminatereply: nil,
}
func init() {
@@ -91,6 +93,14 @@ func init() {
}
x = append(x, 0)
itypes[sel_void_rect] = x
+
+ x = make([]C.char, 0, 256) // more than enough
+ y = C.GoString(C.encodedTerminateReply)
+ for _, b := range y {
+ x = append(x, C.char(b))
+ }
+ x = append(x, '@', ':', 0)
+ itypes[sel_terminatereply] = x
}
func makeClass(name string, super C.id, sels []selector, desc string) (id C.id, err error) {
diff --git a/objc_darwin.h b/objc_darwin.h
index 84f4e70..fbe169c 100644
--- a/objc_darwin.h
+++ b/objc_darwin.h
@@ -117,8 +117,12 @@ extern struct xpoint getTranslatedEventPoint(id, id);
/* for objc_darwin.go */
extern char *encodedNSRect;
+extern char *encodedTerminateReply;
/* for sysdata_darwin.go */
extern void objc_setFont(id, unsigned int);
+/* for delegate_darwin.go */
+extern void *_appDelegate_applicationShouldTerminate;
+
#endif
diff --git a/test/main.go b/test/main.go
index 1c8f948..9df9c13 100644
--- a/test/main.go
+++ b/test/main.go
@@ -282,6 +282,9 @@ _=curtime
case <-w.Closing:
println("window closed event received")
break mainloop
+ case <-AppQuit:
+ println("application quit event received")
+ break mainloop
case <-b.Clicked:
w.SetTitle(fmt.Sprintf("%v | %s | %s | %s | %s",
c.Checked(),