Skip to content

master 追従 2026-08-31 - #3

Open
github-actions[bot] wants to merge 44 commits into
PonPilotfrom
master
Open

master 追従 2026-08-31#3
github-actions[bot] wants to merge 44 commits into
PonPilotfrom
master

Conversation

@github-actions

Copy link
Copy Markdown

No description provided.

elkoled and others added 30 commits August 26, 2026 15:20
chestnut: rename eGPU interfaces
* chestnut stats: overlap with gpu work

* ci

---------

Co-authored-by: elkoled <elkoled@gmail.com>
ui: unify chestnut status presentation
* ui: remove raygui usage

* match previous gui_text_box line spacing

* Revert "match previous gui_text_box line spacing"

This reverts commit ffd2fe3.

* Reapply "match previous gui_text_box line spacing"

This reverts commit d41404f.
* log chestnut INA supply fault

* ci
cabana: split SettingsDialog out of settings.{h,cc}
* system: add chestnut offroad alerts

* system: refine chestnut offroad alerts

* system: refine chestnut power alerts

* system: confirm chestnut power recovery from PCIe

* system: detect missing chestnut power from INA voltage
The destructor built its cleanup commands as "rm %s -rf", with the flags
after the operand. GNU rm permutes arguments so this works on device and
in CI, but BSD rm on macOS stops option parsing at the first operand and
treats "-rf" as a second filename:

  $ mkdir -p /tmp/rmtest/sub && rm /tmp/rmtest -rf
  rm: /tmp/rmtest: is a directory
  rm: -rf: No such file or directory
  exit=1

So nothing is removed, and each of the four calls prints two errors plus
"system command failed (256)" from check_system. Every run of a tool that
owns an OpenpilotPrefix (replay, cabana) leaks its params dir, its
comma_home and its /tmp/msgq_ dir; 33 of each had accumulated on my
machine.

Pass the flags first.
pandad: support compact health packet
* mici: name updater signal constants

* drop SIGNAL_ prefix

* self contained

---------

Co-authored-by: Shane Smiskol <shane@smiskol.com>
E.118 specifies decimal digits, but many real SIMs carry hex characters
in EF_ICCID (e.g. China Mobile's 898600B5... range, some MVNO/IoT SIMs).
AT+QCCID returns them verbatim, and the strict isdigit() check blanked
the ICCID, leaving the modem daemon stuck in INITIALIZING forever and
cellular dead. ModemManager parses ICCID as hex for the same reason.

Verified on a comma four with a China Mobile SIM (EG916Q-GL): previously
stuck retrying 'identity read incomplete', now dials and passes traffic.
* 23e6a04e-e6e5-462b-a0bb-e4088275ee43/12864 tgc

* here
elkoled and others added 14 commits September 1, 2026 05:59
hardwared: monitor chestnut USB independently
modeld: wait for stable chestnut
* modeld: fuse warp and policy TinyJit

* bump tg

* fix?

* this simple trick...

* debug 1

* bump tg

* pack all

* wips

* fix

* BIG_INTO_SMALL remove

* slower
* ui: show USB status

* ui: resize USB icon

* ui: classify USB device once

* ui: debounce USB disconnect
ui: show one GPU status icon
* cabana: imgui frontend base infra (ui/)

* cabana: line-for-line imgui ports of the Qt widgets and dialogs into ui/

* cabana ui: fixes from the side by side parity test

* cabana ui: deqt.md status after the line-for-line ports

* cabana ui: fixes from the line-for-line review

* cabana ui: parity fixes from the end to end matrix, event driven frame pacing

* cabana ui: preserve F1 help formatting

* cabana ui: parity fixes from the end to end matrix, event driven frame pacing

* cabana ui: deqt.md status

* cabana: fix macOS build of imgui frontend

- link Security.framework (libusb's darwin backend needs
  SecTaskCreateFromSelf/SecTaskCopyValueForEntitlement)
- drop unused loop counter in SignalView::updateChartState
- avoid -Wshadow on Sparkline::size and SignalView::highlight

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: parity round 3 fixes, thread pool and one malloc arena for flat memory

* cabana ui: toolbar overflow budget, menu button carets, help overlay colors, signal editor validation

* cabana ui: deqt.md status

* cabana: let vsync pace the frame loop

The loop threw away frames with glfwWaitEventsTimeout() to hit a 30fps
(10fps idle) target while glfwSwapBuffers() was already blocking on
vsync, so two clocks beat against each other. Input events also reset
frameInterval() to 0 for a few frames, so a click swung the cadence from
~33ms to ~13ms and back -- the camera view redraws on the UI's schedule,
so that showed up as a visible hitch on every message selection.

Poll and draw every iteration and let glfwSwapInterval(1) do the pacing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana: fix macOS build of thread pool / malloc arena changes

- malloc.h and mallopt(M_ARENA_MAX) are glibc only; guard on __GLIBC__.
  macOS has a single allocator zone, so there is nothing to cap.
- capturing structured bindings in a lambda is a C++20 extension and
  clang rejects it under -Werror; bind the event range to plain locals.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: chart axis label precision, signal list click on empty space clears the selection

* cabana ui: codespell

* cabana ui: taller signal rows, system theme detection, full dark palette

- signal rows are 1.5x a frame tall with the sparkline sized to the row,
  so the graphs are readable. The expanded sub-rows keep the Qt height.
- "Automatic" resolved to the light theme regardless of the system: Qt
  gets this from QStyle::standardPalette(), which follows the macOS
  appearance, so read AppleInterfaceStyle and match it. Other platforms
  stay light, like standardPalette() does there.
- widgets that tested settings.theme == DARK_THEME themselves went light
  under AUTO_THEME while the style went dark; they now ask isDarkTheme()
  for the theme applyTheme() actually resolved.
- the dark branch only set 10 ImGuiCol_ entries, so buttons, scrollbars,
  tabs, title bars, separators, tables and grips still came from imgui's
  stock dark theme. Derive the whole palette from DarkTheme instead.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: drop the dead y axis alignment chain and chart cache stub

ImPlot::BeginAlignedPlots aligns the chart y axes, so the hand-rolled
alignment protocol ported from Qt no longer feeds anything: align_to was
write-only. Remove the whole chain (y_label_width and its measuring loop
in draw(), axisYLabelWidthChanged, align_timer, alignCharts), which
reduces updatePlotArea(int, bool) to updatePlotArea().

resetChartCache() has been an empty stub since the port (imgui redraws
every frame); drop it and its four call sites. Also replace the empty
move_icon_rect branch in mousePressEvent with an early return.

No behavior change. updateAxisY's "|| y_label_width == 0" guard only
fired after a unit change, and y_precision/y_tick_count depend solely on
min_y/max_y/tick_count, so the recompute it triggered was a no-op.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: stop the main window from scrolling

The host window that holds the dockspace uses zero WindowPadding but the
default ItemSpacing, so the dockspace and the status bar below it summed
to ItemSpacing.y (5px) more than the viewport, leaving the whole UI
scrollable by a few pixels.

Reserve the spacing along with the status bar height, and mark the host
window NoScrollbar/NoScrollWithMouse: it is pinned to the viewport work
area and should never scroll, as QMainWindow does not. Full screen is
unaffected, it draws no status bar and reserves no height.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: inset the status bar so its ends are not clipped

A borderless BeginChild gets WindowPadding forced to zero, so the status
bar text sat flush against both edges and the first glyph of "For Help,
Press F1" was cut off. Inset both ends by WindowPadding.x, which lines
the text up with the content of the docked panels above it.

Right align the cached minutes / FPS label to the captured child width
rather than calling GetContentRegionAvail() again after the message
text, which only returned the full width because the text had already
wrapped the cursor to a new line.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: drop the leftover imgui object census log

The block printed an imgui/implot object count to stderr every 10s,
which was instrumentation for tracking down a leak, not something the
port needs. It was the only user of implot_internal.h in mainwin.cc, so
drop that include with it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: keep the selected row highlighted while hovered

Selectable() picks its background as HeaderActive when held, else
HeaderHovered when hovered, else Header. The hovered test comes before
the selected one, so a selected row under the cursor takes the hover
color. Both tables push a transparent HeaderHovered to suppress the hover
highlight that QTreeView/QTableView do not have, which also blanked the
selection: clicking a row walked press (HeaderActive, visible), release
(HeaderHovered, transparent, looks unselected), then mouse off the row
(Header, visible), so the selection appeared to flicker until the cursor
moved away.

Only make HeaderHovered transparent for rows that are not selected.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: draw the binary view hex column in bold and in the text color

The Qt delegate never sets a pen for the hex column, so it inherited the
black QPainter default and the two halves of a row did not match. Use
paletteText(is_message_active), the same color the bit columns use, so
both halves read as one row and dim together when the message goes
inactive.

JetBrains Mono ships no bold variant and imgui has no embolden option, so
give drawStaticText a bold flag that redraws the glyphs a fraction of a
pixel to the right. That keeps the monospace advance, which switching to
the proportional bold face would not.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: highlight the whole row in the speed menu

MenuItem spans from the cursor to the right edge, so the Indent() that
made room for the radio bullet also pushed the highlight in by one
FontSize and left the bullet column outside it. QMenu highlights the
whole item, indicator included.

Draw each row as one full width Selectable with the bullet and the label
inside it. Every row declares the same width, so the popup is as wide as
the widest entry and the highlights reach both edges; a label-less
Selectable sized zero would declare no layout width and collapse the
auto-sizing popup. Selectable auto-closes its parent popup like MenuItem
does, so clicking still works in the dropdown and in the Speed submenu of
the toolbar overflow menu, which shares this function.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: fix help menu overlay, Ctrl+F11, time label clipping, toolbar overflow and tool table parity

* cabana ui: click to edit signal cells, light theme selection, logs cell selection and filter fixes

* cabana ui: chart x label margin, zoom context menu items, video splitter collapse, signal editor close

* cabana ui: signal editor lifetime and close, logs cell hover, tool table headers

* cabana ui: branch indicator clicks, editor swallows shortcut and button clicks, selection colors

* cabana ui: float dock windows into real OS windows

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: toolbar menu arrow spacing, only open the editor on editable cells

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* op: add cabana2 to run the imgui cabana

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana: cabana2 launcher script builds _cabana_ui before running it

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: only float the dock panels into their own OS windows

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: open the video pane at the camera's natural aspect ratio

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana: default fps to 30

* cabana ui: fusion palette, shared fusion slider, chart grid colors

* cabana ui: smaller checkbox indicator, closer to the Fusion size

* cabana ui: video toolbar height and item centering, separator extent and menu arrow like Fusion

* cabana ui: message and signal row heights match Qt

* cabana ui: timeline slider height, groove and stacking match the Qt video layout

* cabana ui: fix crash opening a live stream, the video pane default height read the missing camera widget

* cabana: drop the FPS setting, the streams update the UI at a fixed 30 fps

* cabana ui: video and charts pane run edge to edge with a uniform toolbar margin like the Qt frames

* cabana ui: binary view M/L marker size and timeline event fills match Qt

* cabana ui: signal view keeps its sparklines while filtering, number label size matches Qt

* cabana ui: no modal dim fade, QDialog does not animate in

* cabana ui: collapse all is an auto-raise tool button with the Qt icon size

* cabana ui: dialogs and tool windows open as real OS windows like QDialog

* cabana ui: hold back a focus loss while a mouse button is down so tearing a panel off does not abort the drag and create its window twice

* cabana ui: speed menu rows pad the label on the right like QMenu

* cabana ui: raise the dark theme contrast, the Darcula grays all sat on top of the background

the chart y axis guides are opaque and 2 px in dark mode, and text, outlines,
separators, table borders, scrollbar and slider grabs move away from the window
and base grays. light theme is unchanged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: simplify comments, drop the Qt references and the ones that only restate the code

* cabana ui: keep the sparkline antialiased, thin peaks sparkled as the window slid

Qt dropped antialiasing above 500 points because it rasterized into a pixmap. drawing
straight into the frame, an aliased 1 px segment between two columns rounds into one of
them and the rounding flips as the window advances, so the peaks of the dense signals
popped between columns. updateState runs at STREAM_UPDATE_FPS, which at a 30s range moves
the curve well under a pixel per update, so the flip is all that is visible.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: anchor the sparkline to the time window, it jittered sideways as samples expired

x was measured from the first sample still inside the window, which changes whenever the
oldest one falls out, so every update slid the whole curve sideways by the sample spacing.
measuring from the start of the window pins the right edge and lets the samples flow left
with the clock. the density heuristic wanted the data span, which is no longer the x of the
last point, and the flat line started at x 0 instead of at its first sample.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: scroll the sparkline at the frame rate, it stepped at the message rate

the window ended at the last message of the id and updateState only runs when one arrives,
so a slow message held the sparkline still for several frames and then jumped it. the window
now ends at the playback clock, and draw() slides the rendered polyline by the time that has
passed since it was built, clipped to the cell.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: keep the signal value on the right of the column before there is a sparkline

it was drawn left aligned from the start of the column, so the value sat next to the name
until the first samples arrived and then jumped across the row.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: read a little past the sparkline window so the oldest points slide out of it

a sample used to disappear the moment it aged out, which on a fixed rate signal is a point
popping off the left edge. the query reaches back a bit further and the clip rect hides it
instead. the lead in must not move the scale, so it is left out of the min and max.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: use the macOS fullscreen space, taking over the monitor rendered at the old size

glfwSetWindowMonitor switched the display mode and returned a drawable at that mode, so the
ui was rendered at the windowed size and stretched over the screen. NSWindow toggleFullScreen
keeps the backing scale. the green button goes through the same space, so the state is read
back from the style mask rather than tracked.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: let the signal value column shrink again, it held the widest value ever seen

max_value_width only ever grew, so one long value left the sparklines ending
well short of the text for the rest of the message. Track the current widest
value instead, growing on demand and giving room back once it is a couple of
characters too wide, which keeps the width from jittering per sample.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: make the signal rows a quarter taller so the sparklines read better

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: lift the binary view heatmap alphas in dark mode, the tints washed out

The alphas were tuned against a white background; over the dark base the same
values left the cells barely colored. The floor comes up and the ramp gets a
gamma in dark mode only, which keeps the flip counts in the same order.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: saturate the sparkline color in light mode, the pastel lines vanished

Signal colors are low saturation and high value, which is aimed at dark fills;
a 1 px line of one of them on white is hard to see. Draw the sparkline with
twice the saturation and less value when the theme is light.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: give the docked panels a minimum width, the dividers ran over content

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* replay: capture the downloader's stderr so the progress lines reach the handler

file_downloader.py writes PROGRESS:<cur>:<total> to stderr while it streams a
file, but runPython() only piped stdout and left stderr attached to the parent,
so the progress handler only ever fired on failure and cabana downloaded a
segment with no progress bar. Pipe stderr as well, turn the PROGRESS lines into
handler calls, and pass everything else through to the parent's stderr.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* replay: read the downloader's stderr on a thread, the two fd select was overkill

getline() handles the line splitting, partial lines and EOF, so the manual
splitter, the second drain loop and the multiplexing bookkeeping go away and
the stdout loop goes back to what it was.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: one toolButton helper in imgui_util.h

* cabana ui: one toImU32/toImVec4/paletteBrightText in imgui_util.h

* cabana ui: string helpers live in utils/strings.h

* cabana ui: share the fusion slider handle from imgui_util.h

* cabana ui: style.cc declarations move to imgui_util.h

* cabana ui: validatedInput and the qt validators move to imgui_util.h

* cabana ui: viewSelectable helper for the item view rows

* cabana ui: drop the comboBox pass-through

* cabana ui: tabbar moves to its own file, ready for the charts port

* cabana ui: find signal searches on the main thread again, deferred one frame like QTimer::singleShot(0)

* cabana ui: find signal computes its button and label state from the model instead of caching it

* cabana ui: share the queued popup owner protocol between the message box and the file dialog

* cabana ui: one beginDialog helper for the three centered modals, with the reopen recovery

* cabana ui: tool dialogs share the title, begin/end and escape handling, and own their connections

* cabana ui: comboBox helper replaces the hand rolled zero separated item buffers

* cabana ui: drop the unused dialog isOpen accessors

* cabana ui: one validatedText helper for the ip, double and int line edits

* cabana ui: route info reads the route segments instead of caching a row copy

* cabana ui: settings drops the phantom fps label, the constant spin flags and the raw log path buffer

* cabana ui: find similar bits drops the no-op find button disable and the address round trip

* cabana ui: message box warning overload without the empty detailed text

* cabana ui: help overlay only collects rects while it is up, skips torn off panels, and the fingerprint compare is ordered

* cabana ui: drop the glfw callbacks that only forward to the imgui backend, which already installs them

* cabana ui: elided label renders with RenderTextEllipsis instead of a paint time cache

* cabana ui: one save loop, inline cached minutes label, and drop the dead help parser branches

* cabana ui: signal cell bands are built from the two corner notches instead of a region sweep

* cabana ui: binary view items go through itemAt and updateItem assigns unconditionally

* cabana ui: message bytes read the cell padding inline and colored bytes keep the qt default pen

* cabana ui: detail widget drops createToolBar, the welcome widget flag and the unused whatsThis

* cabana ui: messages widget owns its view, header and model directly, fixed size filter editors, from_chars range parsing

* cabana ui: colored hex bytes keep the row pen, the qt delegate does not reset it per cell

* cabana ui: closeEditor drops the queued commit, its item is about to be deleted

* cabana ui: rowsInserted carries the insert position so the selected row follows its message

* cabana ui: the log filter and the message name editors use the shared validators

* cabana ui: the log header sizing and painting are free functions, no HeaderView object

* cabana ui: the visible row range is the change detector, no mirrored scroll position

* cabana ui: the line editor takes the focus flag as an argument and lets InputText revert on escape

* cabana ui: signal view drops the unreachable column parameters, unused item values and repeated sparkline tests

* cabana ui: rows outside the tree viewport are measured but not painted

* cabana ui: one toolbar item table, playback state read in draw()

* cabana ui: draw the stored thumbnail scaled by AddImage, no cpu prescaled copy

* cabana ui: one radioMenuItem helper for the speed and series type menus

* cabana ui: drop dead camera members, hoist the jpeg colour space branch, decode qlog thumbnails on the thread pool

* cabana ui: stop the vipc thread when the splitter collapses the video pane

* cabana ui: the toolbar strings and enabled state are computed in drawToolBar

* cabana ui: chartswidget uses the shared tabbar widget

* cabana ui: the chart header layout is recomputed in resizeEvent, no updateTitle

* cabana ui: updateLayout has no force flag

* cabana ui: one condition hides the value tip

* cabana ui: signal selector uses the shared dialog buttons and row indexes

* cabana ui: the chart tile geometry is one Layout struct saved and restored by drawGhost

* cabana ui: drop the empty theme branch, the unused size hint and the charts container indirections

* cabana ui: the chart holds its tip label by value

* cabana ui: one toolbar item list for both toolbar groups

* cabana ui: the sparkline polyline is emitted through the draw list path

* cabana ui: the tab bar latches a programmatic selection and defers the close request past EndTabBar

* cabana ui: validatedText refuses an invalid edit inside the imgui buffer and the ip field keeps its char filter

* cabana ui: drop the ambiguous three argument warning overload

* cabana ui: combobox reports a real change, menu rows span the popup, one popup protocol for the dialogs

* cabana ui: the startup stream is owned by the window until the first frame opens it

* cabana ui: the slider toolbar index has an out of range sentinel

* cabana ui: the find signal search runs on the frame after the pending state is painted

* cabana ui: the log clears its selection when the rows are dropped and cells are identified by their message

* cabana ui: the open editor survives a scroll, collapse all commits it and escape in the size editor does not

* cabana ui: the header display order is filled with iota

* cabana ui: qlog thumbnails decode on their own threads, the hover thumbnail is mipmapped and the time tooltip appears on the first toggle

* cabana ui: a collapsed video dock stops the vipc thread

* cabana ui: one TOOLBAR_ITEM_SPACING, the signal view used the QCommonStyle 4 instead of Fusion's 1

* cabana ui: sparkline includes imgui_util.h for isDarkTheme

* cabana ui: imgui_util.h becomes util.h and util.cc

* cabana: delete deqt.md

* cabana ui: panel min width, matching video panel padding, centered tabs

The dock panels stop shrinking at the width where the signal view tool bar
squishes instead of at a hardcoded 440. The video/charts panel keeps the
standard window padding so it lines up with the other panels, and the
Msg/Logs tabs are centered in their bar. The cached minutes label is gone
from the status bar.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: persist imgui state in cabana.json and migrate the Qt frontend's layout blobs

* cabana ui: 2px sparkline stroke

a 1px antialiased line is all fringe and no solid core, so the curve
faded and shimmered as the window scrolled.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana: drop the Automatic color theme

it only did anything on macOS: the Qt frontend fell through to
standardPalette() for both Automatic and Light, so the two were
identical everywhere else.

LIGHT_THEME and DARK_THEME keep their values so a persisted dark theme
still reads as dark; the old Automatic 0 falls back to light on load.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: window color between the binary and signal views, fixed split

the binary view sits at its size hint and no longer resizes, and the gap
below it takes the window color instead of leaving a white seam.

also border the video and chart panels like the signal view.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: bigger tab bar scroll buttons

imgui's built in scroll arrows are fixed at FontSize - 2 wide with the
glyph drawn in a FontSize box, so they are small and sit off center.
draw chevron buttons at the frame height instead, spaced and disabled at
the ends of the scroll range like the rest of the tool buttons.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* cabana ui: 1.5px sparkline stroke

* cabana ui: stable sparkline scrolling, one sample per column, aliased spikes

Scroll the polyline by whole physical pixels with each sample's subpixel
phase fixed to its timestamp, thin to one sample per pixel column, and
draw near-vertical segments aliased so spikes stay crisp while smooth
curves keep antialiasing.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* cabana ui: fix spelling

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* cabana ui: size the value column for the widest value a signal can produce

Sizing it to the values in the last message moved the sparklines every
time a value changed length.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* cabana ui: center the tab bar scroll chevrons and give the buttons a frame

The icon font glyph sits off center in its padded advance, so the
chevron is drawn in the button rect. The buttons take the theme's
button background and border like the tool buttons next to them.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* cabana ui: darker grid lines between table cells

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* cabana ui: the gap between the video and the charts matches the side padding

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* cabana ui: plus-square icon for the new chart button, like the remove all button

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* cabana ui: video toolbar buttons as tall as the charts toolbar buttons

The buttons carried 10 px of vertical padding, so the hover rect was
much taller than the glyph and the row looked off center.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* cabana ui: the time display in the mono font at the ui font size

With proportional digits the time changed width as it ticked and the
items after it moved.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* cabana ui: closing a floated side panel docks it back, no hide tab bar button, the charts container never scrolls

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* cabana ui: the message tabs use the TabBar widget, chevron scroll buttons for both tab bars

The chevron scroll buttons move into a scrollable tab bar widget that
both use. The wheel scrolls the tabs, both tab bars get Close Other
Tabs, and the Msg tab is labeled Messages.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* cabana ui: deliver a focus loss right away on macOS, holding it back swallowed the first click in a popup

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* cabana ui: draw the remote routes dialog at the modal's level, opened inside the tab's child window it never appeared

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* cabana ui: --no-cache turns off the local route file cache, same as replay

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* cabana: parse merged segments on replay's merge thread, the parse on the main thread dropped frames on every merge while downloading

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* cabana ui: Esc leaves full screen on all platforms

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* cabana ui: an app bundle on macOS so the menu bar and the dock show Cabana

A bare binary shows its file name there. The build wraps _cabana_ui in
a minimal Cabana.app with an Info.plist and the launcher runs that.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Revert "cabana ui: an app bundle on macOS so the menu bar and the dock show Cabana"

This reverts commit 1a45540.

* cabana ui: the app menu on macOS says Cabana

A bare binary gets an info dictionary with its file name in it, which
glfw reads for the app menu. The name is set there before glfw brings
up cocoa.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* cabana ui: macapp moves into ui/util

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* cabana ui: setMacAppName lives in ui/util.cc

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* cabana ui: apply the code review

Bugs: an empty decode batch dereferenced vals.front(), the chart x comparator
took a float, reserve used capacity(), the bit text went black while resizing
a signal, byte cells under-sized non-multiple-of-8 payloads, the CAN speed
lookup read the data speed table, the export tooltip never showed while
disabled, and the thumbnail parser and the signal search joined ad-hoc
threads on the render thread. Both now run off the pool; the search fans out
over it from its own thread.

Shared helpers in ui/util: the tool bar with its overflow menu, the menu
button, modal dialog setup, Escape inside dialogButtons, drawText,
drawElidedText, color markers, alignRight, clearableInput,
disabledItemTooltip, inputTextMultiline, tableHeadersRow with the right
click, withAlpha, boldFont, the Cocoa full screen glue, the messages panel
id. utils gets hexByte, guarded and nonEmptyDBCFiles; threadpool gets
parallelFor.

The help overlay leaves mainwin.cc for its own file, the stream teardown is
one releaseStream(), the charts own their views through unique_ptr, the
find-similar-bits message list follows the source bus, the clipboard copies
every open DBC, and the Qt vestiges (event names, model API, protected
sections, restating comments, stale TODOs, mixed member naming) are gone.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* cabana ui: collapse the model/view/delegate split

The Qt-era model, view and delegate classes were ported one to one, but
imgui draws a table in one function. MessageView, MessageViewHeader and
MessageListModel's string API fold into MessagesWidget over a plain
MessageList; HistoryLogModel folds into LogsWidget; BinaryViewModel and
BinaryItemDelegate fold into BinaryView; SignalItemDelegate folds into
SignalView, and SignalModel keeps only the item tree with three predicates
instead of the flags bitmask; FindSignalModel becomes SignalSearch. The
byte cell painter is a set of free functions shared by the two tables.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* cabana ui: load the route behind the window

The route file listing is an HTTPS round trip to the comma API and took
the whole first second of startup before the window existed. The replay
branch of main() now hands run() a loader that a worker executes after
the first frame; the window maps in ~0.1 s instead of ~1 s. On a failed
load the app stays open in the No Stream state with the error box
instead of exiting before a window ever appeared.

* cabana ui: fix the live stream video controls layout

* cabana ui: only copy dbc to clipboard with a single file

* cabana ui: report route loading failures instead of hanging

* cabana: launch the imgui frontend by default, --legacy for Qt

---------

Co-authored-by: Trey Moen <trey@Treys-MacBook-Pro.local>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* cabana: remove Qt implementation
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.

6 participants