Fix laggy terminal sync during sidebar drags (#1598)
* Fix sidebar drag terminal resize lag * Add display resolution churn regression * Prelaunch display churn helper in e2e workflow * Use manifest handoff for display churn UI test * Fix e2e display churn harness startup * Resolve display churn UI test socket path * Use marker-based socket discovery in display UI test * Add failing sidebar drag portal regression tests * Fix sidebar drag terminal portal resize lag * Add failing scoped resize regression tests * Fix terminal portal resize scheduling lag * Add failing zsh resize prompt regression test * Fix zsh resize prompt duplication * Fix Sequoia sidebar resize regression * Guard display-resolution CI runner * Run display-resolution CI on WarpBuild * Allow backgrounded display regression app launch * Launch display regression app directly * Launch display regression app via NSWorkspace * Load display regression launch env from manifest * Write display regression manifest in runner temp dir * Write display regression manifest in shared tmp * Write display regression manifest in repo scratch dir * Launch display regression app with explicit env * Avoid xcodebuild broken pipe in compat CI * Launch display regression via XCUIApplication * Harden display regression socket readiness * Trust display socket diagnostics path * Replace display socket probe with render diagnostics * Write display churn start marker atomically * Move display churn harness out of /tmp --------- Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
This commit is contained in:
parent
629b63dfb8
commit
798c1fbc42
16 changed files with 1537 additions and 41 deletions
5
.github/workflows/ci-macos-compat.yml
vendored
5
.github/workflows/ci-macos-compat.yml
vendored
|
|
@ -48,9 +48,10 @@ jobs:
|
|||
echo "Selected: $XCODE_APP"
|
||||
echo "DEVELOPER_DIR=$XCODE_DIR" >> "$GITHUB_ENV"
|
||||
export DEVELOPER_DIR="$XCODE_DIR"
|
||||
XCODE_VER="$(xcodebuild -version | head -1)"
|
||||
XCODE_VERSION_OUTPUT="$(xcodebuild -version)"
|
||||
XCODE_VER="${XCODE_VERSION_OUTPUT%%$'\n'*}"
|
||||
echo "XCODE_VER=$XCODE_VER" >> "$GITHUB_ENV"
|
||||
echo "$XCODE_VER"
|
||||
echo "$XCODE_VERSION_OUTPUT"
|
||||
xcrun --sdk macosx --show-sdk-path
|
||||
sw_vers
|
||||
|
||||
|
|
|
|||
134
.github/workflows/ci.yml
vendored
134
.github/workflows/ci.yml
vendored
|
|
@ -385,3 +385,137 @@ jobs:
|
|||
CMUX_LAG_MAX_CHURN_P95_MS=35 \
|
||||
CMUX_LAG_KEY_EVENTS=180 \
|
||||
python3 tests/test_workspace_churn_up_arrow_lag.py
|
||||
|
||||
ui-display-resolution-regression:
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
|
||||
runs-on: warp-macos-15-arm64-6x
|
||||
timeout-minutes: 25
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Select Xcode
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if [ -d "/Applications/Xcode.app/Contents/Developer" ]; then
|
||||
XCODE_DIR="/Applications/Xcode.app/Contents/Developer"
|
||||
else
|
||||
XCODE_APP="$(ls -d /Applications/Xcode*.app 2>/dev/null | sort | tail -n 1 || true)"
|
||||
if [ -n "$XCODE_APP" ]; then
|
||||
XCODE_DIR="$XCODE_APP/Contents/Developer"
|
||||
else
|
||||
echo "No Xcode.app found under /Applications" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
echo "DEVELOPER_DIR=$XCODE_DIR" >> "$GITHUB_ENV"
|
||||
export DEVELOPER_DIR="$XCODE_DIR"
|
||||
xcodebuild -version
|
||||
xcrun --sdk macosx --show-sdk-path
|
||||
|
||||
- name: Download pre-built GhosttyKit.xcframework
|
||||
run: ./scripts/download-prebuilt-ghosttykit.sh
|
||||
|
||||
- name: Install zig
|
||||
run: |
|
||||
ZIG_REQUIRED="0.15.2"
|
||||
if command -v zig >/dev/null 2>&1 && zig version 2>/dev/null | grep -q "^${ZIG_REQUIRED}"; then
|
||||
echo "zig ${ZIG_REQUIRED} already installed"
|
||||
else
|
||||
echo "Installing zig ${ZIG_REQUIRED} from tarball"
|
||||
curl -fSL "https://ziglang.org/download/${ZIG_REQUIRED}/zig-aarch64-macos-${ZIG_REQUIRED}.tar.xz" -o /tmp/zig.tar.xz
|
||||
tar xf /tmp/zig.tar.xz -C /tmp
|
||||
sudo mkdir -p /usr/local/bin /usr/local/lib
|
||||
sudo cp -f /tmp/zig-aarch64-macos-${ZIG_REQUIRED}/zig /usr/local/bin/zig
|
||||
sudo cp -rf /tmp/zig-aarch64-macos-${ZIG_REQUIRED}/lib /usr/local/lib/zig
|
||||
export PATH="/usr/local/bin:$PATH"
|
||||
zig version
|
||||
fi
|
||||
|
||||
- name: Cache Swift packages
|
||||
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4
|
||||
with:
|
||||
path: .ci-source-packages
|
||||
key: spm-ui-display-resolution-${{ hashFiles('GhosttyTabs.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved') }}
|
||||
restore-keys: spm-ui-display-resolution-
|
||||
|
||||
- name: Resolve Swift packages
|
||||
run: |
|
||||
set -euo pipefail
|
||||
SOURCE_PACKAGES_DIR="$PWD/.ci-source-packages"
|
||||
mkdir -p "$SOURCE_PACKAGES_DIR"
|
||||
|
||||
for attempt in 1 2 3; do
|
||||
if xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux -configuration Debug \
|
||||
-clonedSourcePackagesDirPath "$SOURCE_PACKAGES_DIR" \
|
||||
-resolvePackageDependencies; then
|
||||
exit 0
|
||||
fi
|
||||
if [ "$attempt" -eq 3 ]; then
|
||||
echo "Failed to resolve Swift packages after 3 attempts" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Package resolution failed on attempt $attempt, retrying..."
|
||||
sleep $((attempt * 5))
|
||||
done
|
||||
|
||||
- name: Run display resolution churn UI regression
|
||||
run: |
|
||||
set -euo pipefail
|
||||
SOURCE_PACKAGES_DIR="$PWD/.ci-source-packages"
|
||||
HARNESS_DIR="${RUNNER_TEMP}/cmux-display-churn-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"
|
||||
mkdir -p "$HARNESS_DIR"
|
||||
PREFIX="${HARNESS_DIR}/cmux-display-churn"
|
||||
READY_PATH="${PREFIX}.ready"
|
||||
DISPLAY_ID_PATH="${PREFIX}.id"
|
||||
START_PATH="${PREFIX}.start"
|
||||
DONE_PATH="${PREFIX}.done"
|
||||
LOG_PATH="${PREFIX}.log"
|
||||
MANIFEST_PATH="${HARNESS_DIR}/cmux-ui-test-display-harness.json"
|
||||
|
||||
rm -f "$READY_PATH" "$DISPLAY_ID_PATH" "$START_PATH" "$DONE_PATH" "$LOG_PATH" "$MANIFEST_PATH"
|
||||
|
||||
clang -framework Foundation -framework CoreGraphics \
|
||||
-o /tmp/create-virtual-display scripts/create-virtual-display.m
|
||||
|
||||
/tmp/create-virtual-display \
|
||||
--modes 1920x1080,1728x1117,1600x900,1440x810 \
|
||||
--ready-path "$READY_PATH" \
|
||||
--display-id-path "$DISPLAY_ID_PATH" \
|
||||
--start-path "$START_PATH" \
|
||||
--done-path "$DONE_PATH" \
|
||||
--iterations 40 \
|
||||
--interval-ms 40 \
|
||||
>"$LOG_PATH" 2>&1 &
|
||||
VDISPLAY_PID=$!
|
||||
trap 'kill "$VDISPLAY_PID" >/dev/null 2>&1 || true; rm -f "$MANIFEST_PATH"' EXIT
|
||||
|
||||
for _ in {1..120}; do
|
||||
[ -f "$READY_PATH" ] && break
|
||||
sleep 0.25
|
||||
done
|
||||
[ -f "$READY_PATH" ] || {
|
||||
echo "Display harness failed to start" >&2
|
||||
cat "$LOG_PATH" >&2 || true
|
||||
exit 1
|
||||
}
|
||||
|
||||
cat >"$MANIFEST_PATH" <<EOF
|
||||
{"readyPath":"$READY_PATH","displayIDPath":"$DISPLAY_ID_PATH","startPath":"$START_PATH","donePath":"$DONE_PATH","logPath":"$LOG_PATH"}
|
||||
EOF
|
||||
echo "Display harness manifest: $MANIFEST_PATH"
|
||||
cat "$MANIFEST_PATH"
|
||||
|
||||
CMUX_UI_TEST_DISPLAY_READY_PATH="$READY_PATH" \
|
||||
CMUX_UI_TEST_DISPLAY_ID_PATH="$DISPLAY_ID_PATH" \
|
||||
CMUX_UI_TEST_DISPLAY_START_PATH="$START_PATH" \
|
||||
CMUX_UI_TEST_DISPLAY_DONE_PATH="$DONE_PATH" \
|
||||
CMUX_UI_TEST_DISPLAY_LOG_PATH="$LOG_PATH" \
|
||||
xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux -configuration Debug \
|
||||
-clonedSourcePackagesDirPath "$SOURCE_PACKAGES_DIR" \
|
||||
-disableAutomaticPackageResolution \
|
||||
-destination "platform=macOS" \
|
||||
-only-testing:cmuxUITests/DisplayResolutionRegressionUITests \
|
||||
test
|
||||
|
|
|
|||
61
.github/workflows/test-e2e.yml
vendored
61
.github/workflows/test-e2e.yml
vendored
|
|
@ -108,6 +108,7 @@ jobs:
|
|||
fi
|
||||
|
||||
- name: Create virtual display
|
||||
if: ${{ inputs.test_filter != 'DisplayResolutionRegressionUITests' }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
echo "=== Display before ==="
|
||||
|
|
@ -204,8 +205,64 @@ jobs:
|
|||
set -euo pipefail
|
||||
SOURCE_PACKAGES_DIR="$PWD/.ci-source-packages"
|
||||
ONLY_TESTING="-only-testing:cmuxUITests/$TEST_FILTER"
|
||||
DISPLAY_ENV_PREFIX=()
|
||||
|
||||
# Start recording right before the test (after build/resolve)
|
||||
if [ "$TEST_FILTER" = "DisplayResolutionRegressionUITests" ]; then
|
||||
HARNESS_DIR="${RUNNER_TEMP}/cmux-display-churn-${{ github.run_id }}-${{ github.run_attempt }}"
|
||||
mkdir -p "$HARNESS_DIR"
|
||||
PREFIX="${HARNESS_DIR}/cmux-display-churn"
|
||||
READY_PATH="${PREFIX}.ready"
|
||||
DISPLAY_ID_PATH="${PREFIX}.id"
|
||||
START_PATH="${PREFIX}.start"
|
||||
DONE_PATH="${PREFIX}.done"
|
||||
LOG_PATH="${PREFIX}.log"
|
||||
MANIFEST_PATH="${HARNESS_DIR}/cmux-ui-test-display-harness.json"
|
||||
|
||||
rm -f "$READY_PATH" "$DISPLAY_ID_PATH" "$START_PATH" "$DONE_PATH" "$LOG_PATH" "$MANIFEST_PATH"
|
||||
|
||||
clang -framework Foundation -framework CoreGraphics \
|
||||
-o /tmp/create-virtual-display scripts/create-virtual-display.m
|
||||
|
||||
/tmp/create-virtual-display \
|
||||
--modes 1920x1080,1728x1117,1600x900,1440x810 \
|
||||
--ready-path "$READY_PATH" \
|
||||
--display-id-path "$DISPLAY_ID_PATH" \
|
||||
--start-path "$START_PATH" \
|
||||
--done-path "$DONE_PATH" \
|
||||
--iterations 40 \
|
||||
--interval-ms 40 \
|
||||
>"$LOG_PATH" 2>&1 &
|
||||
DISPLAY_VDISPLAY_PID=$!
|
||||
trap 'kill "${DISPLAY_VDISPLAY_PID:-}" >/dev/null 2>&1 || true; rm -f "$MANIFEST_PATH"' EXIT
|
||||
|
||||
for _ in {1..120}; do
|
||||
[ -f "$READY_PATH" ] && break
|
||||
sleep 0.25
|
||||
done
|
||||
[ -f "$READY_PATH" ] || {
|
||||
echo "Display harness failed to start" >&2
|
||||
cat "$LOG_PATH" >&2 || true
|
||||
exit 1
|
||||
}
|
||||
|
||||
cat >"$MANIFEST_PATH" <<EOF
|
||||
{"readyPath":"$READY_PATH","displayIDPath":"$DISPLAY_ID_PATH","startPath":"$START_PATH","donePath":"$DONE_PATH","logPath":"$LOG_PATH"}
|
||||
EOF
|
||||
echo "Display harness manifest: $MANIFEST_PATH"
|
||||
cat "$MANIFEST_PATH"
|
||||
|
||||
DISPLAY_ENV_PREFIX=(
|
||||
CMUX_UI_TEST_DISPLAY_READY_PATH="$READY_PATH"
|
||||
CMUX_UI_TEST_DISPLAY_ID_PATH="$DISPLAY_ID_PATH"
|
||||
CMUX_UI_TEST_DISPLAY_START_PATH="$START_PATH"
|
||||
CMUX_UI_TEST_DISPLAY_DONE_PATH="$DONE_PATH"
|
||||
CMUX_UI_TEST_DISPLAY_LOG_PATH="$LOG_PATH"
|
||||
)
|
||||
fi
|
||||
|
||||
# Start recording right before the test (after build/resolve).
|
||||
# The display churn regression creates its own virtual display above,
|
||||
# so recording must start after that harness is ready.
|
||||
if [ "$RECORD_VIDEO" = "true" ]; then
|
||||
DEVLIST=$( ffmpeg -f avfoundation -list_devices true -i "" 2>&1 || true )
|
||||
echo "Available devices:"
|
||||
|
|
@ -233,7 +290,7 @@ jobs:
|
|||
fi
|
||||
|
||||
set +e
|
||||
OUTPUT=$(xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux -configuration Debug \
|
||||
OUTPUT=$(env "${DISPLAY_ENV_PREFIX[@]}" xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux -configuration Debug \
|
||||
-clonedSourcePackagesDirPath "$SOURCE_PACKAGES_DIR" \
|
||||
-disableAutomaticPackageResolution \
|
||||
-destination "platform=macOS" \
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue