Repository navigation
Windows pet overlay loses its hit region after the first drag #41501
Description
What version of the Codex App are you using (From “About Codex” dialog)?
Build 26.825.5331.0
What subscription do you have?
Pro plan
What platform is your computer?
Microsoft Windows NT 10.0.19045.0 x64
What issue are you seeing?
Windows pet overlay loses its hit region after the first drag. The first drag after restart or Wake Pet works; subsequent clicks pass through while animation continues. Reproduces with built-in and custom pets at every scale. Build 26.825.5331.0, Windows 10 build 19045, three 1920×1080 monitors.
What steps can reproduce the bug?
Feedback ID: no-active-thread-01a04c97-8764-7990-ab27-d88d8b0b7570
What is the expected behavior?
The pet should remain interactive after every completed drag.
After releasing the pointer:
- The next pointer-down event on the visible pet should start another drag.
- The native hit region should follow the pet window’s final position.
- Transparent parts of the overlay may remain click-through, but the pet’s designated hit region must continue accepting pointer input.
- Behavior should be identical for built-in and custom pets, at every supported scale and on every connected display.
- Restarting the app or recreating the pet overlay should not be required between drags.
Additional information
Feedback ID: no-active-thread-01a04c97-8764-7990-ab27-d88d8b0b7570
- What steps can reproduce the bug?
Environment:
- OS: Windows 10 Pro for Workstations, build 19045
- Desktop app package: 26.825.5331.0
- Embedded app version: 26.825.41651, build 7345
- Electron: 42.3.0
- Display configuration: three 1920×1080 monitors at 100% scaling
- The problem affects both built-in and local custom pets at every tested pet scale.
Reproduction steps:
- Fully quit and restart the desktop app.
- Open Settings → Pets and wake any pet.
- Press and drag the pet to another position.
- Release the pointer. The first drag works correctly.
- Without restarting or recreating the pet overlay, try to drag the same pet again.
- The pet no longer receives pointer input. Clicking or dragging passes through the overlay to the application underneath.
- The pet animation continues normally.
- Restarting the app, or using Tuck Away Pet followed by Wake Pet, restores interaction for exactly one more drag. The problem then repeats.
No user code or prompt is required to reproduce the issue. Equivalent pseudocode:
restartDesktopApp()
wakePet(anyBuiltInOrCustomPet)
drag(pet, positionA, positionB) // succeeds
drag(pet, positionB, positionC) // fails: pointer input passes through
assert(pet.animationIsStillRunning)
The same behavior was observed before and after the application updated from package 26.825.4187.0 to 26.825.5331.0.
Session ID: Not available.
Token limit usage: Not applicable.
Context window usage: Not applicable.
This is a native desktop overlay interaction bug and does not depend on a conversation, prompt, model, token limit, or context-window usage.
Activity
github-actions commentedon Aug 29, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
clatkins27-sudo commentedon Aug 30, 2026
I can reproduce this with a custom v2 pet on Windows. The pet continues animating after interaction fails. Switching to another pet and back recreates the avatarOverlay and restores exactly one interaction before pointer hit-testing fails again. Local Codex logs also show repeated renderer-level ResizeObserver errors around the failure. The pet package itself remains valid and loaded.
chen123753 commentedon Aug 31, 2026
Still reproducible on Codex App 26.825.6671.0.
Environment
BrowserWindow.isInputShapeSupported() = falseClean native isolation
(1467, 780)and remained inside the visible overlay bounds(1177, 0)–(1708, 1067), so the stored visual geometry was valid.0x2800A8;WS_EX_TRANSPARENTwas set.A narrow local diagnostic confirms that calling Electron's native
overlay.setIgnoreMouseEvents(false)only while the cursor is over the existing DOM hit regions restores trusted native pointer handling. No synthetic pointer events are required.This continues to suggest a cached pointer-interactivity/native-window-style mismatch: the Windows fallback should unconditionally reconcile/clear the real
WS_EX_TRANSPARENTstate when an avatar hit region becomes interactive, rather than relying only on cachedmousePassthroughMode.It would also help if
native-pet-state.jsonincludedisInputShapeSupported,mousePassthroughMode,pointerInteractive, drag state, and the actual Win32 extended style; the current diagnostics do not expose those fields.314159ctl commentedon Aug 31, 2026
我在 Windows Codex build 26.825.5331.0 上复现了这个问题:第一次拖动成功,松开后第二次点击或拖动失效,但宠物动画仍在运行。
本地分析显示,更新后的 Windows 宠物使用了 native 大型透明悬浮层;第一次拖动结束后,命中区域和鼠标穿透状态可能没有正确恢复,导致后续输入穿透到下面的窗口。
我将 Windows 宠物强制切换回 legacy 小窗口渲染/拖动路径后,点击、唤醒以及连续多次拖动均恢复正常。这个 workaround 不修改宠物素材,问题似乎属于 overlay hit-region / pointer-passthrough 状态同步。
该方案目前只是本地验证过的、与版本相关的 workaround,不是官方最终修复,后续应用更新可能会覆盖它。
clatkins27-sudo commentedon Aug 31, 2026
I think there is enough evidence now to suggest a concrete Windows-side fix rather than only another reproduction report.
The common failure appears to be that the avatar overlay's logical pointer state and the actual Win32 window state can diverge after drag completion. In the broken state, WS_EX_TRANSPARENT remains set even though Codex may believe mouse passthrough is disabled. Clearing that native flag restores dragging, and forcing the legacy small-window path also avoids the failure.
A likely fix would be to reconcile the real native state whenever the pet becomes interactive instead of trusting cached mousePassthroughMode:
before applying/reapplying the pet hit region, call overlay.setIgnoreMouseEvents(false) unconditionally;
after every drag-end/drop, explicitly restore pointer interactivity and then reapply the hit region;
on Windows, verify the actual HWND extended style and clear/reconcile WS_EX_TRANSPARENT if the logical state says the overlay should be interactive;
when BrowserWindow.isInputShapeSupported() is false, use the Windows fallback that actively toggles mouse passthrough over the pet hit target, or temporarily fall back to the legacy small-window path rather than leaving the large overlay permanently transparent;
expose the cached state plus actual Win32 extended style in diagnostics so this mismatch can be seen directly.
The important part seems to be that mousePassthroughMode == disabled should not be treated as proof that the native window is actually accepting pointer input. The real HWND state needs to be reconciled after drag/drop.
I wouldn't call this a confirmed patch without testing it in the Codex source, but the reproduction data now seems strong enough that this is a specific implementation direction rather than speculation about pet assets.
mdruy commentedon Aug 31, 2026
I can reproduce a broader and inconsistent pet-overlay failure on Windows since a few days.
Environment:
Actual behavior:
Expected behavior:
The pet overlay should render consistently, show its controls only in the intended state and position, and allow clicking the pet, dragging it, and using the visible voice/chevron controls.
feifeifeifeifeifeifei commentedon Sep 1, 2026
Same failure on Windows 11 with package
26.831.1445.0. Adding a root-cause analysis from the packaged app plus measurements from the live process, because I believe the fix direction proposed above (reconcilingWS_EX_TRANSPARENTafter drag-end) addresses the symptom but not the cause.TL;DR — after a drag the hit region is not merely disabled, it is computed in the wrong place. There is a Windows-only window-clipping step that makes the mascot's offset inside the overlay window display-dependent, while every reverse-derivation of the pet anchor assumes that offset is constant — which it is on macOS, but not on Windows.
Environment
OpenAI.Codex_26.831.1445.0_x64__2p2nqsd0c76g0Re the 125%-scaling angle in #41485: that looks like a red herring. The reporter of this issue runs three 1920x1080 displays all at 100% and sees identical behaviour, and I see it on a 100% primary.
The Windows-only branch
getLayoutForDisplaycontains the only platform branch in the overlay module:and
lseuses that flag to replace the native draw window with its intersection with the display:use()builds a fixed ~772 x 2129 transparent canvas — its anchor is a compile-time constant (80 x 87), not the mascot size — with the mascot at a constant offset inside it. On macOS that window is used as-is, solayout.mascot.left/topreally is a constant.On Windows the intersection is unavoidable: the raw window's
yis always negative and its bottom always exceeds the display, so for any legal anchor the clipped window collapses toy = 0, height = display height. That matches measurement: on this machine the overlay window is 1080 px tall for every pet and every pet size, and only its width changes (443 / 544 / 548 / 633 / 656 / 681 px observed).So on Windows
layout.mascot.left/topis a function of the clipping — i.e. of the anchor and the display — not a constant.Why the first drag poisons the state
These all reverse-derive the anchor from the window rectangle plus
layout.mascot:startDrag:o = t.pointerWindowX - i.mascot.left,s = t.pointerWindowY - i.mascot.toprememberMovedWindow:anchor = contentBounds + this.layout.mascot.left/tophandleNativeWindowDragMove: keeps the previousmascotand swaps in the newwindowBoundsOn Windows the offset they assume is wrong, so the derived anchor drifts. The drifted value is then clamped by
pseto the edge of the legal region and written to disk bypersistWindowBounds, which is why restarting the app and rebooting do not recover it.Measured drift. I set the persisted anchor to the centre of the primary display and restarted the app — all three records, since lookup order is
byDisplayId->byResolution-> top-level:The pet appeared at (700, 400) as expected. I then dragged it roughly 20 px. After releasing the pointer:
A ~20 px drag moved the stored anchor ~900 px right and ~400 px down, landing on the bottom-right clamp boundary.
The hit region is misplaced, not just disabled
In the broken state I scanned the overlay window with
WindowFromPoint(~7k probe points on a 6-12 px grid) to find where Windows actually routes the mouse:(1239, 0)-(1920, 1080)(1239, 0)-(1587, 312)— a solid ~348 x 312 block pinned to the window's top-left corner(1555, 740)-(1670, 860)So the hit region is non-empty. It simply does not overlap the visible mascot. Immediately after
Tuck Away Pet->Wake Petthe two do overlap (the sprite happens to land inside that top-left block), which is exactly why interaction works for one drag and then stops.This matters for the proposed fix: unconditionally clearing
WS_EX_TRANSPARENTafter drag-end would make that misplaced 348 x 312 block interactive — it would start swallowing clicks over an empty area of the screen — without making the visible pet draggable. I can confirm that shape empirically: while the overlay is in its non-transparent state, that empty block already captures the mouse and the sprite does not.Suggested direction
Recompute
layout.mascotfrom the post-clipping window on win32 before any anchor reverse-derivation; or dropconstrainNativeDrawWindowToDisplayand let the input-shape / passthrough path handle the off-screen parts of the canvas. Note thatBrowserWindow.isInputShapeSupported()reportedly returnsfalseon Windows (comment above), so that second route needs the fallback path to be correct first.Diagnostics that would make this directly visible in
native-pet-state.json:layout.mascot, the pre-clipping and post-clipping window rects, and the real Win32 extended style — in addition to the fields already requested above.All of the above comes from inspecting the shipped package and from measuring the running process; happy to share the measurement scripts, and happy to be corrected if the reconstruction is off.
hmhm2333 commentedon Sep 4, 2026
Additional data point from a newer Windows build: the failure here appears stricter than the misplaced-hit-region variant described above.
Environment
OpenAI.Codex_26.901.2854.0_x64__2p2nqsd0c76g0/pethide/wake was tried again; the pet still could not be draggedLive Win32 measurement while the pet overlay was visible
(648, 0), size772 x 10670x2800A8, includingWS_EX_TRANSPARENTWindowFromPointscan on an 8 px grid: 12,998 samples, 0 hits resolving to the overlay HWND or its rootI also tested native movement separately:
SetWindowPosmoved the overlay by 80 px and moving it back restored the original bounds successfully. This suggests rendering and native window movement are still functional; the broken part is the pointer-region / mouse-interactivity handoff.I inspected the shipped ASAR read-only as well. The avatar page computes elements marked with
data-avatar-overlay-hit-regionand callssetPointerRegions(...), but on this live process no corresponding hit-testable area was observable at the Win32 layer.This may be a regression or second failure mode in
26.901.2854.0: instead of a non-empty region being displaced from the visible mascot, the visible overlay can remain entirely click-through. Happy to run additional targeted diagnostics if maintainers suggest fields to capture.DuckyGameDev commentedon Sep 4, 2026
I can reproduce the same issue and collected some additional diagnostics that may help distinguish the
WS_EX_TRANSPARENTproblem from a stale/offset input-region problem.TL;DR
I can reproduce this on Codex/ChatGPT desktop 26.901.31953 on Windows.
The main finding is that this appears to involve two related but distinct failures:
ExStyle 0x280088to0x2800A8, i.e. the app enablesWS_EX_TRANSPARENT.WS_EX_TRANSPARENTis not always sufficient to restore the pet. In the broken state, the visible Codey can remain completely non-interactive while a separate invisible ("ghost") interactive region still exists elsewhere inside the same overlay window.I measured the ghost region and found it near the top-left of the overlay, while the visible mascot was rendered much farther down/right.
Native
MoveWindow()and a real+1 px resize -> restoredid not resynchronize the visible pet and the ghost hit region.Tuck Away -> Wake Petreliably restores correct interaction temporarily.This suggests that, in addition to the
WS_EX_TRANSPARENT/ mouse-passthrough problem, the Electron input/hit region can become stale or detached from the rendered mascot position after drag.Full diagnostics below.
Full diagnostic results
Environment
Reproduction
Tuck Away -> Wake Petrestores correct interaction temporarily.WS_EX_TRANSPARENTobservationI identified the pet's top-level ChatGPT overlay window and monitored its extended window style.
Immediately after Wake, while the pet is working:
After the first drag:
The difference is exactly
0x20(WS_EX_TRANSPARENT).A short watcher caught the application enabling it twice:
So the application is actively re-applying
WS_EX_TRANSPARENT.In one reproduction, manually clearing only this bit:
immediately restored pet interaction.
However, this was not sufficient in later reproductions.
The overlay could remain:
while the visible Codey was still non-interactive.
This is what led to the second finding.
Detached / stale input region
In the broken state, I found an invisible area elsewhere inside the pet overlay where Codey still reacts to the pointer.
Example overlay geometry:
Approximate visible Codey center:
Approximate bounds of the invisible interactive ("ghost") region:
The upper bound could not be measured completely because the interactive region appeared to reach/clip against the monitor boundary.
The interesting part is its relationship to the overlay origin:
So the ghost region begins very close to the overlay's top-left, while the visible mascot is rendered much farther down/right inside the same overlay.
This does not look like the entire native overlay window simply being in the wrong position. It looks more like the rendered mascot position and its input/hit region have diverged inside the overlay.
Native move test
I tested a very small native
MoveWindow()operation:The final native window rectangle was unchanged, but the ghost interactive region moved noticeably.
For example, before the test an approximate visible/ghost pair was:
After the native move-and-return:
The native overlay itself returned to exactly:
This suggests that a native window-position event causes some internal input-region state to be recalculated, but it still does not become synchronized with the rendered pet.
The application also re-enabled
WS_EX_TRANSPARENTduring this process.Move test while suppressing
WS_EX_TRANSPARENTI then performed several very small native Y movements while immediately clearing
WS_EX_TRANSPARENTafter each movement:The visible pet still did not become interactive.
The ghost region remained in the upper-left portion of the overlay.
Native resize test
I also tested whether a real native resize would force the input shape to be rebuilt.
The overlay was changed from:
to:
and then immediately restored to:
while
WS_EX_TRANSPARENTwas cleared.Result:
Win32 region observation
GetWindowRgn()did not report a custom Win32 HRGN for the overlay.Observed result:
So the interactive shape does not appear to be implemented as a normal
SetWindowRgn()region.This seems consistent with the problem being in Electron/Chromium input-shape / pointer-interactivity handling rather than a conventional Win32 window region.
Interpretation
Based on these observations, there seem to be at least two related states involved:
1. Mouse passthrough state
After drag, the overlay can acquire:
Clearing this flag can restore interaction when the input region is otherwise still valid.
2. Stale/detached input region
In other reproductions, even with:
the visible mascot remains non-interactive while an invisible interactive region exists elsewhere inside the overlay.
Native move and resize operations affect this ghost region but do not make it coincide with the rendered mascot.
That makes me suspect the visual pet coordinates and the Electron input/hit region coordinates become desynchronized after movement.
The fact that:
reliably restores interaction suggests that recreating/resetting the overlay also recreates the correct input region and mouse-passthrough state.
I have not modified or patched the Codex application. These observations were made externally using Win32 window-style, geometry, and pointer diagnostics.
If useful, I'm happy to run additional diagnostics against a test build or check specific window/input state requested by the Codex team.
mdruy commentedon Sep 6, 2026
For me, before,the first drag only worked for a custom made pet (yet felt down from top to bottom if released/renewed or selected) but dragging or clicking doesnt work at all for any pets.
I can reproduce the same issue after hard reset / clean install on the same and/or any other device.
Windows 11 Pro (25H2) build: 26200.9168
Resolution: 3840 × 2160 (150% scaling)
Chat GPT Desktop versions: 26.825.6671.0 - 26.901.6511.0
Also worth noting is that the most recent Windows update KB5120998) breaks mouse cursor behaviour/design in Windows (regardless of Chat GPT) but I'm not on that build, yet I tested it and the same issue persist.
This pet codex issue has been around for weeks now, what are they waiting for?
CapyKkuing commentedon Sep 7, 2026
I am experiencing a very similar recurring issue on Windows while a Codex voice chat is active.
My reproduction sequence:
Expected: The floating voice/pet indicator should remain draggable after switching applications, without repeatedly hiding and waking it.
This is a user-observed reproduction sequence; I have not isolated whether the trigger is the first drag, switching application focus, or their combination. Exact app build, display scaling, and monitor configuration have not yet been collected for this report. I am not claiming a confirmed root cause.
MAXAM-13 commentedon Sep 7, 2026
I’m experiencing a similar issue on Windows with app version 26.901.51231.
The pet initially moved a little during the first launch after installation, but afterward I could no longer drag it. Clicks seem to pass through the pet.
Hiding and waking the pet did not help. Fully closing and reopening the app several times also did not resolve the issue.
scriptjerk-dev commentedon Sep 8, 2026
Additional reproduction evidence from a Windows 11 Pro system:
Native-window inspection showed that the input shape existed but was offset from the rendered mascot:
This places the interactive region in the overlay's upper-left while the mascot is drawn in the lower-right, leaving the visible pet outside the native hit shape. Windows therefore routes clicks on the pet to the application beneath it. This corroborates that the failure is in the desktop overlay/input-region positioning rather than the pet spritesheet.
clatkins27-sudo commentedon Sep 9, 2026
The latest Windows reproduction looks especially useful because it suggests the pet’s native input region may be becoming desynchronized from the rendered mascot position.
In the reported example, the overlay window was approximately (649,0)–(1094,615), while the visible mascot occupied roughly (885,349)–(1094,615). That puts the mascot around local overlay coordinates (236,349). However, the sampled interactive region was approximately (649,0)–(1004,315), which corresponds to an input shape beginning near local (0,0).
In other words, the input shape exists, but appears to be positioned in the overlay’s upper-left while the rendered mascot is in the lower-right. That would explain why animation continues normally while pointer input passes through to the application underneath.
This may be worth checking as a coordinate-space / layout synchronization issue rather than a sprite or drag-handler issue. Possible areas to inspect would be:
whether the input shape is calculated before the mascot’s final layout/offset is applied;
whether screen coordinates, window-local coordinates, CSS pixels, or device-independent pixels are being mixed;
whether DPI scaling or multi-monitor coordinate conversion affects the result;
whether the hit region is refreshed after window movement, clipping, resize, display changes, Tuck Away/Wake, or drag completion.
A relatively simple diagnostic test might be:
Temporarily make the entire overlay window interactive instead of using the mascot-shaped input region.
If dragging remains reliable after switching applications and moving between displays, that would strongly isolate the failure to input-shape geometry.
Log the overlay bounds, getBoundingClientRect() for the rendered mascot, display scale factor, and the final rectangles passed to the native input-shape API.
Ideally, after layout settles, the values should correspond to something like:
overlay: 445 x 615
mascot rect: x=236 y=349 w=209 h=266
input shape: x=236 y=349 w=209 h=266
If the broken state instead shows the mascot at (236,349) while the input shape remains near (0,0), that would provide a fairly direct confirmation.
I would not call DPI scaling or multi-monitor use the confirmed cause yet, since the issue has been reported under several circumstances, but the new measurements make native hit-region positioning/synchronization look like a strong area to investigate.
mdruy commentedon Sep 9, 2026
Whatever is the cause, it seems that every user of Chat GPT on Desktop is affected or am I wrong?
The first drag doesnt work anymore either - it used to work only for the custom pet on select or renewal, though the custom pet spawned on the top right of my screen every time.
After reinstalling Windows and hard reset PC , the dragging never worked. The pet and tooltips/icons are 100% in click-through state.
mdruy commentedon Sep 9, 2026
Issue is fixed for me as we speak - pet spawns and i can keep dragging it and icons/tooltips are clickable.
Chat GPT Desktop version: 26.903.8094.0 (latest)
Windows 26200.9445 (latest)