Commit Graph
12 Commits
Author SHA1 Message Date
devsyncwrld d525bbb8c5 feat(desktop): capture system audio with process isolation
Electron's audio: 'loopback' captures the whole output mix, this app's own
playback included — so everyone else's voices went back out inside the share
and each listener heard themselves. Not acoustic echo but a digital copy of
the output, which is why headphones never helped, and why shareAudio already
defaulted to off in the desktop app.

Electron offers no way to exclude our own audio: the docs allow only
'loopback' or 'loopbackWithMute', and the handler discards the renderer's
constraints (restrictOwnAudio never arrives). electron-native-screenshare does
it at the OS level — WASAPI process loopback on Windows — capturing only the
shared window when its pid resolves, and otherwise everything except us.

The module hands raw PCM to the main process, so it crosses IPC and is
scheduled onto a running cursor in Web Audio to become a MediaStreamTrack,
published as ScreenShareAudio. Loading is optional and failure degrades to a
silent share rather than blocking the app or the screen share.

The browser path is untouched: Chrome honours restrictOwnAudio and has no echo.

Verified by typecheck (web and Electron main) and the web suite. The audio path
itself cannot be exercised here — no Windows, no Electron, no audio device.
2026-09-01 00:56:34 -03:00
Jannis Braun ece81a2b71 feat(desktop): add recovery bridge methods to preload + types
- rendererReady (boot-completion ping)
- getRecoveryState / onRecoveryStateChanged (recovery.html subscribers)
- recoveryAction (button click dispatcher with enum action)

Type declarations kept ambient (no export) to preserve window.backspace
global augmentation — exporting from an ambient .d.ts converts it to a
module and breaks the Window interface extension.
2026-05-03 11:57:51 +02:00
Jannis Braun b00d21df0e feat(desktop): preload exposes setConnectedOrigins + onOpenInternalRoute 2026-04-29 22:07:26 +02:00
Jannis Braun c6d345048a feat(keybinds): add useKeybinds hook with Electron IPC bridge and web fallback 2026-03-22 20:35:31 +01:00
Jannis Braun 0f4f129337 feat(desktop): add automatic game/app activity detection
Add cross-platform process scanning that detects running games and apps,
then broadcasts them as Rich Presence activities via the existing Phase 1
pipeline (activityStore -> WS -> other users).

- games.json dictionary with 26 entries (games, Spotify, VLC, OBS)
- activityDetector module: polls OS process list every 15s via execFile,
  matches against dictionary, emits IPC on state change only
- IPC bridge in main.ts/preload.ts with cleanup on quit
- Frontend activityBridge subscribes to IPC and feeds activityStore
- Supports Windows (tasklist CSV), macOS (ps -c), Linux (ps)
2026-03-21 02:57:30 +01:00
Jannis Braun 6ebb124d25 feat(desktop): update preload bridge types for enhanced update-error and getVersion 2026-03-21 02:30:06 +01:00
Jannis Braun ac7d3cb71b feat: add start-at-boot setting and fix tray icon to use app logo
Add auto-launch settings (start at boot + start minimized) to the
Desktop section in Account settings, using Electron's built-in
setLoginItemSettings API across macOS, Windows, and Linux.

Replace the fallback colored-circle tray icon with proper B logo assets:
template images for macOS (adapts to light/dark menu bar) and colored
icons for Windows/Linux. Fix BGRA channel order bug in fallback generator
and move tray icons to resources/ so they're packaged into the app.
2026-03-17 02:28:38 +01:00
Jannis Braun bda7930e61 fix: restore setDisplayMediaRequestHandler with useSystemPicker
Electron requires setDisplayMediaRequestHandler for getDisplayMedia() to
work — removing it broke screen sharing entirely. Restored the handler
with useSystemPicker: true, which on macOS 15+ uses the native system
picker (honoring restrictOwnAudio), while Windows/Linux fall back to
the custom picker with the shareAudio toggle for echo control.
2026-03-16 18:34:50 +01:00
Jannis Braun 9ff3761640 fix: remove setDisplayMediaRequestHandler to let restrictOwnAudio work natively
The custom screen share picker intercepted getDisplayMedia() and created
a raw loopback stream, bypassing Chromium's constraint pipeline entirely.
restrictOwnAudio was silently discarded. Removing the handler lets
Chromium 144's native getDisplayMedia run end-to-end with restrictOwnAudio
applied, eliminating the audio feedback loop in the desktop app.
2026-03-16 18:18:42 +01:00
Jannis Braun 46f55643ae fix: eliminate screen share audio feedback loop + upgrade Electron 33→40
Screen sharing with audio captured the app's own voice playback, causing
users to hear themselves echoed back. Fixed via two layers:

- Add restrictOwnAudio constraint (Chrome 141+/Chromium 144) to exclude
  the app's own audio from system audio capture
- Add shareAudio toggle so users can disable system audio entirely
- Remove outdated macOS audio block (now supported via ScreenCaptureKit)
- Upgrade Electron 33→40 (Chromium 130→144) so restrictOwnAudio works
  natively in the desktop app
- Add NSAudioCaptureUsageDescription for macOS 14.2+ audio capture
- Add GTK 3 fallback for Linux GNOME compatibility (Electron 36+)
2026-03-16 18:01:40 +01:00
Jannis Braun 95ec3ff952 feat: Electron screen share picker, instance selector, and system audio loopback
- Custom screen share picker for Electron (ScreenSharePicker.tsx) with
  Aether Drift design: glass-bubble footer, adaptive grid, pill tabs,
  border-based selection (avoids overflow clipping), hover brightness
- Instance URL picker so Electron connects to any Backspace server
- System audio loopback on Windows/Linux via desktopCapturer callback
- macOS: video-only callback (OS blocks system audio capture)
- IPC bridge for screen source enumeration and selection
- Purge stale service worker caches on Electron launch
2026-03-16 03:50:07 +01:00
Jannis Braun 8ae3ffc912 feat: Electron desktop app — hardening, IPC bridge, and dev launch fixes
- Dev/prod URL auto-detection (Vite 5173 in dev, server 3000 in prod)
- Typed IPC bridge via preload (notifications, badge, window controls, updates, deep links)
- Native OS notifications via NotificationController with window focus suppression
- Auto-update via electron-updater with UpdateToast UI
- Deep linking (backspace:// protocol) for macOS and Windows/Linux
- Window state persistence (position, size, maximize across restarts)
- Tray icon with graceful fallback when icon asset missing
- Suppress PWA service worker polling/reloads inside Electron
- Platform detection layer (isElectron, getElectronAPI)
- Root workspace scripts (dev:desktop, build:desktop)
- Document BACKSPACE_URL and BACKSPACE_UPDATE_URL env vars
2026-03-16 00:10:47 +01:00