Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Improve scroll speed #5283

Draft
wants to merge 4 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions event.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,26 @@ type DragEvent struct {
PointEvent
Dragged Delta
}

type EventFunc interface {
Execute()
}

type SimpleEventFunc func()

func (fn SimpleEventFunc) Execute() {
fn()
}

type DragEventFunc struct {
wid Draggable
ev *DragEvent
}

func NewDragEventFunc(wid Draggable, ev *DragEvent) *DragEventFunc {
return &DragEventFunc{wid, ev}
}

func (drag *DragEventFunc) Execute() {
drag.wid.Dragged(drag.ev)
}
Comment on lines +39 to +60
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this is a draft PR but just FYI: this adds a public API for something that I suppose only was intended to be used internally? You might want to use one of the packages in the internal/ folder.

102 changes: 102 additions & 0 deletions internal/async/chan_eventfunc.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions internal/async/chan_go1.21.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,17 @@ func NewUnboundedInterfaceChan() *UnboundedInterfaceChan {
// CanvasObject objects. A channel must be closed via Close method.
type UnboundedCanvasObjectChan = UnboundedChan[fyne.CanvasObject]

type UnboundedEventFuncChan = UnboundedChan[fyne.EventFunc]

// NewUnboundedCanvasObjectChan returns a unbounded channel, of canvas objects, with unlimited capacity.
func NewUnboundedCanvasObjectChan() *UnboundedChan[fyne.CanvasObject] {
return NewUnboundedChan[fyne.CanvasObject]()
}

func NewUnboundedEventFuncChan() *UnboundedChan[fyne.EventFunc] {
return NewUnboundedChan[fyne.EventFunc]()
}

// UnboundedChan is a channel with an unbounded buffer for caching
// Func objects. A channel must be closed via Close method.
type UnboundedChan[T any] struct {
Expand Down
5 changes: 5 additions & 0 deletions internal/async/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ func main() {
Name: "Interface",
Imports: "",
},
"chan_eventfunc.go": {
Type: "fyne.EventFunc",
Name: "EventFunc",
Imports: `import "fyne.io/fyne/v2"`,
},
},
}

Expand Down
38 changes: 32 additions & 6 deletions internal/driver/common/window.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package common

import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/internal/async"
)

// Window defines common functionality for windows.
type Window struct {
eventQueue *async.UnboundedFuncChan
eventQueue *async.UnboundedEventFuncChan
}

// DestroyEventQueue destroys the event queue.
Expand All @@ -17,20 +18,45 @@ func (w *Window) DestroyEventQueue() {
// InitEventQueue initializes the event queue.
func (w *Window) InitEventQueue() {
// This channel should be closed when the window is closed.
w.eventQueue = async.NewUnboundedFuncChan()
w.eventQueue = async.NewUnboundedEventFuncChan()
}

// QueueEvent uses this method to queue up a callback that handles an event. This ensures
// user interaction events for a given window are processed in order.
func (w *Window) QueueEvent(fn func()) {
func (w *Window) QueueEvent(fn fyne.EventFunc) {
w.eventQueue.In() <- fn
}

// RunEventQueue runs the event queue. This should called inside a go routine.
// This function blocks.
func (w *Window) RunEventQueue() {
for fn := range w.eventQueue.Out() {
fn()
for evfn := range w.eventQueue.Out() {
if dragfn, ok := evfn.(*fyne.DragEventFunc); ok {
evfn = nil

L:
for {
select {
case nevfn := <-w.eventQueue.Out():
ndragfn, ok := nevfn.(*fyne.DragEventFunc)
if !ok {
evfn = nevfn
break L
}
dragfn = ndragfn
default:
break L
}
}

dragfn.Execute()
if evfn != nil {
evfn.Execute()
}
continue
}

evfn.Execute()
}
}

Expand All @@ -39,7 +65,7 @@ func (w *Window) WaitForEvents() {
done := DonePool.Get()
defer DonePool.Put(done)

w.eventQueue.In() <- func() { done <- struct{}{} }
w.eventQueue.In() <- fyne.SimpleEventFunc(func() { done <- struct{}{} })
<-done
}

Expand Down
2 changes: 1 addition & 1 deletion internal/driver/glfw/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func (d *gLDriver) Device() fyne.Device {
func (d *gLDriver) Quit() {
if curWindow != nil {
if f := fyne.CurrentApp().Lifecycle().(*intapp.Lifecycle).OnExitedForeground(); f != nil {
curWindow.QueueEvent(f)
curWindow.QueueEvent(fyne.SimpleEventFunc(f))
}
curWindow = nil
if d.trayStop != nil {
Expand Down
2 changes: 1 addition & 1 deletion internal/driver/glfw/menu_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ func registerCallback(w *window, item *fyne.MenuItem, nextItemID int) int {
callbacks = append(callbacks, &menuCallbacks{
action: func() {
if item.Action != nil {
w.QueueEvent(item.Action)
w.QueueEvent(fyne.SimpleEventFunc(item.Action))
}
},
enabled: func() bool {
Expand Down
Loading