aboutsummaryrefslogtreecommitdiff
path: root/xA/xA.go
diff options
context:
space:
mode:
Diffstat (limited to 'xA/xA.go')
-rw-r--r--xA/xA.go162
1 files changed, 100 insertions, 62 deletions
diff --git a/xA/xA.go b/xA/xA.go
index e5f5ce8..f501622 100644
--- a/xA/xA.go
+++ b/xA/xA.go
@@ -281,7 +281,11 @@ func beep() {
}
go func() {
<-otoReady
- otoContext.NewPlayer(bytes.NewReader(beepSample)).Play()
+ p := otoContext.NewPlayer(bytes.NewReader(beepSample))
+ p.Play()
+ for p.IsPlaying() {
+ time.Sleep(time.Second)
+ }
}()
}
@@ -363,50 +367,6 @@ func bufferByName(name string) *buffer {
return nil
}
-func bufferActivate(name string) {
- relaySend(RelayCommandData{
- Variant: &RelayCommandDataBufferActivate{BufferName: name},
- }, nil)
-}
-
-func bufferToggleUnimportant(name string) {
- relaySend(RelayCommandData{
- Variant: &RelayCommandDataBufferToggleUnimportant{BufferName: name},
- }, nil)
-}
-
-// --- Current buffer ----------------------------------------------------------
-
-func bufferToggleLogFinish(err string, response *RelayResponseDataBufferLog) {
- if response == nil {
- showErrorMessage(err)
- return
- }
-
- wLog.SetText(string(response.Log))
- wLog.Show()
- wRichScroll.Hide()
-}
-
-func bufferToggleLog() {
- if wLog.Visible() {
- wRichScroll.Show()
- wLog.Hide()
- wLog.SetText("")
- return
- }
-
- name := bufferCurrent
- relaySend(RelayCommandData{Variant: &RelayCommandDataBufferLog{
- BufferName: name,
- }}, func(err string, response *RelayResponseData) {
- if bufferCurrent == name {
- bufferToggleLogFinish(
- err, response.Variant.(*RelayResponseDataBufferLog))
- }
- })
-}
-
func bufferAtBottom() bool {
return wRichScroll.Offset.Y >=
wRichScroll.Content.Size().Height-wRichScroll.Size().Height
@@ -421,22 +381,31 @@ func bufferScrollToBottom() {
refreshStatus()
}
+func bufferPushLine(b *buffer, line bufferLine) {
+ b.lines = append(b.lines, line)
+
+ // Fyne's text layouting is extremely slow.
+ // The limit could be made configurable,
+ // and we could use a ring buffer approach to storing the lines.
+ if len(b.lines) > 100 {
+ b.lines = slices.Delete(b.lines, 0, 1)
+ }
+}
+
// --- UI state refresh --------------------------------------------------------
func refreshIcon() {
- highlighted := false
+ resource := resourceIconNormal
for _, b := range buffers {
if b.highlighted {
- highlighted = true
+ resource = resourceIconHighlighted
break
}
}
- if highlighted {
- wWindow.SetIcon(resourceIconHighlighted)
- } else {
- wWindow.SetIcon(resourceIconNormal)
- }
+ // Prevent deadlocks (though it might have a race condition).
+ // https://github.com/fyne-io/fyne/issues/5266
+ go func() { wWindow.SetIcon(resource) }()
}
func refreshTopic(topic []bufferLineItem) {
@@ -504,6 +473,63 @@ func refreshStatus() {
wStatus.SetText(status)
}
+func recheckHighlighted() {
+ // Corresponds to the logic toggling the bool on.
+ if b := bufferByName(bufferCurrent); b != nil &&
+ b.highlighted && bufferAtBottom() &&
+ inForeground && !wLog.Visible() {
+ b.highlighted = false
+ refreshIcon()
+ refreshBufferList()
+ }
+}
+
+// --- Buffer actions ----------------------------------------------------------
+
+func bufferActivate(name string) {
+ relaySend(RelayCommandData{
+ Variant: &RelayCommandDataBufferActivate{BufferName: name},
+ }, nil)
+}
+
+func bufferToggleUnimportant(name string) {
+ relaySend(RelayCommandData{
+ Variant: &RelayCommandDataBufferToggleUnimportant{BufferName: name},
+ }, nil)
+}
+
+func bufferToggleLogFinish(err string, response *RelayResponseDataBufferLog) {
+ if response == nil {
+ showErrorMessage(err)
+ return
+ }
+
+ wLog.SetText(string(response.Log))
+ wLog.Show()
+ wRichScroll.Hide()
+}
+
+func bufferToggleLog() {
+ if wLog.Visible() {
+ wRichScroll.Show()
+ wLog.Hide()
+ wLog.SetText("")
+
+ recheckHighlighted()
+ return
+ }
+
+ name := bufferCurrent
+ relaySend(RelayCommandData{Variant: &RelayCommandDataBufferLog{
+ BufferName: name,
+ }}, func(err string, response *RelayResponseData) {
+ if bufferCurrent == name {
+ bufferToggleLogFinish(
+ err, response.Variant.(*RelayResponseDataBufferLog))
+ }
+ })
+}
+
// --- RichText formatting -----------------------------------------------------
func defaultBufferLineItem() bufferLineItem { return bufferLineItem{} }
@@ -745,6 +771,7 @@ func refreshBuffer(b *buffer) {
bufferPrintAndWatchTrailingDateChanges()
wRichText.Refresh()
bufferScrollToBottom()
+ recheckHighlighted()
}
// --- Event processing --------------------------------------------------------
@@ -755,7 +782,7 @@ func relayProcessBufferLine(b *buffer, m *RelayEventDataBufferLine) {
// Initial sync: skip all other processing, let highlights be.
bc := bufferByName(bufferCurrent)
if bc == nil {
- b.lines = append(b.lines, line)
+ bufferPushLine(b, line)
return
}
@@ -767,7 +794,7 @@ func relayProcessBufferLine(b *buffer, m *RelayEventDataBufferLine) {
separate := display &&
!visible && bc.newMessages == 0 && bc.newUnimportantMessages == 0
- b.lines = append(b.lines, line)
+ bufferPushLine(b, line)
if !(visible || m.LeakToActive) ||
b.newMessages != 0 || b.newUnimportantMessages != 0 {
if line.isUnimportant || m.LeakToActive {
@@ -780,7 +807,7 @@ func relayProcessBufferLine(b *buffer, m *RelayEventDataBufferLine) {
if m.LeakToActive {
leakedLine := line
leakedLine.leaked = true
- bc.lines = append(bc.lines, leakedLine)
+ bufferPushLine(bc, leakedLine)
if !visible || bc.newMessages != 0 || bc.newUnimportantMessages != 0 {
if line.isUnimportant {
@@ -910,11 +937,11 @@ func relayProcessMessage(m *RelayEventMessage) {
b.bufferName = data.New
- refreshBufferList()
if data.BufferName == bufferCurrent {
bufferCurrent = data.New
refreshStatus()
}
+ refreshBufferList()
if data.BufferName == bufferLast {
bufferLast = data.New
}
@@ -1311,7 +1338,8 @@ func (e *inputEntry) SetText(text string) {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
type logEntry struct {
- // XXX: Sadly, we can't seem to make it read-only in any way.
+ // XXX: Sadly, we can't seem to make it actually read-only.
+ // https://github.com/fyne-io/fyne/issues/5263
widget.Entry
}
@@ -1323,6 +1351,12 @@ func newLogEntry() *logEntry {
return e
}
+func (e *logEntry) SetText(text string) {
+ e.OnChanged = nil
+ e.Entry.SetText(text)
+ e.OnChanged = func(string) { e.Entry.SetText(text) }
+}
+
func (e *logEntry) AcceptsTab() bool {
return false
}
@@ -1356,6 +1390,9 @@ func (l *customLayout) Layout(objects []fyne.CanvasObject, size fyne.Size) {
}
if toBottom {
bufferScrollToBottom()
+ } else {
+ recheckHighlighted()
+ refreshStatus()
}
}
@@ -1472,16 +1509,14 @@ func main() {
a := app.New()
a.Settings().SetTheme(&customTheme{})
+ a.SetIcon(resourceIconNormal)
wWindow = a.NewWindow(projectName)
wWindow.Resize(fyne.NewSize(640, 480))
a.Lifecycle().SetOnEnteredForeground(func() {
// TODO(p): Does this need locking?
inForeground = true
- if b := bufferByName(bufferCurrent); b != nil {
- b.highlighted = false
- refreshIcon()
- }
+ recheckHighlighted()
})
a.Lifecycle().SetOnExitedForeground(func() {
inForeground = false
@@ -1522,7 +1557,10 @@ func main() {
wRichText = widget.NewRichText()
wRichText.Wrapping = fyne.TextWrapWord
wRichScroll = container.NewVScroll(wRichText)
- wRichScroll.OnScrolled = func(position fyne.Position) { refreshStatus() }
+ wRichScroll.OnScrolled = func(position fyne.Position) {
+ recheckHighlighted()
+ refreshStatus()
+ }
wLog = newLogEntry()
wLog.Wrapping = fyne.TextWrapWord
wLog.Hide()