diff --git a/internal/gts/gts.go b/internal/gts/gts.go index 47b6fbe..a6d5b48 100644 --- a/internal/gts/gts.go +++ b/internal/gts/gts.go @@ -70,7 +70,7 @@ func NewEmptyModalDialog() (*gtk.Dialog, error) { func AddAppAction(name string, call func()) { action := glib.SimpleActionNew(name, nil) - action.Connect("activate", func(*glib.SimpleAction) { call() }) + action.Connect("activate", func(interface{}) { call() }) App.AddAction(action) } @@ -161,7 +161,7 @@ func Async(fn func() (func(), error)) { // ExecLater executes the function asynchronously with a low priority. func ExecLater(fn func()) { - glib.IdleAddPriority(glib.PRIORITY_LOW, fn) + glib.IdleAddPriority(glib.PRIORITY_DEFAULT_IDLE, fn) } // ExecAsync executes function asynchronously in the Gtk main thread. diff --git a/internal/ui/messages/view.go b/internal/ui/messages/view.go index 4ed7f21..0d70ba6 100644 --- a/internal/ui/messages/view.go +++ b/internal/ui/messages/view.go @@ -2,6 +2,7 @@ package messages import ( "context" + "runtime" "time" "github.com/diamondburned/cchat" @@ -308,18 +309,22 @@ func (v *View) JoinServer(session cchat.Session, server cchat.Server, bc travers // such as determinining if it's deletable or not. v.InputView.SetMessenger(session, messenger) - gts.Async(func() (func(), error) { + go func() { // We can use a background context here, as the user can't go anywhere // that would require cancellation anyway. This is done in ui.go. s, err := messenger.JoinServer(context.Background(), v.Container) if err != nil { - err = errors.Wrap(err, "Failed to join server") + log.Error(errors.Wrap(err, "Failed to join server")) // Even if we're erroring out, we're running the done() callback // anyway. - return func() { v.ctrl.OnMessageDone(); v.FaceView.SetError(err) }, err + gts.ExecAsync(func() { + v.ctrl.OnMessageDone() + v.FaceView.SetError(err) + }) + return } - return func() { + gts.ExecAsync(func() { // Run the done() callback. v.ctrl.OnMessageDone() @@ -337,8 +342,12 @@ func (v *View) JoinServer(session cchat.Session, server cchat.Server, bc travers // Try and use the list. v.MemberList.TryAsyncList(messenger) - }, nil - }) + }) + + // Collect garbage after a channel switch since a lot of images will + // need to be freed. + runtime.GC() + }() } func (v *View) FetchBacklog() { diff --git a/main.go b/main.go index 38bf5f9..614e7ad 100644 --- a/main.go +++ b/main.go @@ -20,7 +20,7 @@ import ( func init() { go func() { // If you GC more, you have shorter STWs. Easy. - for range time.Tick(10 * time.Second) { + for range time.Tick(time.Minute) { runtime.GC() } }()