• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

fyne-io / fyne / 18807176232

25 Oct 2025 06:34PM UTC coverage: 61.057% (-0.004%) from 61.061%
18807176232

Pull #5989

github

Jacalz
Fix TODO regarding comparable map key
Pull Request #5989: RFC: Proof of concept for upgrading Go to 1.24

155 of 188 new or added lines in 62 files covered. (82.45%)

27 existing lines in 6 files now uncovered.

25609 of 41943 relevant lines covered (61.06%)

692.99 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.24
/internal/driver/util.go
1
package driver
2

3
import (
4
        "math"
5
        "slices"
6

7
        "fyne.io/fyne/v2"
8
        "fyne.io/fyne/v2/internal/cache"
9
)
10

11
// AbsolutePositionForObject returns the absolute position of an object in a set of object trees.
12
// If the object is not part of any of the trees, the position (0,0) is returned.
13
func AbsolutePositionForObject(object fyne.CanvasObject, trees []fyne.CanvasObject) fyne.Position {
9✔
14
        var pos fyne.Position
9✔
15
        findPos := func(o fyne.CanvasObject, p fyne.Position, _ fyne.Position, _ fyne.Size) bool {
187✔
16
                if o == object {
185✔
17
                        pos = p
7✔
18
                        return true
7✔
19
                }
7✔
20
                return false
171✔
21
        }
22
        for _, tree := range trees {
28✔
23
                if WalkVisibleObjectTree(tree, findPos, nil) {
26✔
24
                        break
7✔
25
                }
26
        }
27
        return pos
9✔
28
}
29

30
// FindObjectAtPositionMatching is used to find an object in a canvas at the specified position.
31
// The matches function determines of the type of object that is found at this position is of a suitable type.
32
// The various canvas roots and overlays that can be searched are also passed in.
33
func FindObjectAtPositionMatching(mouse fyne.Position, matches func(object fyne.CanvasObject) bool, overlay fyne.CanvasObject, roots ...fyne.CanvasObject) (fyne.CanvasObject, fyne.Position, int) {
5✔
34
        var found fyne.CanvasObject
5✔
35
        var foundPos fyne.Position
5✔
36

5✔
37
        findFunc := func(walked fyne.CanvasObject, pos fyne.Position, clipPos fyne.Position, clipSize fyne.Size) bool {
28✔
38
                if !walked.Visible() {
23✔
39
                        return false
×
40
                }
×
41

42
                if mouse.X < clipPos.X || mouse.Y < clipPos.Y {
23✔
43
                        return false
×
44
                }
×
45

46
                if mouse.X >= clipPos.X+clipSize.Width || mouse.Y >= clipPos.Y+clipSize.Height {
23✔
47
                        return false
×
48
                }
×
49

50
                if mouse.X < pos.X || mouse.Y < pos.Y {
31✔
51
                        return false
8✔
52
                }
8✔
53

54
                if mouse.X >= pos.X+walked.Size().Width || mouse.Y >= pos.Y+walked.Size().Height {
24✔
55
                        return false
9✔
56
                }
9✔
57

58
                if matches(walked) {
8✔
59
                        found = walked
2✔
60
                        foundPos = fyne.NewPos(mouse.X-pos.X, mouse.Y-pos.Y)
2✔
61
                }
2✔
62
                return false
6✔
63
        }
64

65
        layer := 0
5✔
66
        if overlay != nil {
7✔
67
                WalkVisibleObjectTree(overlay, findFunc, nil)
2✔
68
        } else {
5✔
69
                for _, root := range roots {
8✔
70
                        layer++
5✔
71
                        if root == nil {
5✔
72
                                continue
×
73
                        }
74
                        WalkVisibleObjectTree(root, findFunc, nil)
5✔
75
                        if found != nil {
6✔
76
                                break
1✔
77
                        }
78
                }
79
        }
80

81
        return found, foundPos, layer
5✔
82
}
83

84
// ReverseWalkVisibleObjectTree will walk an object tree in reverse order for all visible objects
85
// executing the passed functions following the following rules:
86
// - beforeChildren is called for the start obj before traversing its children
87
// - the obj's children are traversed by calling walkObjects on each of the visible items
88
// - afterChildren is called for the obj after traversing the obj's children
89
// The walk can be aborted by returning true in one of the functions:
90
//   - if beforeChildren returns true, further traversing is stopped immediately, the after function
91
//     will not be called for the obj where the walk stopped, however, it will be called for all its
92
//     parents
93
func ReverseWalkVisibleObjectTree(
94
        obj fyne.CanvasObject,
95
        beforeChildren func(fyne.CanvasObject, fyne.Position, fyne.Position, fyne.Size) bool,
96
        afterChildren func(fyne.CanvasObject, fyne.Position, fyne.CanvasObject),
97
) bool {
2✔
98
        clipSize := fyne.NewSize(math.MaxInt32, math.MaxInt32)
2✔
99
        return walkObjectTree(obj, true, nil, fyne.NewPos(0, 0), fyne.NewPos(0, 0), clipSize, beforeChildren, afterChildren, true)
2✔
100
}
2✔
101

102
// WalkCompleteObjectTree will walk an object tree for all objects (ignoring visible state) executing the passed
103
// functions following the following rules:
104
// - beforeChildren is called for the start obj before traversing its children
105
// - the obj's children are traversed by calling walkObjects on each of the items
106
// - afterChildren is called for the obj after traversing the obj's children
107
// The walk can be aborted by returning true in one of the functions:
108
//   - if beforeChildren returns true, further traversing is stopped immediately, the after function
109
//     will not be called for the obj where the walk stopped, however, it will be called for all its
110
//     parents
111
func WalkCompleteObjectTree(
112
        obj fyne.CanvasObject,
113
        beforeChildren func(fyne.CanvasObject, fyne.Position, fyne.Position, fyne.Size) bool,
114
        afterChildren func(fyne.CanvasObject, fyne.Position, fyne.CanvasObject),
115
) bool {
1✔
116
        clipSize := fyne.NewSize(math.MaxInt32, math.MaxInt32)
1✔
117
        return walkObjectTree(obj, false, nil, fyne.NewPos(0, 0), fyne.NewPos(0, 0), clipSize, beforeChildren, afterChildren, false)
1✔
118
}
1✔
119

120
// WalkVisibleObjectTree will walk an object tree for all visible objects executing the passed functions following
121
// the following rules:
122
// - beforeChildren is called for the start obj before traversing its children
123
// - the obj's children are traversed by calling walkObjects on each of the visible items
124
// - afterChildren is called for the obj after traversing the obj's children
125
// The walk can be aborted by returning true in one of the functions:
126
//   - if beforeChildren returns true, further traversing is stopped immediately, the after function
127
//     will not be called for the obj where the walk stopped, however, it will be called for all its
128
//     parents
129
func WalkVisibleObjectTree(
130
        obj fyne.CanvasObject,
131
        beforeChildren func(fyne.CanvasObject, fyne.Position, fyne.Position, fyne.Size) bool,
132
        afterChildren func(fyne.CanvasObject, fyne.Position, fyne.CanvasObject),
133
) bool {
28✔
134
        clipSize := fyne.NewSize(math.MaxInt32, math.MaxInt32)
28✔
135
        return walkObjectTree(obj, false, nil, fyne.NewPos(0, 0), fyne.NewPos(0, 0), clipSize, beforeChildren, afterChildren, true)
28✔
136
}
28✔
137

138
func walkObjectTree(
139
        obj fyne.CanvasObject,
140
        reverse bool,
141
        parent fyne.CanvasObject,
142
        offset, clipPos fyne.Position,
143
        clipSize fyne.Size,
144
        beforeChildren func(fyne.CanvasObject, fyne.Position, fyne.Position, fyne.Size) bool,
145
        afterChildren func(fyne.CanvasObject, fyne.Position, fyne.CanvasObject),
146
        requireVisible bool,
147
) bool {
249✔
148
        if obj == nil {
249✔
149
                return false
×
150
        }
×
151
        if requireVisible && !obj.Visible() {
269✔
152
                return false
20✔
153
        }
20✔
154
        pos := obj.Position().Add(offset)
229✔
155

229✔
156
        var children []fyne.CanvasObject
229✔
157
        switch co := obj.(type) {
229✔
158
        case *fyne.Container:
51✔
159
                children = co.Objects
51✔
160
        case fyne.Widget:
115✔
161
                if cache.IsRendered(co) || requireVisible {
230✔
162
                        children = cache.Renderer(co).Objects()
115✔
163
                }
115✔
164
        }
165

166
        if IsClip(obj) {
233✔
167
                clipPos = pos
4✔
168
                clipSize = obj.Size()
4✔
169
        }
4✔
170

171
        if beforeChildren != nil {
458✔
172
                if beforeChildren(obj, pos, clipPos, clipSize) {
236✔
173
                        return true
7✔
174
                }
7✔
175
        }
176

177
        cancelled := false
222✔
178
        followChild := func(child fyne.CanvasObject) bool {
440✔
179
                if walkObjectTree(child, reverse, obj, pos, clipPos, clipSize, beforeChildren, afterChildren, requireVisible) {
223✔
180
                        cancelled = true
5✔
181
                        return true
5✔
182
                }
5✔
183
                return false
213✔
184
        }
185
        if reverse {
234✔
186
                for i := len(children) - 1; i >= 0; i-- {
29✔
187
                        if followChild(children[i]) {
17✔
188
                                break
×
189
                        }
190
                }
191
        } else {
210✔
192
                if slices.ContainsFunc(children, followChild) {
215✔
193

5✔
194
                }
5✔
195
        }
196

197
        if afterChildren != nil {
222✔
198
                afterChildren(obj, pos, parent)
×
UNCOV
199
        }
×
200
        return cancelled
222✔
201
}
202

203
func IsClip(o fyne.CanvasObject) bool {
229✔
204
        _, scroll := o.(fyne.Scrollable)
229✔
205
        if scroll {
233✔
206
                return true
4✔
207
        }
4✔
208

209
        if _, isWid := o.(fyne.Widget); !isWid {
337✔
210
                return false
112✔
211
        }
112✔
212
        r, rendered := cache.CachedRenderer(o.(fyne.Widget))
113✔
213
        if !rendered {
113✔
214
                return false
×
UNCOV
215
        }
×
216

217
        _, clip := r.(interface{ IsClip() })
113✔
218
        return clip
113✔
219
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc