Skip to content

[Linux] Split-pane grid — recursive binary tree #135

@2witstudios

Description

@2witstudios

Overview

Implement the split-pane terminal grid matching macOS PaneGridController.swift. A recursive binary tree of splits, up to 6 panes.

Data Structure

enum PaneSplitNode {
    Leaf { id: String, entry: Option<TabEntry> },
    Split {
        direction: SplitDirection, // Horizontal | Vertical
        first: Box<PaneSplitNode>,
        second: Box<PaneSplitNode>,
        ratio: f64, // 0.0 to 1.0, default 0.5
    },
}

GTK Implementation

Each Split node renders as a gtk::Paned:

  • Horizontalgtk::Orientation::Vertical (top/bottom)
  • Verticalgtk::Orientation::Horizontal (left/right)
  • ratio maps to Paned::set_position() based on allocated size

Each Leaf node contains either a TerminalPane (VTE) or a PlaceholderView with "New Agent" / "New Terminal" buttons.

Operations

  • Split focused pane (Ctrl+D horizontal, Ctrl+Shift+D vertical): Split the leaf, create new empty leaf
  • Close focused pane (Ctrl+W): Remove leaf, promote sibling
  • Move focus (Ctrl+Arrow): Navigate directionally through the tree
  • Max 6 leaves: Enforce limit, max 2 rows × 3 columns

Focus Management

Track focused_leaf_id. Highlight focused pane with a subtle border. Mouse click updates focus. Keyboard shortcuts navigate focus.

Hover Overlay

Each pane cell shows translucent overlay on hover with:

  • Split horizontal button (⊟)
  • Split vertical button (⊞)
  • Close button (✕)

Use gtk::Overlay with a gtk::EventControllerMotion for hover detection.

Session Persistence

Serialize PaneSplitNode to GridLayoutNode (Codable/serde) and persist in .ppg/dashboard-sessions.json under gridLayouts[entryId]. Restore on app relaunch.

References

  • macOS: PPG CLI/PPG CLI/PaneGridController.swift (1158 lines)
  • Persistence: PPG CLI/PPG CLI/DashboardSession.swift (GridLayoutNode)

Acceptance Criteria

  • Binary split tree renders correctly with nested gtk::Paned widgets
  • Split/close/focus-move keyboard shortcuts work
  • Max 6 panes enforced
  • Hover overlay with split/close buttons
  • Grid layout persisted and restored from dashboard-sessions.json
  • Empty panes show placeholder with spawn buttons
  • Drag-to-resize splits via Paned handles

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions