Skip to content

feat(gtk): modernize the GTK GUI - sidebar, dashboards, light/dark theme - #2379

Draft
andrut-ds wants to merge 10 commits into
pactus-project:mainfrom
andrut-ds:feat/gtk-theme-foundation
Draft

feat(gtk): modernize the GTK GUI - sidebar, dashboards, light/dark theme#2379
andrut-ds wants to merge 10 commits into
pactus-project:mainfrom
andrut-ds:feat/gtk-theme-foundation

Conversation

@andrut-ds

@andrut-ds andrut-ds commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Summary

This reworks the GTK GUI (cmd/gtk) from the legacy notebook‑tab layout into a
modern desktop app: a left navigation sidebar, dashboard‑style pages, a
cohesive theme with the official Pactus palette, and a working light/dark
toggle. Data and behaviour are unchanged — only the presentation layer and a
few platform fixes.

I have built and run it on Windows 11. It still needs testing on Linux
and macOS
before it can be merged, which is why this is a draft. All
platform‑specific code is isolated behind build tags with no‑op fallbacks, so
non‑Windows builds should be unaffected, but that needs to be verified on real
machines.

What's included

  • Theme foundation — token‑based stylesheet derived from GTK's adaptive
    named colors, so widgets follow the active theme. Official Pactus palette:
    navy #002235 (brand), green #00a085 (primary actions/accent), blue
    #217aff (navigation).
  • Light/dark toggle via the libadwaita style manager, shown as a round
    moon/sun button in the title bar. The choice is persisted and restored on the
    next launch (falls back to the system theme until the user picks one).
  • Custom title bar with the Pactus logo and app name.
  • Left sidebar navigation (Lucide line icons) driving a GtkStack, replacing
    the top notebook tabs.
  • Node Overview dashboard — metric cards (Network Health, Validator Network)
    plus a custom circular sync gauge (GtkDrawingArea + cairo) and an aligned
    "Local Node Info" definition list. The node agent string is parsed into a
    readable summary.
  • Committee, Wallet, Network and My Validators rebuilt to match: page title,
    info stat cards, and framed data tables.
  • Designed data tables — reusable column helpers remove the spreadsheet
    look: no column grid lines, a flat muted header, roomy rows with hover,
    right‑aligned numbers, and middle‑ellipsized addresses/hashes with the full
    value on hover, so tables never scroll sideways.
  • Dialog polish — flat text buttons (accent for confirm actions), padded
    content, and equal heights for entries, dropdowns and combo boxes.
  • Window placement — GTK4 cannot position windows, so the splash, dialogs
    and main window are centered natively on Windows (no‑op elsewhere). The Node
    page opens at its natural height while staying resizable.
  • English UI strings — force GTK/libadwaita built‑in widget strings (the
    assistant navigation, about dialog) to English so they match the rest of the
    interface regardless of the OS display language.
  • About dialogs — stop GtkAboutDialog from auto‑selecting (highlighting)
    the program name.

New dependencies

  • System: libadwaita (on MSYS2: mingw-w64-x86_64-libadwaita).
  • Go module: github.com/diamondburned/gotk4-adwaita.

Build unchanged otherwise: make build_gui (go build -tags gtk ./cmd/gtk).

Testing

  • Builds and runs on Windows 11 (MSYS2/mingw64, GTK 4.22).
  • Linux
  • macOS

Feedback on the direction and cross‑platform results is very welcome.

andrut-ds added 10 commits July 10, 2026 23:09
Rework the GTK GUI stylesheet into a token-based theme. Colors derive
from GTK's adaptive named colors so the UI follows the active light or
dark theme automatically, with a fixed Pactus teal accent that stays
legible on both. Adds modern tab styling with an accent underline,
rounded buttons/entries with focus rings, card-styled frames and
assistant pages, hover transitions, and a polished splash screen.
Add a custom header bar showing the Pactus logo next to the app name,
and a round moon/sun toggle beside the window buttons that switches the
appearance at runtime. Theme control now goes through the libadwaita
style manager (ColorSchemeForceLight/ForceDark), which works reliably on
Windows where gtk-application-prefer-dark-theme did not. Removes the
hard-coded dark preference at startup so the app follows the system
theme by default. Also brands progress bars, switches, checks and the
sync scale with the accent color.
Replace the flat label grid with a responsive GtkFlowBox of grouped
metric cards (Network Health, Validator Network, Local Node Info) that
reflow on narrow windows, plus a dedicated synchronization card. Add a
custom circular progress gauge (DrawingArea + cairo) that fills with the
sync percentage and shows it in the center, replacing the plain progress
bar. All original fields are preserved.
Replace the top notebook tabs with a left navigation sidebar (Lucide
SVG icons, blue active state) driving a GtkStack. Redesign the Node
Overview into a fit-to-window dashboard: metric cards for Network Health
and Validator Network, a Sync Status hero with the circular gauge, and a
tidy aligned Local Node Info definition list. Parse the node agent into a
readable summary and show the peer id in full.

Adopt the official Pactus palette (navy pactus-project#2235, green #00a085 for
primary actions and accent, blue #217aff for navigation). Flatten dialog
buttons to clean text (accent for confirm actions), pad dialog content,
and equalize the height of entries, dropdowns and combo boxes.

Center the splash, dialogs and main window natively on Windows since GTK4
cannot position windows, and open the Node page at its natural height
while keeping it resizable via a propagating scrolled window.
Replace the nested left-tab notebooks with single dashboard pages that
match the Node Overview: a page title, info stat cards, and framed data
tables. Add reusable column helpers so tables read as designed rather
than spreadsheet-like: no column grid lines, a flat muted header, roomy
rows with hover, right-aligned numbers, and middle-ellipsized addresses
and hashes with the full value on hover, so tables never scroll
sideways. The Wallet page keeps Addresses and Transactions as a padded,
card-styled tab strip with the balance stats and details above. Also
reword the sync caption to "Syncing blocks" / "Fully synced".
The interface text is English only, but GTK and libadwaita translate
their built-in widgets (assistant navigation, about dialog, file
choosers) to the operating system locale, which produced a mix of
languages. Set LANGUAGE=en before initialization so those strings stay
English too. This affects message translation only, not number or date
formatting.
Setting LANGUAGE=en is not enough on Windows: GTK and libadwaita pick
their translations from the thread UI language, so the built-in
GtkAssistant navigation buttons still appeared in the system language.
Call SetThreadUILanguage(en-US) before initialization so those strings
render in English, matching the rest of the interface.
os.Setenv writes to the Win32 environment block, which the C runtime
that GTK and libintl link against does not read, so LANGUAGE=en was
invisible to gettext and the built-in widget strings stayed in the
system language. Set the variables through g_setenv instead, which
updates the same C runtime environment GTK uses, so its assistant and
dialog strings render in English.
GtkAboutDialog gives its selectable program-name label the initial
keyboard focus, which selects the whole label and makes "Pactus" and
"GTK" look highlighted. Walk the dialog tree and make its labels
non-selectable so the name renders plainly.
The dark-mode toggle only changed the libadwaita color scheme for the
running session, so the app fell back to the system theme on the next
launch. Persist the choice to the user config directory and restore it
on startup, still following the system theme until the user picks one.
@b00f

b00f commented Jul 11, 2026

Copy link
Copy Markdown
Collaborator

This is a significant GUI change. While it's a nice improvement, it's very unlikely that we'll merge it.

@codecov

codecov Bot commented Jul 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 73.59%. Comparing base (86a8ba9) to head (3948ad3).
⚠️ Report is 500 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2379      +/-   ##
==========================================
- Coverage   75.07%   73.59%   -1.48%     
==========================================
  Files         234      299      +65     
  Lines       12156    18687    +6531     
==========================================
+ Hits         9126    13753    +4627     
- Misses       2582     4378    +1796     
- Partials      448      556     +108     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@b00f

b00f commented Jul 11, 2026

Copy link
Copy Markdown
Collaborator

@andrut-ds Please attach the screenshots for these changes.

@andrut-ds

Copy link
Copy Markdown
Contributor Author

@andrut-ds Please attach the screenshots for these changes.

@b00f Thanks for the feedback! I understand a change this large is unlikely to land as is, so I'm sharing it mainly as a direction and proposal. Screenshots below (Windows 11, GTK 4.22): Node Overview (light and dark), Committee, Network, My Validators, and Wallet.

Highlights: a left sidebar replaces the notebook tabs, a persisted light/dark toggle, a custom circular sync gauge, and restyled data tables. I'm happy to split the low-risk, self-contained pieces (native window centering on Windows, forcing English for GTK's built-in strings, and the About dialog fix) into small standalone PRs if that is more useful, and to adjust the overall direction based on your input.

01-node-light 02-node-dark 03-committee 04-network 05-my-validators 06-wallet

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