5 Commits
Author SHA1 Message Date
471dd56640 feat(windows): cross target, and quit ui-host with WM_QUIT instead of hard-killing it (#23)
* feat(windows): wire the view-module-runtime for x86_64-windows

Routes through logos-nix.lib.forAllTargets, widens meta.platforms, and
picks up Qt's host-tool cmake flags (empty natively).

wrapQtAppsHook is GATED rather than removed: it fails to EVALUATE for a
mingw host, and wrap-qt-apps-hook.sh would skip a PE anyway
(`isELF || isMachO || continue`) -- but removing it outright would change
native behaviour. dontWrapQtApps = true is the mandatory other half, or
qtbase's own setup hook hard-errors with "depends on qtbase, but no
wrapping behavior was specified".

Windows and native (aarch64-darwin) both evaluate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(windows): quit ui-host with WM_QUIT instead of hard-killing it

QProcess::terminate() cannot stop ui-host on Windows, so every UI-plugin
teardown paid the full 3s grace period and then TerminateProcess.

MEASURED, not inferred. terminate() on Windows is EnumWindows(WM_CLOSE) plus
PostThreadMessage(tid, WM_CLOSE) (qprocess_win.cpp:648-653). ui-host owns ZERO
windows -- it is a bare QCoreApplication linking no Qt6::Gui at all
(ui-host/main.cpp:70, CMakeLists.txt:78-86); the QQuickWidget lives in the
PARENT and ui-host only remotes the plugin object over QtRO. So the enumeration
finds nothing. A controlled zero, not a broken command: the same enumeration in
the same run found 7 windows for Basecamp, including the two never-shown QPA
observer windows a GUI process must own. The thread message IS delivered, but
Qt's dispatcher only branches on WM_QUIT (qeventdispatcher_win.cpp:545-548) --
WM_CLOSE falls through to a no-op for a thread message. terminate() returns
void, so it "succeeds" having done nothing.

A/B against the shipped ui-host.exe: replicating terminate() byte-exactly left
it ALIVE past the full 3000ms; PostThreadMessage(WM_QUIT) exited it in 8ms with
code 0. End to end through the real teardown path (graceful Basecamp quit with
package_manager_ui loaded), same harness and trigger, only the payload differing:

  shipped   ui-host exit 3905ms  code 62097 (0xF291 Qt kill)  "did not exit gracefully" present
  fixed     ui-host exit  690ms  code 0                       warning absent
  (Basecamp total 4395ms -> 1186ms)

REPLACES terminate() on Windows rather than preceding it. An earlier draft
inserted WM_QUIT above the existing terminate()+3000+kill+1000, which would have
made the worst case 6000ms -- worse than today while claiming to improve it.
Since terminate() was measured to be dead time here, keeping it buys nothing:
the ceiling stays 4000ms and the typical case is now sub-second. This also
matches logos-container-subprocess, which REPLACES its equally no-op
request_exit() rather than supplementing it.

The POSIX path is byte-identical -- the original block is preserved verbatim
inside #else; git diff shows zero removed lines.

Getting the child's main THREAD id is the one subtle part. QProcess does not
expose it, but CreateProcessArguments carries the PROCESS_INFORMATION pointer it
hands to CreateProcess. The modifier runs BEFORE CreateProcess, so dwThreadId is
not populated yet: capture the pointer there, read through it once started() has
fired, and null it immediately -- QProcess owns that allocation and frees it in
cleanup(). No CreateProcessW reimplementation and no Toolhelp32 snapshot needed.

NOT fixed here, deliberately: orphan reaping is absent on Windows. ui-host's
setsid + PR_SET_PDEATHSIG + getppid watchdog are wholly inside #ifndef _WIN32
(ui-host/main.cpp:40-68) and ViewModuleHost assigns no Job Object, so a Basecamp
crash leaks ui-host.exe. That is a real second defect, but it is an untested
process-lifetime change and does not belong bundled into a latency fix.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* chore(deps): re-pin the L1-L4 inputs to their merged revs

logos-nix (L1), logos-protocol (L2), logos-cpp-sdk (L3) and logos-qt-sdk (L4)
are all on their default branches now, so the lock can name the merged revs
instead of the pre-merge branch tips it was resolving against while those PRs
were open.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-11 14:49:08 -03:00
Khushboo Mehta 96735cb9c8 fix: Pass per-spawn auth token to ui-host via private socket 2026-06-10 21:00:03 +02:00
Khushboo Mehta d611d697bf Revert "fix: handle long module names"
This reverts commit 1b35afb543.
2026-04-17 15:09:42 +02:00
Khushboo Mehta 1b35afb543 fix: handle long module names 2026-04-17 13:56:59 +02:00
Khushboo Mehta d9fa197f87 feat: add src headers and flake files needed 2026-04-08 22:27:19 +02:00