Files
SonicForgeStudio/9.1_FIX_TRACKUI.md
T

8.7 KiB

Bug Fix Specification: Resolving Critical Row Desynchronization

This document analyzes the root cause and provides a permanent structural solution to eliminate the vertical row desynchronization and internal horizontal scrolling artifacts occurring between the left Track Control Panel (TCP) and the right waveform lanes, based on the real-world visual analysis


1. Visual Symptom Analysis

The layout engine is suffering from two critical alignment failures indicated by the red arrows:

[ LEFT COLUMN - TCP PANEL ]                   [ RIGHT COLUMN - TIMELINE GRID ]
┌──────────────────────────────┐              ┌──────────────────────────────────────────────┐
│ ... Track 05, 06 (Aligned)   │  ══════════  │ Waveform 05, 06 (Aligned)                    │
├──────────────────────────────┤              ├──────────────────────────────────────────────┤
│ 07 Track 3 (Channel Header)  │  [MISALIGNED]│ [EMPTY BLACK DEAD SPACE] (Lower red arrow)   │
│ [Junk horizontal scrollbar]  │ ◄──────────  │ ◄── Caused by Waveform 07 dropping height to 0│
│ (Upper red arrow)            │              ├──────────────────────────────────────────────┤
├──────────────────────────────┤              │ Waveform 07 (Pushed down to Track 08's row)  │
│ 08 Track 3                   │  ══════════  │ ...                                          │
└──────────────────────────────┘              └──────────────────────────────────────────────┘

1.1. Defect Index 1: Spurious Internal Horizontal Scrollbar (Upper Red Arrow)

  • Symptom: A small gray horizontal scrollbar emerges directly beneath Track 07 within the left TCP column.
  • Root Cause: The container wrapper for the left TCP column enforces a rigid bounding layout (fixed width or missing an explicit overflow-x: hidden safety attribute). When inner structural components (such as long text labels, Mute/Solo clusters, or upload file actions) expand horizontally, the browser generates a local scrollbar. This automatically inflates the effective physical height of the left Track 07 by roughly 12\text{ px} \rightarrow 16\text{ px}.

1.2. Defect Index 2: Vertical Row Desynchronization & Dead Black Space (Lower Red Arrow)

  • Symptom: On the right column (Timeline), a massive horizontal empty black gap disrupts the grid layout where Waveform 07 ought to sit. Consequently, all matching waveforms for Track 07 and Track 08 are offset downward, falling entirely out of phase with their corresponding control headers on the left.
  • Root Cause: The system evaluates the target height (H) of the left TCP container independently from the right Waveform Lane. When the left Track 07 column expands due to the rendering of the junk scrollbar, the right canvas lane does not dynamically adapt. This triggers a cumulative pixel error along the vertical axis (Y), producing progressive, severe desynchronization downstream (the lower the tracks sit, the worse the alignment drifts).

2. Structural Correction Blueprint

To prevent this layout defect from recurring—especially when porting the interface to desktop Python using PyQt/PySide—the system must completely decouple from independent height calculations and embrace a Unified Row Layout model.

2.1. Standardized HTML / Tailwind CSS Architecture Blueprint

Instead of splitting the page tree layout into two isolated columns (Col1: [TCP1, TCP2, TCP3] and Col2: [Wave1, Wave2, Wave3]), the application must encapsulate each matching TCP and Waveform pair within a shared, unified row wrapper:

<!-- Wrap the entire track stack inside a single vertical scroll container -->
<div class="flex-1 overflow-y-auto bg-[#111111]">
  
  <!-- UNIFIED TRACK ROW (Enforces strict shared-row geometry) -->
  <div class="flex h-[96px] w-full min-w-max border-b border-[#141414]">
    
    <!-- Left Side: TCP (Fixed width; absolute containment of horizontal overflows) -->
    <div class="w-[300px] shrink-0 bg-[#262626] p-2.5 overflow-hidden flex flex-col justify-between">
      <!-- TCP Control Content Elements Go Here -->
    </div>
    
    <!-- Right Side: Waveform Lane (Flexibly fills remaining browser canvas viewport) -->
    <div class="flex-1 relative overflow-hidden">
      <!-- Waveform Canvas Engine -->
    </div>
    
  </div>
  
  <!-- Add additional track rows duplicating the exact structural envelope above... -->
</div>

Architectural Advantages:

  • Because both the control deck and the waveform graphic share an identical row container wrapper (flex row or grid row), any arbitrary height fluctuation on the TCP side (due to text zoom-in behaviors or overflow glitches) will instantly force the right waveform canvas view to mirror the 100\% row scale change.
  • Only one master vertical scrollbar exists on the outer perimeter window to slide all rows simultaneously.

3. Prevention Guidelines for Python Porting (PyQt6 / PySide6)

If you attempt to design this DAW interface inside a containerized Python Docker application by leveraging two separate QScrollArea nodes for the TCP track column and the timeline canvas, you will inevitably trigger this row alignment defect due to timing delays or scroll tracking errors (scrollEvent mismatch).

3.1. Secure Layout Architecture Using Python QWidget

Implement a nested widget strategy to securely bind the horizontal axes together at all times:

from PyQt6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QScrollArea
from PyQt6.QtCore import Qt

class ProDAWArrangeWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.main_layout = QVBoxLayout(self)
        self.main_layout.setContentsMargins(0, 0, 0, 0)
        self.main_layout.setSpacing(0)
        
        # 1. Instantiate a single, unified QScrollArea for the absolute Workspace
        self.workspace_scroll = QScrollArea()
        self.workspace_scroll.setWidgetResizable(True)
        self.workspace_scroll.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
        self.workspace_scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
        
        # 2. Outer container hosting the multi-channel rows
        self.container_widget = QWidget()
        self.container_layout = QVBoxLayout(self.container_widget)
        self.container_layout.setContentsMargins(0, 0, 0, 0)
        self.container_layout.setSpacing(0)
        self.container_layout.setAlignment(Qt.AlignmentFlag.AlignTop)
        
        self.workspace_scroll.setWidget(self.container_widget)
        self.main_layout.addWidget(self.workspace_scroll)

    def add_track(self, track_id: str):
        """
        Appends a unified track row utilizing QHBoxLayout with a rigid physical height constraint.
        """
        track_row = QWidget()
        track_row.setFixedHeight(96) # Lock physical pixel height constraints for the row
        
        row_layout = QHBoxLayout(track_row)
        row_layout.setContentsMargins(0, 0, 0, 0)
        row_layout.setSpacing(0)
        
        # Left Panel: Track Control Panel (Enforces a strict rigid width constraint)
        tcp_widget = QWidget()
        tcp_widget.setFixedWidth(300)
        # tcp_widget.setup_ui(...)
        
        # Right Panel: Waveform Canvas Viewport
        waveform_widget = QWidget()
        # waveform_widget.setup_canvas(...)
        
        # Combine both widgets into the layout block to guarantee row lock
        row_layout.addWidget(tcp_widget)
        row_layout.addWidget(waveform_widget)
        
        self.container_layout.addWidget(track_row)

3.2. Concrete Advantages for Python Docker Environments

  • Zero Alignment Variance: Row alignment is entirely guaranteed at the OS-level layout engine, bypassing desynchronization issues caused by asynchronous rendering cycles or UI latency.
  • Streamlined UI Pipelines: The environment tracking mechanisms hook into a single scrollbar, reducing memory usage and optimizing the drawing threads for the Docker X11 Server or WebRTC stream pipelines when projecting graphics down to the client.