Session UX: tray-controlled recording, no per-shot window hiding
Template tests / tests (push) Failing after 24s

Users couldn't click into the app mid-session: every automatic capture
hid the window for the shot, so it vanished under the cursor. Under
WSLg minimize() is a no-op and isFocused() sticks true, so neither can
be used for control.

- Sessions now hide the window once at start and show a red tray icon
  with Capture now / Pause-Resume / Open StepForge (auto-pauses) /
  Finish; finishing or quitting restores/cleans up properly
- Opening the app from the tray pauses capture; resuming tucks the
  window away again
- Automatic captures skip while the cursor is over a visible StepForge
  window (cursor-based, not focus-based, due to WSLg sticky focus)
- Per-shot latency reduced: with the window already hidden the 350 ms
  hide-repaint wait is skipped entirely
- OS notification announces the session; self-tests updated and green

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Iisyourdad
2026-06-10 22:51:01 -05:00
parent 52fd516a5d
commit 25bca7c3de
4 changed files with 134 additions and 4 deletions
+9
View File
@@ -105,6 +105,10 @@ function createWindow() {
try {
const guide = store.createGuide({ title: 'hotkey selftest' });
capture.startSession(guide.guideId, { intervalSec: 0 });
// Sessions hide the window while recording; do it immediately here
// instead of waiting out the toast-grace delay.
mainWindow.hide();
await new Promise((res) => setTimeout(res, 400));
const results = [];
for (let i = 0; i < 3; i++) {
const r = await capture.hotkeyCapture();
@@ -486,6 +490,11 @@ if (!gotLock) {
app.on('will-quit', () => {
globalShortcut.unregisterAll();
if (capture) {
// Targeted cleanup (not finishSession — that re-shows the window).
capture.stopClickWatcher();
capture.destroySessionTray();
}
// clean preview temp files on close
try {
for (const entry of fs.readdirSync(store.tempDir)) {