fix: harden restart_claude_desktop across platforms (#33)
- Linux (and any non-desktop platform): refuse instead of 'pkill claude', which substring-matched running Claude Code CLI sessions and relaunched the CLI, not a desktop app. New restart_supported() gates the button. - macOS: wait (<=5s) for the old instance to exit before 'open -a Claude' so the relaunch can't re-activate the dying process. Runs off the UI thread via a RestartWorker. - Windows: verify the Start-menu shortcut exists BEFORE taskkill, so an MSIX/Store install is never killed without a relaunch path. Closes #33 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1423,6 +1423,17 @@ class AboutDialog(QDialog):
|
||||
QDesktopServices.openUrl(QUrl(self._release_url or core.RELEASES_URL))
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Restart worker: core.restart_claude_desktop() blocks up to ~5 s on macOS
|
||||
# waiting for the old instance to exit, so it must run off the UI thread.
|
||||
# --------------------------------------------------------------------------- #
|
||||
class RestartWorker(QThread):
|
||||
done = Signal(object) # core.RestartResult
|
||||
|
||||
def run(self):
|
||||
self.done.emit(core.restart_claude_desktop())
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Main window
|
||||
# --------------------------------------------------------------------------- #
|
||||
@@ -2284,18 +2295,30 @@ class MainWindow(QMainWindow):
|
||||
def _offer_restart_button(self):
|
||||
"""Show the 'Restart Claude Desktop' button after a successful save,
|
||||
but only when the just-saved profile is Claude Desktop -- restarting
|
||||
makes no sense for Claude Code, which has no GUI process to bounce."""
|
||||
if self.current_profile and core.profile_targets_claude_desktop(self.current_profile):
|
||||
makes no sense for Claude Code, which has no GUI process to bounce --
|
||||
and only on platforms where Claude Desktop exists (never Linux, where
|
||||
'claude' is the Claude Code CLI)."""
|
||||
if (
|
||||
self.current_profile
|
||||
and core.profile_targets_claude_desktop(self.current_profile)
|
||||
and core.restart_supported()
|
||||
):
|
||||
self.restart_btn.show()
|
||||
else:
|
||||
self.restart_btn.hide()
|
||||
|
||||
def _restart_claude_desktop(self):
|
||||
self.restart_btn.setEnabled(False)
|
||||
try:
|
||||
result = core.restart_claude_desktop()
|
||||
finally:
|
||||
self.restart_btn.setEnabled(True)
|
||||
self.restart_btn.setText("Restarting…")
|
||||
# Held on self (MainWindow outlives the worker); replaced only after
|
||||
# done re-enables the button, so a running thread is never dropped.
|
||||
self._restart_worker = RestartWorker()
|
||||
self._restart_worker.done.connect(self._on_restart_done)
|
||||
self._restart_worker.start()
|
||||
|
||||
def _on_restart_done(self, result):
|
||||
self.restart_btn.setEnabled(True)
|
||||
self.restart_btn.setText("Restart Claude Desktop")
|
||||
self.restart_btn.hide()
|
||||
if result.success:
|
||||
self.status.setText(f"{self.status.text()} · {result.detail}")
|
||||
|
||||
Reference in New Issue
Block a user