File: lifecycler.go

package info (click to toggle)
golang-golang-x-exp 0.0~git20230522.2e198f4-1~bpo12%2B1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-backports
  • size: 6,404 kB
  • sloc: ansic: 1,900; objc: 276; sh: 272; asm: 48; makefile: 26
file content (80 lines) | stat: -rw-r--r-- 2,025 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// 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{})
}