lifecycler.go (2025B)
1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package lifecycler tracks a window's lifecycle state. 6 // 7 // It eliminates sending redundant lifecycle events, ones where the From and To 8 // stages are equal. For example, moving a window from one part of the screen 9 // to another should not send multiple events from StageVisible to 10 // StageVisible, even though the underlying window system's message might only 11 // hold the new position, and not whether the window was previously visible. 12 package lifecycler // import "golang.org/x/exp/shiny/driver/internal/lifecycler" 13 14 import ( 15 "sync" 16 17 "golang.org/x/mobile/event/lifecycle" 18 ) 19 20 // State is a window's lifecycle state. 21 type State struct { 22 mu sync.Mutex 23 stage lifecycle.Stage 24 dead bool 25 focused bool 26 visible bool 27 } 28 29 func (s *State) SetDead(b bool) { 30 s.mu.Lock() 31 s.dead = b 32 s.mu.Unlock() 33 } 34 35 func (s *State) SetFocused(b bool) { 36 s.mu.Lock() 37 s.focused = b 38 s.mu.Unlock() 39 } 40 41 func (s *State) SetVisible(b bool) { 42 s.mu.Lock() 43 s.visible = b 44 s.mu.Unlock() 45 } 46 47 func (s *State) SendEvent(r Sender, drawContext interface{}) { 48 s.mu.Lock() 49 from, to := s.stage, lifecycle.StageAlive 50 // The order of these if's is important. For example, once a window becomes 51 // StageDead, it should never change stage again. 52 // 53 // Similarly, focused trumps visible. It's hard to imagine a situation 54 // where a window is focused and not visible on screen, but in that 55 // unlikely case, StageFocused seems the most appropriate stage. 56 if s.dead { 57 to = lifecycle.StageDead 58 } else if s.focused { 59 to = lifecycle.StageFocused 60 } else if s.visible { 61 to = lifecycle.StageVisible 62 } 63 s.stage = to 64 s.mu.Unlock() 65 66 if from != to { 67 r.Send(lifecycle.Event{ 68 From: from, 69 To: to, 70 71 // TODO: does shiny use this at all? 72 DrawContext: drawContext, 73 }) 74 } 75 } 76 77 // Sender is who to send the lifecycle event to. 78 type Sender interface { 79 Send(event interface{}) 80 }