Skip to content

[Windows][Pets] Transparent overlay captures a large screen area, blocks Codex controls, and pet cannot be dragged #41596

Open

Description

@martimtamagnini-hue

What version of the Codex App are you using?

Microsoft Store package OpenAI.Codex 26.825.6671.0 x64.

What platform is your computer?

Windows 11 25H2, build 26200.9168, x64.

What issue are you seeing?

The floating pet is visible but does not respond to left-click, right-click, or drag. This affects every tested pet. The same behavior was also observed on a second Windows PC.

This reproduction differs from the common click-through reports: the transparent pet overlay captures mouse input across a large invisible area. It blocks controls behind it, including the Codex window's maximize/close area, while the visible pet itself still does nothing.

Steps to reproduce

  1. Launch Codex Desktop on Windows.
  2. Wake/show any pet.
  3. Try to left-click, right-click, or drag the visible pet.
  4. Try to click Codex controls that lie behind the transparent portion of the overlay, such as maximize or close.
  5. Switch to another pet and repeat.

Expected behavior

  • The visible pet and its activity controls receive pointer input and the pet can be dragged.
  • Transparent overlay areas pass clicks through to the desktop or Codex window behind them.
  • Codex window controls remain usable.

Actual behavior

  • The pet cannot be clicked, right-clicked, or dragged.
  • Transparent areas of the overlay swallow clicks.
  • Codex window controls behind the overlay cannot be used.
  • Switching pets does not change the behavior.

Native Windows diagnostics

One affected machine uses a 2880×1800 display at 200% scaling (logical 1440×900).

The pet overlay was inspected in the broken state:

  • Physical bounds: 1376,0 1504×1800 (logical 688,0 752×900)
  • Extended styles: WS_EX_TOPMOST | WS_EX_TOOLWINDOW | WS_EX_LAYERED; WS_EX_TRANSPARENT was not set
  • GetWindowRgnBox returned RegionType=0, indicating no restricted native input region
  • Direct WM_NCHITTEST returned HTCLIENT throughout the overlay, including fully transparent points
  • At physical point (2870,20), the overlay returned HTCLIENT, while the underlying Codex main window returned HTCLOSE

The main Codex window was responsive and actually maximized (Zoomed=True, ShowCmd=3); its controls were being occluded by the overlay's input handling.

This suggests the native input shape was not applied, leaving the entire layered overlay interactive, while the renderer's pet hit target still did not process click/drag actions.

Troubleshooting already attempted

  • Updated and fully restarted the desktop app
  • Switched between pets
  • Confirmed all ChatGPT/Codex processes were responsive
  • Confirmed no local mouse hook or Codex package modification was active

The current workaround is to tuck the pet away with /pet, which restores access to the blocked UI.

Related reports

These appear related but primarily describe the opposite failure mode, where clicks pass through the pet:

No conversation contents, local paths, raw logs, screenshots, or account identifiers are included in this report.

Activity

  1. added
    bugSomething isn't working
    appIssues related to the Codex desktop app
    windows-osIssues related to Codex on Windows systems
    on Aug 30, 2026
  2. github-actions commented on Aug 30, 2026

    @github-actions
    Contributor
  3. zoe-he9214 commented on Sep 3, 2026

    @zoe-he9214

    The pet still cannot be clicked or dragged, already updated to 26.901.1978.0 on Windows...

  4. 77kio commented on Sep 5, 2026

    @77kio

    I can reproduce this pet interaction/dragging failure on the Windows Microsoft Store version of Codex. I found a repeatable workaround that may help narrow down the native overlay/composition problem.

    On my machine, the pet is visible but cannot be dragged. Running the following PowerShell reset once immediately restores dragging. After restarting Codex, the issue returns because a new pet overlay window is created.

    The workaround finds the visible Codex Chrome_WidgetWin_1 overlay with WS_EX_TOPMOST | WS_EX_TOOLWINDOW | WS_EX_LAYERED, temporarily removes WS_EX_LAYERED, forces a window refresh, waits 450 ms, then restores WS_EX_LAYERED and refreshes again.

    This does not require changing WS_EX_TRANSPARENT.

    Reset-Codex-Pet-Window.ps1

    param([switch]$Quiet)
    $ErrorActionPreference = 'Stop'
    try {
        $codexProcesses = @(Get-Process ChatGPT -ErrorAction SilentlyContinue | Where-Object { $_.Path -match '\\WindowsApps\\OpenAI\.Codex_[^\\]+\\app\\ChatGPT\.exe$' })
        if ($codexProcesses.Count -eq 0) { throw 'No running Store version of Codex was found. Open Codex and its pet first.' }
        Add-Type -TypeDefinition @"
    using System;
    using System.Text;
    using System.Runtime.InteropServices;
    using System.Collections.Generic;
    using System.Threading;
    public static class CodexPetLayerReset {
        delegate bool EnumCallback(IntPtr hwnd, IntPtr arg);
        [DllImport("user32.dll")] static extern bool EnumWindows(EnumCallback callback, IntPtr arg);
        [DllImport("user32.dll")] static extern uint GetWindowThreadProcessId(IntPtr hwnd, out uint processId);
        [DllImport("user32.dll")] static extern int GetClassName(IntPtr hwnd, StringBuilder value, int max);
        [DllImport("user32.dll")] static extern bool IsWindowVisible(IntPtr hwnd);
        [DllImport("user32.dll")] static extern bool IsWindow(IntPtr hwnd);
        [DllImport("user32.dll")] static extern int GetWindowLong(IntPtr hwnd, int index);
        [DllImport("user32.dll", SetLastError=true)] static extern int SetWindowLong(IntPtr hwnd, int index, int value);
        [DllImport("user32.dll")] static extern bool SetWindowPos(IntPtr hwnd, IntPtr after, int x, int y, int width, int height, uint flags);
        [DllImport("user32.dll")] static extern bool RedrawWindow(IntPtr hwnd, IntPtr rect, IntPtr region, uint flags);
        public static string Run(uint[] processIds) {
            var ids = new HashSet<uint>(processIds);
            var matches = new List<IntPtr>();
            EnumWindows((hwnd, arg) => {
                uint pid;
                GetWindowThreadProcessId(hwnd, out pid);
                if (!ids.Contains(pid) || !IsWindowVisible(hwnd)) return true;
                var name = new StringBuilder(256);
                GetClassName(hwnd, name, name.Capacity);
                int style = GetWindowLong(hwnd, -20);
                if (name.ToString() == "Chrome_WidgetWin_1" && (style & 0x80088) == 0x80088) matches.Add(hwnd);
                return true;
            }, IntPtr.Zero);
            if (matches.Count != 1) throw new Exception("Expected one visible Codex pet overlay; found " + matches.Count + ". No window was changed.");
            var target = matches[0];
            uint originalPid;
            GetWindowThreadProcessId(target, out originalPid);
            int original = GetWindowLong(target, -20);
            try {
                SetWindowLong(target, -20, original & ~0x80000);
                SetWindowPos(target, IntPtr.Zero, 0, 0, 0, 0, 0x37);
                RedrawWindow(target, IntPtr.Zero, IntPtr.Zero, 0x185);
                Thread.Sleep(450);
            } finally {
                uint currentPid;
                GetWindowThreadProcessId(target, out currentPid);
                if (IsWindow(target) && currentPid == originalPid) {
                    int current = GetWindowLong(target, -20);
                    SetWindowLong(target, -20, current | 0x80000);
                    SetWindowPos(target, IntPtr.Zero, 0, 0, 0, 0, 0x37);
                    RedrawWindow(target, IntPtr.Zero, IntPtr.Zero, 0x185);
                }
            }
            if (!IsWindow(target)) throw new Exception("The pet window closed during the reset. Reopen the pet.");
            if ((GetWindowLong(target, -20) & 0x80000) == 0) throw new Exception("Layered style restoration could not be verified. Close and reopen the pet.");
            return "Pet window composition reset. Layered style restored. Try clicking and dragging the pet. This does not prove interaction is fixed.";
        }
    }
    "@
        [CodexPetLayerReset]::Run([uint32[]]($codexProcesses | Select-Object -ExpandProperty Id))
    } catch {
        Write-Host $_.Exception.Message -ForegroundColor Red
    }
    if (-not $Quiet) { Read-Host 'Press Enter to close' | Out-Null }

    Since toggling only the layered/composition state reliably restores interaction for the current overlay HWND, it may be useful to inspect the pet overlay initialization/recreation path and whether the native hit-test/input shape is being refreshed after the layered window is created.

    — Don

  5. mxwu619-ship-it commented on Sep 7, 2026

    @mxwu619-ship-it

    I can reproduce this on Codex App 26.901.6511.0 (Windows x64, ChatGPT Plus) at 150% display scaling (GetDpiForWindow = 144; renderer processes use --device-scale-factor=1.5).

    Additional diagnostics from the click-through variant:

    • The overlay is Chrome_WidgetWin_1 / ChatGPT, normally ExStyle=0x000800A8.
    • Clearing only WS_EX_TRANSPARENT changes it to 0x00080088 and stops complete Win32 click-through, but does not restore the renderer pet hit target.
    • Direct WM_NCHITTEST returns HTCLIENT.
    • When hiding/showing or switching pets, the grab cursor can briefly appear far above/left of the rendered pet, then disappears.
    • During those layout transitions the overlay changed between about 772x720, 422x720, and 434x720, while DPI remained 144.
    • Changing pet size makes the offset worse.
    • Once the transient state expires, scanning the entire overlay yields only arrow/text-selection cursors and no active grab region.

    This looks consistent with stale or incorrectly converted renderer hit-region rectangles (CSS px / DIP / physical px) being reapplied after pet-size, hide/show, or layout changes, plus divergence between pointerInteractive, setIgnoreMouseEvents, and the native input shape.

    The WS_EX_LAYERED composition-reset workaround in the comment above is especially relevant: it suggests recreating/refreshing the layered surface also refreshes the missing or stale native input shape. A durable fix may need to recompute regions on DPI/display/pet-size/layout changes and reject stale region updates using a layout generation/revision.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    appIssues related to the Codex desktop appbugSomething isn't workingpetswindows-osIssues related to Codex on Windows systems

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions