Skip to content

fix: apply host app rules to nested UI apps like Docker Desktop (#25) - #26

Merged
mahirozdin merged 1 commit into
mainfrom
fix/issue-25-investigation
Nov 4, 2026
Merged

mahirozdin merged 1 commit into
mainfrom
fix/issue-25-investigation

Conversation

@mahirozdin

Copy link
Copy Markdown
Owner

Problem (#25)

Ignore-list entries and per-app rules for Docker Desktop (com.docker.docker) had no effect, so SmartClose still quit Docker Desktop.

I inspected the Docker Desktop 4.98.0 arm64 DMG to find the cause:

Bundle Bundle ID Role
Docker.app com.docker.docker Faceless backend (LSUIElement=true) with no windows
Docker.app/Contents/MacOS/Docker Desktop.app com.electron.dockerdesktop Electron UI that owns every window

SmartClose resolves rules against the window owner's bundle ID, so a rule for com.docker.docker never matched.

Fix

  • HostAppResolver finds the app bundle that encloses the window owner. It treats that bundle as a host only when it is faceless (LSUIElement or LSBackgroundOnly). Regular apps that bundle other apps, such as Xcode with Simulator and Instruments, are not hosts, so their rules do not leak onto those apps. Results are cached per bundle path, and the lookup runs only after a close button is detected.
  • Hard exclusions, the allow list, and the ignore list match either ID. An exclusion can only fall back to the system's normal close.
  • Per-app rules and Cmd+W overrides prefer the window owner's own rule (exact, then the longest wildcard) and fall back to the host's rule.
  • The red close button path and the Cmd+W path both use the host. Diagnostics name the host when its rule decided the outcome.
  • Docs: FAQ and decision-engine. CHANGELOG updated.

Existing setups behave the same unless a rule names a faceless host app.

Verification

  • xcodebuild test -only-testing:SmartCloseTests on macOS 27.0.1 / Xcode 27.0: 84 tests, 0 failures, including 16 new tests (Docker ignore/per-app/allow list, own-rule precedence, wildcard, Cmd+W, Xcode-style regular host ignored, caching).
  • A real Bundle(url:) check against a fake bundle tree with Docker's layout: host resolved to com.docker.docker. Simulator inside a regular Xcode.app and top-level Safari both resolved to nil.
  • Not tested with a running Docker Desktop (not installed on the test Mac).

CI: local checks PASS.

Fixes #25

…e 25 regression tests, docs

Docker Desktop's windows belong to com.electron.dockerdesktop, nested inside the faceless
Docker.app agent (com.docker.docker). Rules written for com.docker.docker never matched, so
SmartClose still quit Docker Desktop.

- HostAppResolver finds the enclosing app bundle and treats it as a host only when it is
  faceless (LSUIElement / LSBackgroundOnly); regular apps such as Xcode do not leak rules onto
  bundled apps like Simulator. Results are cached per bundle path.
- Exclusions (hard, allow list, ignore list) match either id; per-app rules and Cmd+W
  overrides prefer the window owner's own rule and fall back to the host's.
- Red close button and Cmd+W paths both pass the host; diagnostics name the host when its
  rule decided the outcome.

Fixes #25
@mahirozdin
mahirozdin merged commit 46c7c84 into main Nov 4, 2026
2 checks passed
@mahirozdin
mahirozdin deleted the fix/issue-25-investigation branch November 4, 2026 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SmartClose closes Docker Desktop even when added to ignore list or per-app Rules

1 participant