Skip to content

docs(setup) + tmux: run the workshop in one window (VSCode tabs / tmux / preconfigured layout)#7

Merged
mrpollo merged 8 commits into
mainfrom
docs-single-window-workflow
May 15, 2026
Merged

docs(setup) + tmux: run the workshop in one window (VSCode tabs / tmux / preconfigured layout)#7
mrpollo merged 8 commits into
mainfrom
docs-single-window-workflow

Conversation

@TSC21
Copy link
Copy Markdown
Member

@TSC21 TSC21 commented May 13, 2026

The workshop needs ~4 shells inside the container running at once (Gazebo, PX4, the common launch, the example). Today attendees end up opening four separate OS terminals and running `docker exec -it px4-ossna-26 bash` in each — workable, but newcomers find it disorienting.

Adds a new `### Running several workshop commands in one window` section to `docs/setup.md` with three newcomer-friendly options:

Option A — VSCode DevContainer integrated terminal. Zero setup; every tab the integrated terminal opens is already inside the container. Documents the `+` button, side-by-side split, and tab switching shortcuts.

Option B — `tmux` inside the container. For attendees on the plain `./docker/docker_run.sh` flow. Adds `tmux` to `docker/scripts/install_deps.sh` so the image ships with it pre-installed, then walks newcomers through the prefix-key model, a ~10-row shortcut reference table, a worked example building a 3-pane layout by hand, and detach/re-attach.

Option C — preconfigured workshop layout (`workshop-tmux`). Adds `docker/scripts/workshop-tmux.sh`, copied to `/usr/local/bin/workshop-tmux` in the image's dev stage. It opens a session named `ossna` with:

  • a `sim` window arranged as a tiled 2×2 grid with panes pre-titled in their borders: `0: gazebo` (top-left), `1: px4` (top-right), `2: ros2 (common.launch.py + example launches)` (bottom-left), `3: qgc` (bottom-right);
  • each pane pre-seeded with comment-only hint lines (e.g. `# python3 /home/ubuntu/PX4-gazebo-models/simulation-gazebo --world default`) so attendees only have to copy → edit → run;
  • a `scratch` window for `ros2 topic echo`, `ros2 node list`, etc.
  • mouse mode on, 20k scrollback, vi keys in copy mode.

Re-running `workshop-tmux` reattaches to the existing session, so it doubles as the recovery command after `Ctrl+b d` or after closing the OS terminal.

Verified

  • `bash -n` on `workshop-tmux.sh`.
  • Smoke-tested inside a real container: `tmux list-panes` confirms all four panes labelled correctly (`gazebo`, `px4`, `ros2 ...`, `qgc`); `capture-pane` confirms each pane shows the expected hint comments.

TSC21 added 2 commits May 13, 2026 14:05
…nals or tmux)

The workshop needs ~4 shells inside the container at once (Gazebo,
PX4, the common launch, the example), and attendees have been
opening ~4 separate OS terminals + 4 `docker exec -it` each time.
Document the two friendlier alternatives.

* Option A: VSCode DevContainer integrated terminal — every tab is
  already inside the container; click the `+` to add a new one.
  Zero setup required.
* Option B: `tmux` inside the container — adds `tmux` to the apt
  install list so the image ships with it pre-installed, then a
  newcomer-friendly walkthrough of the prefix-key model and the
  ~10 most useful shortcuts (split, switch panes, detach/reattach,
  exit). Covers the case where someone is on the plain
  `./docker/docker_run.sh` flow without VSCode.
Adds a small script, /usr/local/bin/workshop-tmux, that builds a
ready-to-use tmux layout for the workshop:

  * one window "sim" with a 2x2 tiled grid of panes labelled in
    their borders as 'gazebo', 'px4', 'ros2', 'qgc'
  * each pane pre-seeded with comment-only hint lines showing the
    exact command to paste there (Gazebo invocation, PX4 SITL
    command, the common.launch.py + per-example launches, QGC)
  * a second window "scratch" for ad-hoc ros2 topic/node commands
  * friendlier defaults: pane title in border, mouse on,
    20000-line scrollback, vi-style copy mode

Re-running `workshop-tmux` reattaches to the existing session
instead of building a new one, so it doubles as the way back in
after `Ctrl+b d` or after closing the OS terminal.

Wired up in Dockerfile's dev stage (COPY before the USER switch
so the file lands in /usr/local/bin owned by root and exec'able by
everyone). docs/setup.md gets a new "Option C" subsection under
the "Running several workshop commands in one window" section
documenting the layout, the launch command, reattach, and how to
nuke and recreate a session.
@TSC21 TSC21 changed the title docs(setup): how to run the workshop in one window (VSCode tabs / tmux) docs(setup) + tmux: run the workshop in one window (VSCode tabs / tmux / preconfigured layout) May 13, 2026
TSC21 added 6 commits May 13, 2026 14:22
…pane

The original 4-pane layout suggested running common.launch.py and the
example launch in the same pane, but both are foreground `ros2 launch`
processes so that's not actually possible. Restructure to a 5-pane
layout where each long-running foreground process owns its own pane:

  ┌─────────────────────┬─────────────────────┐
  │ gazebo              │ px4                 │
  ├─────────────────────┤                     │
  │ ros2 common         │ qgc  (tall pane)    │
  ├─────────────────────┤                     │
  │ ros2 example        │                     │
  └─────────────────────┴─────────────────────┘

QGC gets the bulk of the right column since its UI is what you watch
most.

Also switch the script from numeric pane_index targeting to stable
pane_id (#{pane_id}, %N) targeting because tmux re-numbers
pane_index in reading order whenever the layout changes, which
silently scrambles titles applied after all splits.

docs/setup.md's Option C diagram updated to match.
Dress up the workshop layout. Two small helper scripts run from
tmux's status bar (status-interval 1) to drive cheap animations:

  /usr/local/bin/workshop-banner
      Prints a tmux format string with a rainbow "OSSNA 2026"
      banner where one letter at a time is inverted (white text
      on its own colour). Cycles one letter per second.

  /usr/local/bin/workshop-spinner
      Prints one frame of a 10-frame braille spinner based on
      the wall-clock second.

The launcher applies a cohesive theme: dark navy status background,
bright cyan active pane border, magenta inactive pane title dots,
yellow flash on inactive-window activity, and a purple-on-yellow
message popup. The two helpers feed status-left (banner) and
status-right (spinner + ros2-coloured "workshop" label + clock).

Dockerfile copies all three scripts into /usr/local/bin in the dev
stage, owned by root, executable by everyone.
…come

Make the workshop session look like something built for an Open Source
Summit room and not a 90s vt100. Upgrades:

* Theme switched from the previous five-color hack to a coherent
  Dracula-inspired palette (pink/purple/cyan/green/yellow on #13111c).
  Heavy pane borders on tmux 3.2+; bright pink active border with
  hex-bullet ⬢ ... ⬢ pane titles; cyan-on-dark window list.

* status-left animation reworked: instead of a single rotating
  letter highlight, a traveling "scanner" sweeps across the title
  string `░▒▓ OSS NA ◆ 26 ▓▒░`. Letters within 1, 2, 3 columns of
  the scanner fade from white-hot pink → purple → cyan → dim grey.
  Advances two columns per tmux tick so the motion is visible at
  status-interval 1.

* status-right animation reworked: replaces the braille spinner with
  a 5-bar audio-EQ visualisation. Each bar samples a sine wave at a
  different phase so the heights snapshot to different positions each
  tick — looks like a small bouncing equaliser.

* Pane hint comments dressed up with ▙▟ glyph headers; per-pane
  blurbs name the tech stack (Gazebo Harmonic, PX4 v1.16 SITL, ROS 2
  common.launch.py, QGroundControl v5.0.8).

* New helper /usr/local/bin/workshop-welcome prints a colored Tux
  ASCII + tech-stack badges + a six-line tmux cheat sheet. Wired into
  the scratch window so attendees see it the moment they switch with
  Ctrl-b 1.

* Dockerfile copies all four helpers (workshop-tmux, banner, spinner,
  welcome) into /usr/local/bin in the dev stage, owned by root, world
  executable.
… copy

Three small UX fixes spotted on first interactive use:

1. The scratch pane had no explicit title, so the global
   pane-border-format `⬢ #{pane_title} ⬢` fell back to the
   container hostname. Set its title to "scratch" right after
   creating the window.

2. Each pane was seeded by a chain of `send-keys '#hint' Enter
   '#hint' Enter ...`, which prints one shell prompt per line. With
   the longer ROS 2 example pane that was six prompts before the
   user typed anything. Replace the chain with a single
   `clear; printf 'colored\nmulti\nline\n'` invocation so each
   pane shows the hint once, then exactly one trailing prompt.

3. `set -g mouse on` was capturing click-drag, so attendees couldn't
   use their terminal's native selection to copy command output.
   Turn mouse mode off and add a comment explaining the trade-off
   (no click-to-focus on panes; use Ctrl-b arrow instead). Anyone
   who prefers mouse mode can re-enable per session with
   `tmux set mouse on`.
Two issues reported on the previous iteration:

1. First (Gazebo) pane stuck showing the literal `clear; printf
   '\033[38;5;213m▙▟ Gazebo Harmonic ▙▟\033[0m\n...` and never
   reaching a fresh prompt — typing into the pane just extended that
   broken command line. Cause: tmux send-keys with a long
   quoted-printf payload races with the freshly-spawned shell on the
   first pane (the one already attached to the new-session), so the
   payload can be torn mid-stream and Enter fires on a partial line.

   Fix: ship a tiny external helper `workshop-hint TOPIC` that prints
   the colored card from a Python script. The pane seed is now one
   short, quote-free command (`clear; workshop-hint gazebo`) instead
   of a long printf, which sidesteps the entire race.

2. With `mouse off` (set in the previous push to make copy/paste
   work) attendees could not click panes to focus them either, which
   they expected to be able to do. Switch back to `mouse on` and tell
   the welcome banner to advise Shift+drag for copy — Shift+drag
   bypasses tmux's mouse capture on every common terminal emulator,
   so attendees still get native selection.

Wired the new `workshop-hint` helper into the dev stage of the
Dockerfile alongside the existing animation/welcome helpers.
Reports of "can't select other tabs" — likely a host terminal (often
VSCode's built-in one) that eats tmux mouse events or blocks Ctrl-b
chords. Add a small set of bare-Alt root-table bindings so attendees
always have a working way to navigate, regardless of mouse capture
or prefix interception:

  Alt+1 / Alt+2          switch to window 1 (sim) / 2 (scratch)
  Alt+Left / Alt+Right   previous / next window
  Alt+h Alt+j Alt+k Alt+l   move focus between panes (vim arrows)
  Alt+z                  zoom current pane to full screen

All bound on the `root` key table (no prefix). The welcome banner's
cheat sheet is rewritten to put the no-prefix shortcuts first and the
Ctrl-b alternatives below for users who prefer them.
@mrpollo mrpollo merged commit cb94fb5 into main May 15, 2026
3 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