Skip to content

Polish main workspace UI density and packet detail usability#4

Merged
AlexeyVasilev merged 14 commits into
mainfrom
ui/main-workspace-polish
Jul 2, 2026
Merged

Polish main workspace UI density and packet detail usability#4
AlexeyVasilev merged 14 commits into
mainfrom
ui/main-workspace-polish

Conversation

@AlexeyVasilev

Copy link
Copy Markdown
Owner

Summary

This PR improves the main workspace UI density and usability in both the Qt UI and the experimental Tauri UI.

The main focus is the Flows workspace, where the previous layout used too much vertical and horizontal space after the recent protocol-detail expansion. The goal is not to copy Wireshark’s dense utility-first UI exactly, but to move PcapFlowLab toward a more compact, analyst-friendly workspace while keeping the interface modern and readable.

Main changes

Main Flows workspace density

  • Removed redundant large section headings where tab context already makes the area clear.
  • Reduced vertical spacing between main Flows workspace panels.
  • Tightened flow table and packet table row heights.
  • Reduced Summary card spacing and Packet Details tab spacing.
  • Preserved the current top toolbar and prominent Open Capture... action.

Flow endpoint columns

  • Replaced separate Qt columns:

    Address A | Port A | Address B | Port B
    

    with compact endpoint columns:

    Endpoint A | Endpoint B
    
  • Updated Qt and Tauri endpoint formatting to show address and port as a compact cluster.

  • Added clearer separation between address and port while keeping them visually grouped.

  • Added IPv6 bracket formatting when a port is present:

    [2001:db8::10] : 443
    
  • Avoids misleading : 0 output when a port is missing or invalid.

Lower Packets / Stream panel

  • Combined the lower Packets / Stream tabs, packet status text, and Load More button into one compact toolbar-style row.
  • Applied this layout first in Tauri, then mirrored it in the Qt UI.
  • Preserved existing packet loading, stream switching, selection, and Load More behavior.

Tabs and spacing polish

  • Slightly reduced the height of the main Flows / Analysis / Statistics tabs.
  • Slightly reduced the height of Packet Details tabs such as Summary, Raw, Payload, and Protocol.
  • Removed unnecessary empty vertical space below Packet Details tabs before the first Summary layer.

Qt Packet Details copyability

  • Made Qt Packet Details Summary text selectable/copyable.
  • Layer titles, field names, field values, warning text, and Summary preview text can now be selected and copied.
  • Preserved expand/collapse behavior through the existing disclosure controls.
  • Raw, Payload, and Protocol tabs were intentionally left unchanged in this pass.

Tauri Open Capture button polish

  • Restyled the Tauri Open Capture... button to be visually closer to the Qt version.
  • Reduced the heavy solid primary-button look.
  • Kept the button prominent but less visually loud, with a lighter desktop-style treatment and green accent.

What was intentionally left unchanged

This PR does not change:

  • parser behavior;
  • protocol decoding;
  • flow extraction;
  • packet payload extraction;
  • packet details data model;
  • session DTO contracts;
  • Wireshark filter generation;
  • Analysis / Statistics behavior;
  • QUIC behavior;
  • stream-detail layout beyond small spacing effects.

Stream details still need a separate design pass later.

Validation

Manually checked the updated UI on representative captures in both Qt and Tauri:

  • large YouTube QUIC/TCP capture;
  • IPv4 flow-heavy view;
  • IPv6 flow view;
  • selected-flow packet list;
  • Packet Details Summary with nested protocol details.

The updated layout fits more useful information on screen while preserving readability and existing behavior.

Notes

This PR is primarily visual/UI polish. The Tauri UI still has some advantages in Summary rendering, while the Qt UI now has improved copy/select behavior for Summary text. Further Packet Details and Stream layout improvements should be handled in follow-up UI branches.

Copilot AI review requested due to automatic review settings July 1, 2026 20:36

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refines the main workspace UI density and usability across both the Qt (QML) UI and the experimental Tauri UI, with a focus on making the Flows workspace more compact and improving Packet Details Summary copy/select behavior.

Changes:

  • Tightened spacing and row/tab heights across Flows workspace panels (Qt + Tauri).
  • Replaced separate Address/Port columns with compact Endpoint A/B rendering (Qt + Tauri).
  • Consolidated the lower Packets/Stream controls into a single toolbar-style row and made Qt Summary text selectable.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/ui/qml/Main.qml Reduced top-level tab spacing and tab heights for denser layout.
src/ui/qml/components/StreamView.qml Added showToolbar and tightened stream view spacing/typography.
src/ui/qml/components/PacketList.qml Added showToolbar, tightened list density, and adjusted row heights.
src/ui/qml/components/PacketDetailsPane.qml Introduced selectable summary text via SelectableText and reduced vertical spacing.
src/ui/qml/components/FlowWorkspacePane.qml Added combined lower toolbar row (tabs + status + Load more) and hid inner toolbars.
src/ui/qml/components/FlowTable.qml Implemented compact Endpoint A/B columns and reduced flow table density.
src/ui/app/main.cpp Removed BOM/normalized include line start.
experimental/tauri-ui-spike/web/styles.css Adjusted spacing, tab sizing, added endpoint cell layout, and restyled “Open Capture…” button.
experimental/tauri-ui-spike/web/main.js Updated row virtualization height and implemented endpoint formatting/rendering helpers.
experimental/tauri-ui-spike/web/index.html Converted headings to more compact layout and added combined flow-view toolbar row.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/ui/qml/components/FlowTable.qml
Comment thread experimental/tauri-ui-spike/web/main.js
Comment on lines +440 to +443
readOnly: true
selectByMouse: true
textFormat: TextEdit.PlainText
wrapMode: textWrapMode
Comment on lines +220 to +227
Label {
Layout.fillWidth: true
text: root.lowerToolbarStatusText()
color: "#6b7280"
elide: Text.ElideRight
verticalAlignment: Text.AlignVCenter
font.pixelSize: 12
}
@AlexeyVasilev

Copy link
Copy Markdown
Owner Author

Addressed.

  • Fixed endpoint formatting so IPv6 addresses are bracketed only when a port is shown.
  • Normalized endpoint string formatting to address : port while keeping visual alignment handled by the UI layout.
  • Disabled Tab-focus navigation for selectable Qt Summary text to avoid creating a large focus chain.
  • Restored warning coloring for the Stream status in the combined Qt lower toolbar.
  • Fixed the Qt flow table endpoint overlap regression by giving the table a horizontal scrolling path and clipping cells so endpoint text no longer draws over neighboring columns.
  • Tauri endpoint rendering was kept as-is after the earlier fix because it now displays full IPv4/IPv6 endpoints correctly.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.

Comment thread src/ui/qml/components/FlowTable.qml Outdated
Comment on lines +421 to +427
Label {
id: endpointALabel
anchors.fill: parent
text: endpointAText
font.family: "Consolas"
verticalAlignment: Text.AlignVCenter
}
Comment thread src/ui/qml/components/FlowTable.qml Outdated
Comment on lines +446 to +452
Label {
id: endpointBLabel
anchors.fill: parent
text: endpointBText
font.family: "Consolas"
verticalAlignment: Text.AlignVCenter
}
Comment on lines +275 to +279
ListView {
id: flowListView
readonly property int rightGutter: flowScrollBar.visible ? flowScrollBar.width + 10 : 0

anchors.fill: parent
Comment thread src/ui/qml/components/FlowTable.qml Outdated
Comment on lines +117 to +133
function endpointHasPort(port) {
const numericPort = Number(port)
return Number.isFinite(numericPort) && numericPort > 0
}

function endpointDisplayAddress(address, port) {
const trimmedAddress = address ? String(address).trim() : ""
if (trimmedAddress.length === 0) {
return ""
}

if (root.endpointHasPort(port) && trimmedAddress.indexOf(":") >= 0) {
return "[" + trimmedAddress + "]"
}

return trimmedAddress
}
@AlexeyVasilev

Copy link
Copy Markdown
Owner Author

Addressed.

  • Added explicit endpoint label elision as a fallback so unexpected clipping is visible instead of silent.
  • Kept wide endpoint columns and horizontal scrolling as the primary path for displaying full IPv4/IPv6 endpoints.
  • Reworked the Qt flow table scrolling layout so the vertical scrollbar remains anchored to the viewport while header and row content scroll horizontally in sync.
  • Removed unused endpoint helper functions from FlowTable.qml.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Comment on lines +434 to +450
component SelectableText: TextEdit {
property color textColor: "#0f172a"
property bool monospace: false
property bool bold: false
property int textWrapMode: TextEdit.NoWrap

readOnly: true
activeFocusOnTab: false
selectByMouse: true
textFormat: TextEdit.PlainText
wrapMode: textWrapMode
color: textColor
font.family: monospace ? "Consolas" : ""
font.pixelSize: 12
font.bold: bold
cursorVisible: activeFocus
}
Comment thread src/ui/qml/components/FlowTable.qml Outdated
Comment on lines +433 to +434
ToolTip.visible: endpointAHoverArea.containsMouse && endpointAText.length > 0
ToolTip.text: endpointAText
Comment thread src/ui/qml/components/FlowTable.qml Outdated
Comment on lines +459 to +460
ToolTip.visible: endpointBHoverArea.containsMouse && endpointBText.length > 0
ToolTip.text: endpointBText
@AlexeyVasilev

Copy link
Copy Markdown
Owner Author

Addressed.

  • Endpoint tooltips in FlowTable.qml now appear only when the endpoint label is actually clipped/truncated, using a safe width comparison instead of showing on every hover.
  • SelectableText keeps cursorVisible: false and remains out of the Tab focus chain with activeFocusOnTab: false.
  • I intentionally did not add a new height binding for SelectableText in this pass. A previous TextEdit height-binding attempt caused a Qt/QML startup regression, so the component was kept stable. Wrapped Summary sizing can be handled in a dedicated follow-up with runtime validation.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

experimental/tauri-ui-spike/web/index.html:184

  • Similarly, the Selected-flow packets/stream panel no longer has a semantic heading. Adding an accessible name to the section preserves navigation landmarks for assistive tech without changing the compact visual design.
              <section class="panel packets-panel">
                <div class="flow-view-toolbar">
                  <div class="subtabbar" aria-label="Selected flow views">
                    <button type="button" class="subtab-button active" data-flow-view-tab="packets">Packets</button>
                    <button type="button" class="subtab-button" data-flow-view-tab="stream">Stream</button>
                  </div>
                  <div class="panel-heading-copy flow-view-status-wrap">
                    <p id="packetMeta" class="panel-subtitle panel-subtitle-inline flow-view-status">Select a flow to load packets.</p>
                  </div>
                  <div class="pager-controls">
                    <button id="packetLoadMoreButton" type="button" class="secondary-button">Load More</button>
                    <button id="streamLoadMoreButton" type="button" class="secondary-button">Load More</button>
                  </div>
                </div>

Comment thread src/ui/qml/components/FlowTable.qml Outdated
}
ListView {
id: flowListView
readonly property int rightGutter: flowScrollBar.visible ? flowScrollBar.width + 10 : 0
Comment on lines 111 to 116
<section class="panel flows-panel">
<div class="panel-heading">
<div>
<h2>Flows</h2>
<p id="flowMeta" class="panel-subtitle">No capture loaded.</p>
<div class="panel-heading panel-heading-compact">
<div class="panel-heading-copy">
<p id="flowMeta" class="panel-subtitle panel-subtitle-inline">No capture loaded.</p>
</div>
</div>
@AlexeyVasilev

Copy link
Copy Markdown
Owner Author

Addressed.

  • Added accessible names to the compact Tauri Flows and selected-flow Packets/Stream sections without restoring visible headings or changing the compact visual layout.
  • Decoupled the Qt flow table right gutter from flowScrollBar.visible by reserving a stable scrollbar gutter width, avoiding the potential QML binding-loop path while preserving the current horizontal/vertical scrolling behavior.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 3 comments.

Comment on lines +202 to +220
Item {
id: flowTableViewport
Layout.fillWidth: true
Layout.fillHeight: true
color: "#f8fafc"
border.color: "#e2e8f0"
radius: 6

ListView {
id: flowListView
readonly property int rightGutter: flowScrollBar.visible ? flowScrollBar.width + 10 : 0


Flickable {
id: flowTableScroller
anchors.fill: parent
anchors.margins: 1
clip: true
model: root.flowModel
currentIndex: -1
onCountChanged: root.syncSelectedFlowRow()
onModelChanged: root.syncSelectedFlowRow()

ScrollBar.vertical: ScrollBar {
id: flowScrollBar
policy: flowListView.contentHeight > flowListView.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
contentWidth: root.flowTableContentWidth
contentHeight: 1
flickableDirection: Flickable.HorizontalFlick
boundsBehavior: Flickable.StopAtBounds

ScrollBar.horizontal: ScrollBar {
id: flowTableHorizontalScrollBar
policy: flowTableScroller.contentWidth > flowTableScroller.width ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
}
}
Comment on lines 561 to 566
SelectableText {
Layout.fillWidth: true
text: summaryLayerCard.titleText
font.pixelSize: 13
font.bold: false
color: "#0f172a"
textColor: "#0f172a"
clip: true
}
loadedPacketRowCount: root.loadedPacketRowCount
totalPacketRowCount: root.totalPacketRowCount
canLoadMorePackets: root.canLoadMorePackets
showToolbar: false
@AlexeyVasilev

Copy link
Copy Markdown
Owner Author

Addressed.

  • Added horizontal wheel/gesture forwarding from the visible Qt flow table area to the horizontal scroll controller, while preserving the existing viewport-owned ListView and vertical scrollbar behavior.
  • Kept header and rows synchronized through the existing horizontal offset mechanism.
  • Added clipped-title tooltip discoverability for selectable Packet Details layer titles without changing the stable selectable text implementation.
  • Removed the no-op titleText binding from the compact PacketList usage where showToolbar: false disables the inner toolbar.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 4 comments.

Comment on lines +473 to +476
ToolTip.visible: endpointAHoverArea.containsMouse
&& endpointAText.length > 0
&& endpointALabel.implicitWidth > endpointALabel.width + 1
ToolTip.text: endpointAText
Comment on lines +501 to +504
ToolTip.visible: endpointBHoverArea.containsMouse
&& endpointBText.length > 0
&& endpointBLabel.implicitWidth > endpointBLabel.width + 1
ToolTip.text: endpointBText
Comment on lines 538 to 544
MouseArea {
id: addressBHoverArea
anchors.fill: parent
acceptedButtons: Qt.NoButton
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 52
hoverEnabled: true
Comment on lines +434 to +450
component SelectableText: TextEdit {
property color textColor: "#0f172a"
property bool monospace: false
property bool bold: false
property int textWrapMode: TextEdit.NoWrap

readOnly: true
activeFocusOnTab: false
selectByMouse: true
textFormat: TextEdit.PlainText
wrapMode: textWrapMode
color: textColor
font.family: monospace ? "Consolas" : ""
font.pixelSize: 12
font.bold: bold
cursorVisible: false
}
@AlexeyVasilev

Copy link
Copy Markdown
Owner Author

Addressed.

  • Kept endpoint tooltip visibility on the explicit width comparison intentionally instead of switching to Label.truncated, because Label.truncated previously caused a startup regression in this Qt/QML runtime.
  • Replaced the hard-coded row-click leftMargin with a computed rowClickLeftMargin so it stays aligned with the table layout/selection area.
  • Added safe clipping for non-wrapping SelectableText usages to prevent overflow outside their cells, while leaving wrapped Summary text behavior unchanged.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 1 comment.

Comment on lines 13 to +17
property bool packetsPartiallyLoaded: false
property var loadedPacketRowCount: 0
property var totalPacketRowCount: 0
property bool canLoadMorePackets: false
property bool showToolbar: true

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acknowledged.

titleText is currently harmless dead API after the compact lower-toolbar cleanup. Since this PR has already gone through several QML layout fixes and the component is stable now, I’m leaving this as-is for this PR to avoid additional churn before merge. It can be removed in a small follow-up cleanup if needed.

@AlexeyVasilev AlexeyVasilev merged commit 9b64777 into main Jul 2, 2026
5 checks passed
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