[macOS][Pets] Pet repeatedly jumps during display/resolution changes; saved position from wrong resolution is restored
What version of the Codex App are you using (From “About Codex” dialog)?
Codex Desktop 26.727.51351 (build 6119)
What subscription do you have?
ChatGPT Pro (20x)
What platform is your computer?
Darwin 25.5.0 arm64 arm
What issue are you seeing?
Summary
When an awake Codex Pet is visible and macOS changes the active display topology or logical resolution, the whole Pet can visibly jump back and forth through more than one screen position before settling. This is repeated repositioning during one display transition, not merely a single final offset.
Packaged-code finding
I inspected the installed release package at ChatGPT.app/Contents/Resources/app.asar; the app package was not modified. This is packaged desktop-app code, not source found in the public openai/codex repository.
The relevant formatted main-process chunk is .vite/build/main-dcXtv3U5.js (SHA-256 203559ac11a69659106471a72e61ee1b035aa895761d0d962d217704af16d485).
The causal path in this build is:
- Lines 110484–110487 register the same zero-argument
handleDisplayChangedcallback fordisplay-added,display-removed, anddisplay-metrics-changed. - Lines 110549–110576 immediately call
switchToDisplay()orreclampWindowToVisibleDisplay(), then persist the result. There is no debounce/coalescing orchangedMetricsfiltering. - Lines 111236–111241 (
C7()) preferbyDisplayId[id]before the exactbyResolution[widthxheight]record. - Lines 110884–110940 immediately apply the computed layout to the Electron window, native overlay, backing canvases, and renderer.
- Lines 110974–110992 immediately overwrite both the display-ID and resolution records.
- Lines 109227–109299 (
Yxe) may retry native positioning at 16 ms intervals for up to 250 ms while the window is visible.
This allows successive display-metric events to present old/intermediate/final targets instead of one settled target.
What steps can reproduce the bug?
User-visible reproduction
- Wake/show the floating Codex Pet.
- Drag it to a recognizable position near a screen edge.
- Keep the Pet visible while changing the macOS logical display resolution, reconnecting a display, or switching display configuration.
- Observe that the Pet may move through multiple positions before settling.
- Switch back to a previously used resolution and compare the restored position.
Deterministic reproduction without a video
The saved-position selector below is copied from the packaged build (generated identifiers retained):
function b7(bounds) {
return `${bounds.width}x${bounds.height}`;
}
function C7(state, display) {
return state == null
? null
: (state.byDisplayId?.[String(display.id)] ??
state.byResolution?.[b7(display.bounds)] ??
(state.byDisplayId == null && state.byResolution == null
? state
: null));
}
const state = {
byDisplayId: {
"1": {
x: 7.48828125,
y: 632.18359375,
displayBounds: { x: 0, y: 0, width: 3008, height: 1692 },
displayId: 1,
placement: "bottom-start",
},
},
byResolution: {
"2056x1329": {
x: 11,
y: 1177,
displayBounds: { x: 0, y: 0, width: 2056, height: 1329 },
displayId: 1,
placement: "top-start",
},
},
};
const display = {
id: 1,
bounds: { x: 0, y: 0, width: 2056, height: 1329 },
};
const selected = C7(state, display);
console.assert(selected === state.byDisplayId["1"]);
console.assert(selected !== state.byResolution["2056x1329"]);
console.log(selected);
For display ID 1 at 2056x1329, C7() selects the record saved at 3008x1692 and ignores the exact 2056x1329 record. The stored vertical targets differ by approximately 545 logical pixels (632.18 versus 1177). This reproduces the saved-position precedence error without requiring a screen recording.
What is the expected behavior?
Display topology/metrics changes should be coalesced until the display configuration is stable, after which the Pet should be repositioned once.
When a position exists for the current logical resolution, it should not be shadowed by a display-ID record saved under another resolution. Intermediate positions should not be presented or persisted, and the Electron/native/renderer layers should remain synchronized.
Additional information
Duplicate search
I searched existing openai/codex issues before filing. No exact duplicate was found for repeated whole-Pet position changes during one macOS display/resolution transition.
Related to #20831, #21501, #36106, and #36466, but not an exact duplicate: this report concerns repeated whole-Pet repositioning during a single macOS display/resolution transition and includes a deterministic reproduction of the saved-position precedence error in C7().
Related but distinct:
- #20831 — broad macOS overlay clipping/mispositioning; a later comment reports a focus-change re-clamp jump, but not this resolution-event burst or
C7()precedence error. - #21501 — position-dependent clipping/corruption away from the top-left corner; related bounds family, but not repeated relocation during a display transition.
- #36106 — external-display changes shift the native fog mask, not the whole Pet through multiple screen positions.
- #36466 — same app build and native/renderer layer desynchronization, but triggered by dragging control icons.
- #25004 — terminal/TUI Pet flicker in Windows Terminal + WSL2 (Sixel redraw path), not the Electron/macOS desktop overlay.
- #21374 — external-monitor scaling clipping; closed as a duplicate of #20831, not evidence that this position-jump path was fixed.
Suggested fix direction:
- Debounce/coalesce display events and apply only the final stable layout.
- Do not persist intermediate event results.
- Prefer an exact resolution record, or validate that a display-ID record's saved dimensions match current bounds.
- Update Electron, native material, backing surfaces, and renderer as one presentation transaction where possible.
- Add a regression test that emits a burst of changing display bounds/work areas and asserts that only the final layout is applied and persisted.
Public repository source cross-check
I also searched the public openai/codex repository for the exact packaged-desktop identifiers:
electron-avatar-overlay-boundsavatar-overlay-layout-changeddisplay-metrics-changedsetOverlayWindowPositionnativePositionControllerhandleDisplayChangedbyDisplayId+byResolutionreclampWindowToVisibleDisplay- Electron
BrowserWindow/setContentBoundsPet positioning
All returned zero code matches.
The Pet source that is public in this repository is codex-rs/tui/src/pets/*. Its module documentation describes “Ambient terminal pets,” and it renders via Ratatui and terminal image protocols (Kitty/Sixel). It does not contain the Electron/macOS floating overlay implementation.
Therefore this report does not claim that the bug was found in the public Rust/TUI Pet source. The affected code was confirmed in the installed desktop release package app.asar for build 6119, and there is no public source location available for a line-for-line comparison.