Files
makelore/.project-docs/30-worklog/tasks/20260929-window-close-58c6a9de.md
T

8.5 KiB

Task: Fix native window close and macOS fullscreen lifecycle

Identity

  • Task ID: 20260929-window-close-58c6a9de
  • Mode: Feature
  • Branch: codex/20260929-window-close-58c6a9de-window-close
  • Worktree: /Users/chillishark/Makelore 麦洛/.codex-worktrees/makelore/20260929-window-close-58c6a9de
  • Base commit: f443f3bc66
  • Owner: codex
  • Status: Ready for Integration

Scope

  • Implement native macOS red close as real window destruction, preserving yellow minimize and green native zoom/fullscreen; fix closing from fullscreen and reopening all window-bound services.

Intent And Constraints

  • User explicitly approved changing code after red-close left a black fullscreen Space; manually exiting fullscreen cleared it. The follow-up explicitly authorizes merging this completed fix into local main. Do not replace the installed or running trial app, push, publish, or alter concurrent teacher-composer work. Preserve active Main-owned tasks, authentication, project data and persisted drafts.

Outcome

  • macOS red close now destroys the window. Fullscreen close waits for native leave-full-screen before closing; repeated close requests are coalesced and Cmd+Q retains the existing quit lifecycle. Yellow minimize and green native zoom/fullscreen behavior are preserved. Windows/Linux retain close-to-tray.
  • Main-owned Host API, coding runtime, authentication and task leases remain alive without a window. Dock activation, tray and menu recreate the window with current IPC/dialog owners, updater notifications and browser presentation callbacks; renderer leases are isolated by WebContents and released on destruction.
  • The shared browser module survives window replacement, while each native view retains its original owner. Reopening waits for old preview cleanup; an already cancelled open cannot create a late view or clear its successor. Missing host-window mount failures clean up their view.
  • README describes the native control behavior. Code commit b5e6c66 was fast-forwarded into local main on the user's follow-up request. Installed and running trial apps were not updated; nothing was pushed.

Verification

  • Focused unit verification: 152 passing tests across 12 distinct files covering native close, focus/quit, reopen IPC/menu/tray/dialogs, browser adapter/core/routes, background lifecycle and updater. The final browser core/routes run passed 97 tests. Three delayed-cleanup regressions cover close/reopen, preview replacement and project switching; the latter two failed before the epoch fix (unexpected generation 3 and stale-operation rejection) and passed after it. A fourth regression covers view cleanup on mount failure.
  • Two real macOS Electron E2E passed after the final build (11.8 seconds): three window generations/two closes, surviving Main PID, working minimize/zoom and IPC, new native preview attachment/events, old preview destruction, native leave-full-screen before closed, reopened normal window and clean app.quit exit. Fixtures use isolated temporary HOME/userData and loopback preview, never the running user apps.
  • corepack pnpm run typecheck passed. Scoped ESLint across every changed TypeScript file, build:vite and git diff --check passed.
  • Expanded Main typecheck remains blocked by 66 pre-existing diagnostics. An independent exact-base archive comparison against f443f3bc66 found 66 identical diagnostics, zero added/removed (normalizing source line/column and checkout paths); final rerun matched. Logs: /tmp/makelore-window-close-main-types-final.txt and /tmp/makelore-window-close-build-final.log.
  • Independent review found and verified the now-fixed close/open race; final review found no remaining blocking findings. Project-doc structure and task-aware drift checks passed.

Follow-ups

  • Local main code merge is complete. Rebuild/update the intended app or push only when requested. Post-merge worktree cleanup was offered separately; retain the checkout unless explicitly approved.
  • Expanded Main TypeScript baseline errors remain outside this task.

Promotion Candidates

  • Targets: .project-docs/30-worklog/current-state.md and .project-docs/20-architecture/system-overview.md. Proposal: record macOS red-close/window-recreation semantics and the process-owned services / window-owned presentation boundary. Evidence: user explicitly approved red close with yellow/green preserved, focused unit coverage and native macOS E2E. Future impact: new services must resolve the current window dynamically and retain active Main leases when windows close; they must not dispose process-scoped runtimes on window destruction. Semantic conflicts: replaces the prior macOS hide-on-close implementation; no accepted ADR requires that behavior. Human confirmation: already supplied for this product change; canonical promotion remains for an integration task.

Project Context Loaded

  • Task: 20260929-window-close-58c6a9de; feature mode; owned branch codex/20260929-window-close-58c6a9de-window-close; owned worktree as Identity; base f443f3bc66. Ownership start/status passed.
  • Read: AGENTS.md; entry read-before-planning, memory-index and planning-gate; active record; positioning; integrated current-state; decision index and lifecycle/ADR-006 references; system-overview/module-map/data-flow; business-rules; success-criteria; evidence/reflection/commitments indexes. Large historical documents were read with task-relevant lifecycle sections independently reviewed by a subagent.
  • Project: Main owns system integration and background work; Renderer consumes snapshots. Existing product has Code, Canvas, Robot and published teacher identities. Template placeholders remain in early positioning and are not task authority. Latest user-approved shortcuts/publishing stay untouched.
  • Other local tasks: task-context registry reviewed, with every peer task record read for scope/constraints/promotions. Active teacher-composer work is isolated and concerns teacher input/model contracts; old help-label patch and trial/publication tasks must not be overwritten. Other ready tasks are read-only. No native-close semantic conflict.
  • Relevant constraints: active/uncertain runs retain Main leases while window is absent; close removes native preview view/debugger and renderer leases only; reopening hydrates snapshots and never replays mutations. Cmd+Q retains bounded shutdown. No accepted ADR requires close-to-hide on macOS.
  • Evidence: installed Main intercepts close with preventDefault + hide without fullscreen lifecycle; exiting fullscreen restored user desktop. Green controls remain native.
  • Modules: Main index/close lifecycle, window-bound IPC/dialogs/tray/menu/updater, native browser adapter, focused unit and Electron tests.
  • Gate: Passed.

Plan

  1. Separate process services from recreatable window bindings; implement safe fullscreen close.
  2. Cover repeat close, reopen, leases, dialogs and preview attachment; run focused unit tests, typecheck/lint/build and isolated Electron tests.
  3. Review diff, record verified results and prepare a commit/patch for integration.

Main Merge Follow-up

  • Authorization: user explicitly requested merging the code into main. Same-task resume uses the existing feature worktree/branch/base in Identity; start and matching status passed.
  • Context: entry and task record re-read; canonical context previously loaded is unchanged from base f443f3b. Independently re-read all peer Scope/Intent/Promotion sections. Teacher-prompt-buttons is isolated UI work and explicitly excludes main merge; child-language has unspecified scope but no concrete dependency. No native-close semantic conflict.
  • Main and source were clean; main f443f3b is the direct parent of b5e6c66 (0/1 divergence). Product code is exactly the already-verified source, so tests need not be rerun for this fast-forward.
  • Canonical integration remains reserved by historical task 20260923-classroom-integration-8b4f1e62. Preserve that ownership, branch and checkout. This follow-up lands feature code and updates only its own task record; canonical promotions remain pending.
  • Gate: Passed for the user-authorized feature landing, without canonical reconciliation.
  • Plan: fast-forward clean main to b5e6c66, record the actual merge result, commit this task record and fast-forward its documentation; verify clean main and source ancestry, then complete the task registry.
  • Result: main fast-forwarded f443f3b → b5e6c66 without conflicts. No unrelated feature commits, canonical documents or peer records were imported. Source product code remains exactly the tested b5e6c66 tree. This final task-record update is the only subsequent change.