From 14eb008f51033748d22f6464409f27f8e9e753e6 Mon Sep 17 00:00:00 2001 From: Julien Semaan Date: Tue, 1 Dec 2020 13:34:50 -0500 Subject: [PATCH] fix mem leak in peers table due to https://github.com/fyne-io/fyne/issues/735 --- guiwrapper/main.go | 4 +-- guiwrapper/start_app.go | 15 ++++++---- guiwrapper/table.go | 64 +++++++++++++++++++++++++++++++++++++++++ guiwrapper/util.go | 21 -------------- 4 files changed, 75 insertions(+), 29 deletions(-) create mode 100644 guiwrapper/table.go diff --git a/guiwrapper/main.go b/guiwrapper/main.go index df016df..81d6ceb 100644 --- a/guiwrapper/main.go +++ b/guiwrapper/main.go @@ -93,7 +93,7 @@ func checkTunnelStatus() { } } else if fails >= maxRpcFails { statusLabel.SetText("Too many failures communicating with RPC server. Tunnel seems to be dead. Please restart the client.") - peersTable.SetContent(widget.NewLabel("")) + peersTableContainer.SetContent(widget.NewLabel("")) } else { fmt.Println("Failed to contact tunnel for status update") statusLabel.SetText("Tunnel seems to be inactive...") @@ -108,7 +108,7 @@ func checkTunnelStatus() { return } else { statusLabel.SetText(messages[status]) - //UpdatePeers(ctx, rpc) + UpdatePeers(ctx, rpc) } } diff --git a/guiwrapper/start_app.go b/guiwrapper/start_app.go index 8388cd9..ba513a1 100644 --- a/guiwrapper/start_app.go +++ b/guiwrapper/start_app.go @@ -20,7 +20,8 @@ import ( var spacePlaceholder = " " var statusLabel *widget.Label -var peersTable *widget.Card +var peersTableContainer *widget.Card +var peersTable = NewTable() var restartBtn *widget.Button @@ -198,8 +199,8 @@ func PromptCredentials(tabs *container.AppTabs, callback func(bool)) { func PostConnect(tabs *container.AppTabs) { statusLabel = widget.NewLabel("Opening tunnel process") statusLabel.Wrapping = fyne.TextWrapWord - peersTable = widget.NewCard("Peers", "", widget.NewVBox()) - tabs.Items[0].Content = widget.NewVBox(statusLabel, restartBtn, peersTable) + peersTableContainer = widget.NewCard("Peers", "", widget.NewVBox()) + tabs.Items[0].Content = widget.NewVBox(statusLabel, restartBtn, peersTableContainer) if len(tabs.Items) > 1 { tabs.RemoveIndex(1) } @@ -209,7 +210,7 @@ func PostConnect(tabs *container.AppTabs) { func UpdatePeers(ctx context.Context, rpc wgrpc.WGServiceClient) { peers, err := rpc.GetPeers(ctx, &wgrpc.PeersRequest{}) if err != nil { - peersTable.SetContent(widget.NewLabel("Failed to obtain peers from local wireguard server: " + err.Error())) + peersTableContainer.SetContent(widget.NewLabel("Failed to obtain peers from local wireguard server: " + err.Error())) return } @@ -222,8 +223,10 @@ func UpdatePeers(ctx context.Context, rpc wgrpc.WGServiceClient) { peersInfos = append(peersInfos, []string{peer.Hostname, peer.IpAddress, peer.Status}) } - peersTable.SetContent(makeTable( + peersTable.Update( []string{"Host", "IP address", "State"}, peersInfos, - )) + ) + + peersTableContainer.SetContent(peersTable.GetContainer()) } diff --git a/guiwrapper/table.go b/guiwrapper/table.go new file mode 100644 index 0000000..859ee79 --- /dev/null +++ b/guiwrapper/table.go @@ -0,0 +1,64 @@ +package main + +import ( + "fyne.io/fyne" + "fyne.io/fyne/container" + "fyne.io/fyne/widget" +) + +type Table struct { + columnsRows [][]*widget.Label + columns []*fyne.Container + container *fyne.Container +} + +func NewTable() *Table { + return &Table{columnsRows: [][]*widget.Label{}, columns: []*fyne.Container{}} +} + +func (t *Table) Update(headings []string, rows [][]string) { + columnsData := rowsToColumns(headings, rows) + for i, col := range columnsData { + if len(t.columnsRows) <= i { + t.columnsRows = append(t.columnsRows, []*widget.Label{}) + } + row := t.columnsRows[i] + columnData := append([]string{headings[i]}, col...) + for j, elem := range columnData { + if len(row) <= j { + row = append(row, widget.NewLabel(elem)) + } + row[j].Text = elem + } + t.columnsRows[i] = row + + if len(t.columns) <= i { + t.columns = append(t.columns, container.NewGridWithColumns(1, []fyne.CanvasObject{}...)) + } + + objects := []fyne.CanvasObject{} + for _, o := range t.columnsRows[i] { + objects = append(objects, o) + } + + column := t.columns[i] + column.Objects = objects + column.Refresh() + } + + objects := []fyne.CanvasObject{} + for _, o := range t.columns { + objects = append(objects, o) + } + + if t.container == nil { + t.container = container.NewHBox(objects...) + } else { + t.container.Objects = objects + t.container.Refresh() + } +} + +func (t *Table) GetContainer() *fyne.Container { + return t.container +} diff --git a/guiwrapper/util.go b/guiwrapper/util.go index 83e6b05..088fa56 100644 --- a/guiwrapper/util.go +++ b/guiwrapper/util.go @@ -1,26 +1,5 @@ package main -import ( - "fyne.io/fyne" - "fyne.io/fyne/container" - "fyne.io/fyne/widget" -) - -func makeTable(headings []string, rows [][]string) *fyne.Container { - columns := rowsToColumns(headings, rows) - objects := []fyne.CanvasObject{} - for i, col := range columns { - elems := []fyne.CanvasObject{ - widget.NewLabelWithStyle(headings[i], fyne.TextAlignLeading, fyne.TextStyle{Bold: true}), - } - for _, elem := range col { - elems = append(elems, widget.NewLabel(elem)) - } - objects = append(objects, container.NewGridWithColumns(1, elems...)) - } - return container.NewHBox(objects...) -} - func rowsToColumns(headings []string, rows [][]string) [][]string { columns := make([][]string, len(headings)) for _, row := range rows {