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

internal/ui: update to new Libadwaita widgets and fix a bug with Mullvad node sorting #121

Merged
merged 6 commits into from
Jun 21, 2024
Merged
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
6 changes: 6 additions & 0 deletions dev.deedles.Trayscale.metainfo.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@
<content_rating type="oars-1.1" />

<releases>
<release version="v0.12.4" date="2024-06-21">
<description>
<ul>Update to use new Libadwaita widgets.</ul>
<ul>Fix a bug with ordering of Mullvad nodes.</ul>
</description>
</release>
<release version="v0.12.3" date="2024-05-04">
<description>
<ul>Fix self and Mullvad pages disappearing when re-opening the window.</ul>
Expand Down
13 changes: 13 additions & 0 deletions internal/tsutil/tsutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,16 @@ func CompareLocations(loc1, loc2 *tailcfg.Location) int {
cmp.Compare(loc1.City, loc2.City),
)
}

// ComparePeers compares two peers. It does so by location if
// available or hostname if not. It returns the peers in a
// deterministic order if their locations or hostnames are identical,
// so the result of calling this is never 0. To determine if peers are
// the same, compare their IDs manually.
func ComparePeers(p1, p2 *ipnstate.PeerStatus) int {
ids := cmp.Compare(p1.ID, p2.ID)
if (p1.Location == nil) || (p2.Location == nil) {
return cmp.Or(cmp.Compare(p1.HostName, p2.HostName), ids)
}
return cmp.Or(CompareLocations(p1.Location, p2.Location), ids)
}
6 changes: 3 additions & 3 deletions internal/ui/mainwindow.ui
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.17.2 -->
<!-- Created with Cambalache 0.91.1 -->
<interface>
<!-- interface-name mainwindow.ui -->
<requires lib="gtk" version="4.12"/>
Expand All @@ -13,7 +13,7 @@
<property name="width-request">200</property>
<child>
<object class="AdwBreakpoint">
<!-- Custom fragments -->
<!-- Custom object fragments -->
<condition>max-width: 400sp</condition>
<setter object="SplitView" property="collapsed">True</setter>
</object>
Expand Down Expand Up @@ -67,7 +67,7 @@
<object class="GtkMenuButton" id="MainMenuButton">
<property name="icon-name">open-menu-symbolic</property>
<property name="primary">True</property>
<!-- Custom fragments -->
<!-- Custom object fragments -->
<property name="menu-model">MainMenu</property>
</object>
</child>
Expand Down
33 changes: 14 additions & 19 deletions internal/ui/mullvadpage.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package ui

import (
"cmp"
"context"
_ "embed"
"fmt"
Expand Down Expand Up @@ -55,17 +54,15 @@ func (page *MullvadPage) init(a *App, status tsutil.Status) {
row := exitNodeRow{
peer: peer,

w: adw.NewActionRow(),
r: gtk.NewSwitch(),
w: adw.NewSwitchRow(),
}

row.w.AddSuffix(row.r)
row.w.SetTitle(mullvadExitNodeName(peer))

row.r.SetMarginTop(12)
row.r.SetMarginBottom(12)
row.r.ConnectStateSet(func(s bool) bool {
if s == row.r.State() {
row.r().SetMarginTop(12)
row.r().SetMarginBottom(12)
row.r().ConnectStateSet(func(s bool) bool {
if s == row.r().State() {
return false
}

Expand All @@ -84,7 +81,7 @@ func (page *MullvadPage) init(a *App, status tsutil.Status) {
err := a.TS.ExitNode(context.TODO(), node)
if err != nil {
slog.Error("set exit node", "err", err)
row.r.SetActive(!s)
row.r().SetActive(!s)
return true
}
a.poller.Poll() <- struct{}{}
Expand Down Expand Up @@ -112,30 +109,28 @@ func (page *MullvadPage) Update(a *App, peer *ipnstate.PeerStatus, status tsutil
}
}
}
slices.SortFunc(nodes, func(p1, p2 *ipnstate.PeerStatus) int {
if (p1.Location == nil) || (p2.Location == nil) {
return cmp.Compare(p1.HostName, p2.HostName)
}
return tsutil.CompareLocations(p1.Location, p2.Location)
})
slices.SortFunc(nodes, tsutil.ComparePeers)

page.exitNodeRows.Update(nodes)
}

type exitNodeRow struct {
peer *ipnstate.PeerStatus

w *adw.ActionRow
r *gtk.Switch
w *adw.SwitchRow
}

func (row *exitNodeRow) r() *gtk.Switch {
return row.w.ActivatableWidget().(*gtk.Switch)
}

func (row *exitNodeRow) Update(peer *ipnstate.PeerStatus) {
row.peer = peer

row.w.SetTitle(mullvadExitNodeName(peer))

row.r.SetState(peer.ExitNode)
row.r.SetActive(peer.ExitNode)
row.r().SetState(peer.ExitNode)
row.r().SetActive(peer.ExitNode)
}

func (row *exitNodeRow) Widget() gtk.Widgetter {
Expand Down
2 changes: 1 addition & 1 deletion internal/ui/mullvadpage.ui
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.17.2 -->
<!-- Created with Cambalache 0.91.1 -->
<interface>
<requires lib="gtk" version="4.12"/>
<requires lib="libadwaita" version="1.0"/>
Expand Down
13 changes: 6 additions & 7 deletions internal/ui/peerpage.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ type PeerPage struct {
PreferredDERP *gtk.Label
DERPLatencies *adw.ExpanderRow
MiscGroup *adw.PreferencesGroup
ExitNodeRow *adw.ActionRow
ExitNodeSwitch *gtk.Switch
ExitNodeRow *adw.SwitchRow
OnlineRow *adw.ActionRow
Online *gtk.Image
LastSeenRow *adw.ActionRow
Expand Down Expand Up @@ -186,8 +185,8 @@ func (page *PeerPage) init(a *App, peer *ipnstate.PeerStatus, status tsutil.Stat
return &row
}

page.ExitNodeSwitch.ConnectStateSet(func(s bool) bool {
if s == page.ExitNodeSwitch.State() {
page.ExitNodeRow.ActivatableWidget().(*gtk.Switch).ConnectStateSet(func(s bool) bool {
if s == page.ExitNodeRow.ActivatableWidget().(*gtk.Switch).State() {
return false
}

Expand All @@ -206,7 +205,7 @@ func (page *PeerPage) init(a *App, peer *ipnstate.PeerStatus, status tsutil.Stat
err := a.TS.ExitNode(context.TODO(), node)
if err != nil {
slog.Error("set exit node", "err", err)
page.ExitNodeSwitch.SetActive(!s)
page.ExitNodeRow.ActivatableWidget().(*gtk.Switch).SetActive(!s)
return true
}
a.poller.Poll() <- struct{}{}
Expand Down Expand Up @@ -242,8 +241,8 @@ func (page *PeerPage) Update(a *App, peer *ipnstate.PeerStatus, status tsutil.St
page.routeRows.Update(eroutes)

page.ExitNodeRow.SetVisible(peer.ExitNodeOption)
page.ExitNodeSwitch.SetState(peer.ExitNode)
page.ExitNodeSwitch.SetActive(peer.ExitNode)
page.ExitNodeRow.ActivatableWidget().(*gtk.Switch).SetState(peer.ExitNode)
page.ExitNodeRow.ActivatableWidget().(*gtk.Switch).SetActive(peer.ExitNode)
page.RxBytes.SetText(strconv.FormatInt(peer.RxBytes, 10))
page.TxBytes.SetText(strconv.FormatInt(peer.TxBytes, 10))
page.Created.SetText(formatTime(peer.Created))
Expand Down
13 changes: 3 additions & 10 deletions internal/ui/peerpage.ui
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.17.2 -->
<!-- Created with Cambalache 0.91.1 -->
<interface>
<requires lib="gtk" version="4.12"/>
<requires lib="libadwaita" version="1.3"/>
<requires lib="libadwaita" version="1.4"/>
<object class="AdwStatusPage" id="Page">
<child>
<object class="AdwClamp">
Expand Down Expand Up @@ -45,15 +45,8 @@
<object class="AdwPreferencesGroup" id="MiscGroup">
<property name="title">Misc.</property>
<child>
<object class="AdwActionRow" id="ExitNodeRow">
<property name="activatable-widget">ExitNodeSwitch</property>
<object class="AdwSwitchRow" id="ExitNodeRow">
<property name="title">Use as exit node</property>
<child>
<object class="GtkSwitch" id="ExitNodeSwitch">
<property name="margin-bottom">12</property>
<property name="margin-top">12</property>
</object>
</child>
</object>
</child>
<child>
Expand Down
6 changes: 2 additions & 4 deletions internal/ui/preferences.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@ var preferencesXML string
type PreferencesWindow struct {
*adw.PreferencesWindow `gtk:"PreferencesWindow"`

UseTrayIconRow *adw.ActionRow
UseTrayIcon *gtk.Switch
PollingIntervalRow *adw.ActionRow
PollingInterval *gtk.SpinButton
UseTrayIconRow *adw.SwitchRow
PollingIntervalRow *adw.SpinRow
PollingIntervalAdjustment *gtk.Adjustment
ControlURLRow *adw.EntryRow
}
Expand Down
35 changes: 12 additions & 23 deletions internal/ui/preferences.ui
Original file line number Diff line number Diff line change
@@ -1,37 +1,32 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.17.2 -->
<!-- Created with Cambalache 0.91.1 -->
<interface>
<requires lib="gtk" version="4.0"/>
<requires lib="libadwaita" version="1.3"/>
<requires lib="libadwaita" version="1.4"/>
<object class="AdwPreferencesWindow" id="PreferencesWindow">
<child>
<object class="AdwPreferencesPage">
<child>
<object class="AdwPreferencesGroup">
<property name="title">General</property>
<child>
<object class="AdwActionRow" id="UseTrayIconRow">
<object class="AdwSwitchRow" id="UseTrayIconRow">
<property name="subtitle">If enabled, an icon will be added to the system tray</property>
<property name="title">Use Tray Icon</property>
<child>
<object class="GtkSwitch" id="UseTrayIcon">
<property name="margin-bottom">12</property>
<property name="margin-top">12</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow" id="PollingIntervalRow">
<object class="AdwSpinRow" id="PollingIntervalRow">
<property name="adjustment">
<object class="GtkAdjustment" id="PollingIntervalAdjustment">
<property name="lower">0.5</property>
<property name="step-increment">1.0</property>
<property name="upper">100.0</property>
<property name="value">5.0</property>
</object>
</property>
<property name="subtitle">Interval, in seconds, at which to poll the Tailscale daemon</property>
<property name="title">Polling Interval</property>
<child>
<object class="GtkSpinButton" id="PollingInterval">
<property name="adjustment">PollingIntervalAdjustment</property>
<property name="margin-bottom">12</property>
<property name="margin-top">12</property>
</object>
</child>
</object>
</child>
</object>
Expand All @@ -50,10 +45,4 @@
</object>
</child>
</object>
<object class="GtkAdjustment" id="PollingIntervalAdjustment">
<property name="lower">0.5</property>
<property name="step-increment">1.0</property>
<property name="upper">100.0</property>
<property name="value">5.0</property>
</object>
</interface>
Loading