Skip to content

Add ScrollToBottom method to Entry#6131

Open
XY0797 wants to merge 1 commit into
fyne-io:developfrom
XY0797:develop
Open

Add ScrollToBottom method to Entry#6131
XY0797 wants to merge 1 commit into
fyne-io:developfrom
XY0797:develop

Conversation

@XY0797

@XY0797 XY0797 commented Feb 24, 2026

Copy link
Copy Markdown

Add ScrollToBottom method to Entry widget

Description:

This PR adds a new ScrollToBottom() method to the Entry widget, allowing users to programmatically scroll the entry content to the bottom. This is useful for:

  • Any multi-line entry where automatic scrolling to the latest content is desired

Checklist:

  • Tests included.
  • Lint and formatter run with no errors.
  • Tests all pass.

Where applicable:

  • Public APIs match existing style and have Since: line.
  • Any breaking changes have a deprecation path or have been discussed.
  • Check for binary size increases when importing new modules.

Additional Notes:

Although issue #3590 mentions that alternative methods exist to achieve the same functionality, I believe providing a direct ScrollToBottom method simplifies development.

This is particularly useful for developers who simply want to use a multi-line Entry for basic, low-frequency log output.

However, I am not a professional Go developer. If I have missed any procedural steps or if there are any concerns with this approach, please feel free to point them out. Your understanding and guidance are greatly appreciated.

Add ScrollToBottom method to Entry widget
@andydotxyz

Copy link
Copy Markdown
Member

I'm hesitant on this, as the desired statement:

Any multi-line entry where automatic scrolling to the latest content is desired

Doesn't match exactly the outcome.

Because an entry will (should?) always scroll so the cursor is visible. And I you add content to an Entry then the cursor should progress to the end of that entry.

Therefore this needs a pretty solid reproduction steps and test case to show why it's not working as expected.

@XY0797

XY0797 commented Feb 26, 2026

Copy link
Copy Markdown
Author

I'm hesitant on this, as the desired statement:

Any multi-line entry where automatic scrolling to the latest content is desired

Doesn't match exactly the outcome.

Because an entry will (should?) always scroll so the cursor is visible. And I you add content to an Entry then the cursor should progress to the end of that entry.

Therefore this needs a pretty solid reproduction steps and test case to show why it's not working as expected.

Please see the example below:

package main

import (
	"fmt"
	"sync"
	"time"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/widget"
)

type FRPCApp struct {
	app         fyne.App
	window      fyne.Window
	statusLabel *widget.Label
	logBox      *widget.Entry
	startBtn    *widget.Button
	stopBtn     *widget.Button
	openBtn     *widget.Button
	logLock     sync.RWMutex
}

func NewFRPCApp() *FRPCApp {
	a := app.New()
	w := a.NewWindow("Title")
	w.Resize(fyne.NewSize(400, 300))

	app := &FRPCApp{
		app:    a,
		window: w,
	}

	app.createUI()

	return app
}

func (a *FRPCApp) createUI() {
	a.statusLabel = widget.NewLabel("Running")
	a.logBox = widget.NewMultiLineEntry()
	a.logBox.Wrapping = fyne.TextWrapWord

	a.startBtn = widget.NewButton("start", a.startFRPC)
	a.stopBtn = widget.NewButton("stop", a.stopFRPC)
	a.openBtn = widget.NewButton("open website", a.openWebsite)

	content := container.NewBorder(
		a.statusLabel,
		container.NewHBox(a.startBtn, a.stopBtn, a.openBtn),
		nil,
		nil,
		a.logBox,
	)

	a.window.SetContent(content)
}

func (a *FRPCApp) AddLog(log string) {
	a.logLock.Lock()
	a.logBox.Append(log)
	a.logLock.Unlock()
}

func (a *FRPCApp) startFRPC() {
	a.AddLog("startFRPC\n")
}

func (a *FRPCApp) stopFRPC() {
	a.AddLog("stopFRPC\n")
}

func (a *FRPCApp) openWebsite() {
	a.AddLog("openWebsite\n")
}

func main() {
	FrpcGUIApp := NewFRPCApp()
	go func() {
		ticker := time.NewTicker(1 * time.Second)
		defer ticker.Stop()
		counter := 1
		for range ticker.C {
			logLine := fmt.Sprintf("Log entry #%d at %s\n", counter, time.Now().Format("15:04:05"))
			fyne.CurrentApp().Driver().DoFromGoroutine(func() {
				FrpcGUIApp.AddLog(logLine)
			}, true)
			counter++
		}
	}()
	FrpcGUIApp.window.ShowAndRun()
}

The Entry widget is used as a log box, allowing users to easily view and copy logs.

In the example, the a.logBox is Entry. After calling a.logBox.Append, it does not automatically scroll.

Logs are generated automatically by the program, not manually entered by the user.

Therefore, the log display box should have the ability to auto-scroll. It is reasonable to add a ScrollToBottom method to the Entry.

If this method isn't added, we would need to keep track of how many lines of logs have been output so far and manually update CursorRow to achieve auto-scrolling—which would be very cumbersome.

@andydotxyz

Copy link
Copy Markdown
Member

Alternatively resolving this issue would provide an API to do what you describe without needing to expose the workings of the scroll container inside.

#3445

@XY0797

XY0797 commented Mar 16, 2026

Copy link
Copy Markdown
Author

Alternatively resolving this issue would provide an API to do what you describe without needing to expose the workings of the scroll container inside.

#3445

I think providing a ScrollToBottom directly would be simpler. It's easy to understand and won't add extra cognitive load for developers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants