| // Copyright 2016 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| // Package lifecycler tracks a window's lifecycle state. |
| // |
| // It eliminates sending redundant lifecycle events, ones where the From and To |
| // stages are equal. For example, moving a window from one part of the screen |
| // to another should not send multiple events from StageVisible to |
| // StageVisible, even though the underlying window system's message might only |
| // hold the new position, and not whether the window was previously visible. |
| package lifecycler // import "golang.org/x/exp/shiny/driver/internal/lifecycler" |
| |
| import ( |
| "sync" |
| |
| "golang.org/x/mobile/event/lifecycle" |
| ) |
| |
| // State is a window's lifecycle state. |
| type State struct { |
| mu sync.Mutex |
| stage lifecycle.Stage |
| dead bool |
| focused bool |
| visible bool |
| } |
| |
| func (s *State) SetDead(b bool) { |
| s.mu.Lock() |
| s.dead = b |
| s.mu.Unlock() |
| } |
| |
| func (s *State) SetFocused(b bool) { |
| s.mu.Lock() |
| s.focused = b |
| s.mu.Unlock() |
| } |
| |
| func (s *State) SetVisible(b bool) { |
| s.mu.Lock() |
| s.visible = b |
| s.mu.Unlock() |
| } |
| |
| func (s *State) SendEvent(r Sender, drawContext interface{}) { |
| s.mu.Lock() |
| from, to := s.stage, lifecycle.StageAlive |
| // The order of these if's is important. For example, once a window becomes |
| // StageDead, it should never change stage again. |
| // |
| // Similarly, focused trumps visible. It's hard to imagine a situation |
| // where a window is focused and not visible on screen, but in that |
| // unlikely case, StageFocused seems the most appropriate stage. |
| if s.dead { |
| to = lifecycle.StageDead |
| } else if s.focused { |
| to = lifecycle.StageFocused |
| } else if s.visible { |
| to = lifecycle.StageVisible |
| } |
| s.stage = to |
| s.mu.Unlock() |
| |
| if from != to { |
| r.Send(lifecycle.Event{ |
| From: from, |
| To: to, |
| |
| // TODO: does shiny use this at all? |
| DrawContext: drawContext, |
| }) |
| } |
| } |
| |
| // Sender is who to send the lifecycle event to. |
| type Sender interface { |
| Send(event interface{}) |
| } |