shiny/driver/gldriver: (Cocoa) use the lifecycler.
Change-Id: Ic72c2ed7840d53c73da03649d7b221467b297007
Reviewed-on: https://go-review.googlesource.com/25351
Reviewed-by: David Crawshaw <crawshaw@golang.org>
diff --git a/shiny/driver/gldriver/cocoa.go b/shiny/driver/gldriver/cocoa.go
index cd36949..3f82485 100644
--- a/shiny/driver/gldriver/cocoa.go
+++ b/shiny/driver/gldriver/cocoa.go
@@ -34,9 +34,9 @@
"log"
"runtime"
+ "golang.org/x/exp/shiny/driver/internal/lifecycler"
"golang.org/x/exp/shiny/screen"
"golang.org/x/mobile/event/key"
- "golang.org/x/mobile/event/lifecycle"
"golang.org/x/mobile/event/mouse"
"golang.org/x/mobile/event/paint"
"golang.org/x/mobile/event/size"
@@ -44,7 +44,7 @@
"golang.org/x/mobile/gl"
)
-const useLifecycler = false
+const useLifecycler = true
var initThreadID C.uint64_t
@@ -117,7 +117,10 @@
return // closing window
}
- sendLifecycle(id, lifecycle.StageVisible)
+ // TODO: is this necessary?
+ w.lifecycler.SetVisible(true)
+ w.lifecycler.SendEvent(w, w.glctx)
+
w.Send(paint.Event{External: true})
<-w.drawDone
}
@@ -193,7 +196,7 @@
//export windowClosing
func windowClosing(id uintptr) {
- sendLifecycle(id, lifecycle.StageDead)
+ sendLifecycle(id, (*lifecycler.State).SetDead, true)
}
func sendWindowEvent(id uintptr, e interface{}) {
@@ -336,12 +339,7 @@
var lastFlags uint32
-// TODO: move sendLifecycle out of cocoa.go, for other platforms to use.
-//
-// TODO: figure out whether we need to mutex-protect windowImpl.lifecycleStage
-// (by re-using glctxMu, if we're also reading windowImpl.glctx??)
-
-func sendLifecycle(id uintptr, to lifecycle.Stage) {
+func sendLifecycle(id uintptr, setter func(*lifecycler.State, bool), val bool) {
theScreen.mu.Lock()
w := theScreen.windows[id]
theScreen.mu.Unlock()
@@ -349,44 +347,44 @@
if w == nil {
return
}
- if w.lifecycleStage == to {
- return
- }
- w.Send(lifecycle.Event{
- From: w.lifecycleStage,
- To: to,
- DrawContext: w.glctx,
- })
- w.lifecycleStage = to
+ setter(&w.lifecycler, val)
+ w.lifecycler.SendEvent(w, w.glctx)
}
-func sendLifecycleAll(to lifecycle.Stage) {
+func sendLifecycleAll(dead bool) {
+ windows := []*windowImpl{}
+
theScreen.mu.Lock()
- defer theScreen.mu.Unlock()
for _, w := range theScreen.windows {
- if w.lifecycleStage == to {
- continue
+ windows = append(windows, w)
+ }
+ theScreen.mu.Unlock()
+
+ for _, w := range windows {
+ w.lifecycler.SetFocused(false)
+ w.lifecycler.SetVisible(false)
+ if dead {
+ w.lifecycler.SetDead(true)
}
- w.Send(lifecycle.Event{
- From: w.lifecycleStage,
- To: to,
- DrawContext: w.glctx,
- })
- w.lifecycleStage = to
+ w.lifecycler.SendEvent(w, w.glctx)
}
}
//export lifecycleDeadAll
-func lifecycleDeadAll() { sendLifecycleAll(lifecycle.StageDead) }
+func lifecycleDeadAll() { sendLifecycleAll(true) }
-//export lifecycleAliveAll
-func lifecycleAliveAll() { sendLifecycleAll(lifecycle.StageAlive) }
+//export lifecycleHideAll
+func lifecycleHideAll() { sendLifecycleAll(false) }
//export lifecycleVisible
-func lifecycleVisible(id uintptr) { sendLifecycle(id, lifecycle.StageVisible) }
+func lifecycleVisible(id uintptr, val bool) {
+ sendLifecycle(id, (*lifecycler.State).SetVisible, val)
+}
//export lifecycleFocused
-func lifecycleFocused(id uintptr) { sendLifecycle(id, lifecycle.StageFocused) }
+func lifecycleFocused(id uintptr, val bool) {
+ sendLifecycle(id, (*lifecycler.State).SetFocused, val)
+}
// cocoaRune marks the Carbon/Cocoa private-range unicode rune representing
// a non-unicode key event to -1, used for Rune in the key package.
diff --git a/shiny/driver/gldriver/cocoa.m b/shiny/driver/gldriver/cocoa.m
index 7745532..1d07af7 100644
--- a/shiny/driver/gldriver/cocoa.m
+++ b/shiny/driver/gldriver/cocoa.m
@@ -173,24 +173,30 @@
[self callSetGeom];
}
+// TODO: catch windowDidMiniaturize?
+
- (void)windowDidExpose:(NSNotification *)notification {
- lifecycleVisible((GoUintptr)self);
+ lifecycleVisible((GoUintptr)self, true);
}
- (void)windowDidBecomeKey:(NSNotification *)notification {
- lifecycleFocused((GoUintptr)self);
+ lifecycleFocused((GoUintptr)self, true);
}
- (void)windowDidResignKey:(NSNotification *)notification {
- if (![NSApp isHidden]) {
- lifecycleVisible((GoUintptr)self);
+ lifecycleFocused((GoUintptr)self, false);
+ if ([NSApp isHidden]) {
+ lifecycleVisible((GoUintptr)self, false);
}
}
- (void)windowWillClose:(NSNotification *)notification {
+ // TODO: is this right? Closing a window via the top-left red button
+ // seems to return early without ever calling windowClosing.
if (self.window.nextResponder == NULL) {
return; // already called close
}
+
windowClosing((GoUintptr)self);
[self.window.nextResponder release];
self.window.nextResponder = NULL;
@@ -213,7 +219,7 @@
}
- (void)applicationWillHide:(NSNotification *)aNotification {
- lifecycleAliveAll();
+ lifecycleHideAll();
}
@end