Skip to content

fix(wework): make close-to-tray action responsive - #2621

Merged
qdaxb merged 2 commits into
mainfrom
fix/close-to-tray-action
Aug 12, 2026
Merged

qdaxb merged 2 commits into
mainfrom
fix/close-to-tray-action

Conversation

@qdaxb

@qdaxb qdaxb commented Aug 12, 2026 •

Copy link
Copy Markdown
Contributor

What changed

  • close the first-run close-to-tray confirmation immediately when the user selects Move to background
  • move the acknowledgement persistence into the native close-to-tray command
  • keep window closure independent from a preference-write failure while logging the persistence failure
  • add regression coverage and update the Chinese and English desktop preference documentation

Root cause

The renderer waited for a separate update_app_preferences IPC call before invoking the native close-to-tray command. If that preference write stalled or failed, the native window close was never attempted and the dialog appeared unresponsive.

User impact

Selecting Move to background now responds immediately. The main window closes to the system tray while running tasks and the executor continue in the background. If native closure fails, the confirmation reappears so the user can retry.

Validation

  • pnpm --filter wework test src/features/workbench/RuntimeTaskCloseGuard.test.tsx src/tauri/runtimeTaskCloseGuard.test.ts
  • pnpm --filter wework exec prettier --check ...
  • pnpm --filter wework exec eslint ...
  • cargo fmt --manifest-path wework/src-tauri/Cargo.toml -- --check
  • cargo check --manifest-path wework/src-tauri/Cargo.toml
  • isolated real-Tauri verification with ai:verify: request close, confirm the dialog, click Move to background, verify windowWillClose and persisted acknowledgement
  • full pre-push Wework ESLint, TypeScript, and unit-test suite

Summary by CodeRabbit

  • Bug Fixes

    • Improved the “Move to background” flow so the confirmation closes immediately after selection.
    • The main window now moves to the system tray after confirmation.
    • If closing the window fails, the confirmation reappears so the action can be retried.
    • The preference is saved before the window closes, while save issues no longer block the tray transition.
  • Tests

    • Added coverage for immediate dialog dismissal and a single close attempt.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@qdaxb, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 2 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f993a10c-5de0-4690-a9e4-c04c30e1b39a

📥 Commits

Reviewing files that changed from the base of the PR and between a32c48e and a44c020.

📒 Files selected for processing (2)
  • wework/src-tauri/src/lib.rs
  • wework/src/features/workbench/RuntimeTaskCloseGuard.test.tsx
📝 Walkthrough

Walkthrough

The close-to-tray confirmation now closes before the native window transition. Failed native closure reopens the confirmation. The native command records the acknowledgement and logs preference persistence failures.

Changes

Close-to-tray behavior

Layer / File(s) Summary
Confirmation dismissal and retry flow
wework/src/features/workbench/RuntimeTaskCloseGuard.tsx, wework/src/features/workbench/RuntimeTaskCloseGuard.test.tsx, docs/en/.../desktop-app-preferences.md, docs/zh/.../desktop-app-preferences.md
The confirmation closes before closeMainWindowToTray runs. The test verifies dismissal and one native command call. English and Chinese guides document the retry behavior.
Native acknowledgement persistence
wework/src-tauri/src/lib.rs
close_main_window_to_tray records the acknowledged preference before destroying the main window. Persistence failures are logged.

Estimated code review effort: 2 (Simple) | ~10 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant RuntimeTaskCloseGuard
  participant Tauri
  participant SystemTray
  User->>RuntimeTaskCloseGuard: Select Move to background
  RuntimeTaskCloseGuard->>RuntimeTaskCloseGuard: Close confirmation
  RuntimeTaskCloseGuard->>Tauri: Invoke close_main_window_to_tray
  Tauri->>Tauri: Persist close_to_tray_hint_seen
  Tauri->>SystemTray: Move main window to tray
  Tauri-->>RuntimeTaskCloseGuard: Return close result
  RuntimeTaskCloseGuard->>RuntimeTaskCloseGuard: Reopen confirmation if closing fails
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: making the close-to-tray action respond immediately.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/close-to-tray-action

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@qdaxb
qdaxb enabled auto-merge August 12, 2026 09:20

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@wework/src-tauri/src/lib.rs`:
- Around line 3250-3256: Serialize the read-modify-write sequence around
read_app_preferences_impl and write_app_preferences_impl using the existing
application preference synchronization mechanism. Hold the guard across reading,
updating close_to_tray_hint_seen, and writing so concurrent or failed reads
cannot overwrite unrelated preferences.

In `@wework/src/features/workbench/RuntimeTaskCloseGuard.test.tsx`:
- Around line 45-60: Add tests alongside the existing RuntimeTaskCloseGuard
close-flow test to cover a pending and a rejected closeMainWindowToTray promise.
Configure the native command mock before clicking, assert the overlay closes
while the promise is pending and resolve it, then add a rejection case that
asserts the overlay reappears with the confirm button enabled for retry.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 44e60014-a288-45b2-8a39-74f35a60886c

📥 Commits

Reviewing files that changed from the base of the PR and between 7937acd and a32c48e.

📒 Files selected for processing (5)
  • docs/en/wegent/user-guide/settings/desktop-app-preferences.md
  • docs/zh/wegent/user-guide/settings/desktop-app-preferences.md
  • wework/src-tauri/src/lib.rs
  • wework/src/features/workbench/RuntimeTaskCloseGuard.test.tsx
  • wework/src/features/workbench/RuntimeTaskCloseGuard.tsx

Comment thread wework/src-tauri/src/lib.rs Resolved
Comment on lines +45 to +60

test('closes the dialog immediately and sends one native close-to-tray command', async () => {
render(<RuntimeTaskCloseGuard />)

await waitFor(() => expect(mocks.closeRequestHandler).toBeDefined())
act(() => {
mocks.closeRequestHandler?.()
})

fireEvent.click(screen.getByTestId('runtime-task-close-confirm-button'))

await waitFor(() =>
expect(screen.queryByTestId('runtime-task-close-confirm-overlay')).not.toBeInTheDocument()
)
await waitFor(() => expect(mocks.closeMainWindowToTray).toHaveBeenCalledTimes(1))
})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C 8 -i 'close.?to.?tray|move to background|runtime-task-close' \
  wework/e2e/desktop wework/src .github/workflows 2>/dev/null || true

rg -n -C 8 -i 'e2e/desktop|desktop.*e2e|task-flow' \
  .github/workflows 2>/dev/null || true

Repository: wecode-ai/Wegent

Length of output: 50372


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- AGENTS guidance ---'
if [ -f wework/AGENTS.md ]; then
  cat wework/AGENTS.md
fi

printf '%s\n' '--- component test and mock setup ---'
sed -n '1,140p' wework/src/features/workbench/RuntimeTaskCloseGuard.test.tsx
sed -n '1,120p' wework/src/features/workbench/RuntimeTaskCloseGuard.tsx

printf '%s\n' '--- E2E lifecycle flow ---'
sed -n '105,245p' wework/e2e/desktop/modules/window-attachment-flows.mjs

printf '%s\n' '--- E2E registration and CI references ---'
rg -n -C 4 'window.?lifecycle|window-attachment-flows|desktop.*e2e|e2e/desktop' \
  wework/e2e/desktop .github/workflows 2>/dev/null | head -n 240

Repository: wecode-ai/Wegent

Length of output: 40755


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- all close-command failure coverage ---'
rg -n -C 5 \
  'closeMainWindowToTray|close_main_window_to_tray|Failed to hide window after close-to-tray|runtime-task-close-confirm-overlay' \
  wework/src wework/e2e/desktop .github/workflows 2>/dev/null |
  grep -E -i 'closeMainWindowToTray|close_main_window_to_tray|Failed to hide window|runtime-task-close-confirm|window-lifecycle|task-flow|run-checkpoints|e2e:desktop' |
  head -n 320

printf '%s\n' '--- checkpoint dispatch ---'
sed -n '1,80p' wework/e2e/desktop/checkpoints.mjs
rg -n -C 8 \
  'run-checkpoints|--segment|e2e:desktop|task-flow.e2e.mjs' \
  .github/workflows wework/package.json package.json 2>/dev/null | head -n 320

printf '%s\n' '--- exact component test mock behavior ---'
python3 - <<'PY'
from pathlib import Path
p = Path('wework/src/features/workbench/RuntimeTaskCloseGuard.test.tsx')
text = p.read_text()
print('closeMainWindowToTray mock has implementation:', 'closeMainWindowToTray.mockImplementation' in text)
print('closeMainWindowToTray mock has resolved value:', 'closeMainWindowToTray.mockResolvedValue' in text)
print('closeMainWindowToTray mock has rejected value:', 'closeMainWindowToTray.mockRejectedValue' in text)
print('component awaits close command:', 'await closeMainWindowToTray()' in Path('wework/src/features/workbench/RuntimeTaskCloseGuard.tsx').read_text())
PY

Repository: wecode-ai/Wegent

Length of output: 17232


Add deferred and rejected native-command coverage.

The real-Tauri window-lifecycle checkpoint covers successful close-to-tray behavior and runs in CI. It does not cover a rejected closeMainWindowToTray call.

Configure a pending Promise before the click, assert that the overlay closes while it is pending, then resolve it. Add a rejected-Promise case that verifies the overlay reappears and the confirm button is enabled for retry.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@wework/src/features/workbench/RuntimeTaskCloseGuard.test.tsx` around lines 45
- 60, Add tests alongside the existing RuntimeTaskCloseGuard close-flow test to
cover a pending and a rejected closeMainWindowToTray promise. Configure the
native command mock before clicking, assert the overlay closes while the promise
is pending and resolve it, then add a rejection case that asserts the overlay
reappears with the confirm button enabled for retry.

Sources: Coding guidelines, Learnings

@qdaxb
qdaxb added this pull request to the merge queue Aug 12, 2026
@qdaxb
qdaxb removed this pull request from the merge queue due to a manual request Aug 12, 2026
@qdaxb
qdaxb enabled auto-merge August 12, 2026 09:52
@qdaxb
qdaxb added this pull request to the merge queue Aug 12, 2026
Merged via the queue into main with commit 8c0b079 Aug 12, 2026
65 checks passed
@qdaxb
qdaxb deleted the fix/close-to-tray-action branch August 12, 2026 10:59
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.

1 participant