Skip to content

Commit 7efaa6a

Browse files
Merge pull request #1389 from CapSoftware/release-fixes
Fixes for 0.3.84 from testing
2 parents 19cbc64 + 8602dc6 commit 7efaa6a

File tree

8 files changed

+124
-48
lines changed

8 files changed

+124
-48
lines changed

apps/desktop/src-tauri/src/target_select_overlay.rs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -268,16 +268,11 @@ impl WindowFocusManager {
268268
let cap_main = CapWindowId::Main.get(app);
269269
let cap_settings = CapWindowId::Settings.get(app);
270270

271-
let has_cap_main = cap_main
272-
.as_ref()
273-
.and_then(|v| Some(v.is_minimized().ok()? || !v.is_visible().ok()?))
274-
.unwrap_or(true);
275-
let has_cap_settings = cap_settings
276-
.and_then(|v| Some(v.is_minimized().ok()? || !v.is_visible().ok()?))
277-
.unwrap_or(true);
278-
279-
// Close the overlay if the cap main and settings are not available.
280-
if has_cap_main && has_cap_settings {
271+
let main_window_available = cap_main.is_some();
272+
let settings_window_available = cap_settings.is_some();
273+
274+
// Close the overlay if both cap windows are gone.
275+
if !main_window_available && !settings_window_available {
281276
window.hide().ok();
282277
break;
283278
}

apps/desktop/src-tauri/src/tray.rs

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
use crate::windows::ShowCapWindow;
2-
use crate::{RecordingStarted, RecordingStopped, RequestOpenSettings, recording};
1+
use crate::{
2+
RecordingStarted, RecordingStopped, RequestOpenRecordingPicker, RequestOpenSettings, recording,
3+
recording_settings::RecordingTargetMode, windows::ShowCapWindow,
4+
};
35

46
use std::sync::{
57
Arc,
@@ -18,6 +20,9 @@ use tauri_specta::Event;
1820

1921
pub enum TrayItem {
2022
OpenCap,
23+
RecordDisplay,
24+
RecordWindow,
25+
RecordArea,
2126
PreviousRecordings,
2227
PreviousScreenshots,
2328
OpenSettings,
@@ -29,6 +34,9 @@ impl From<TrayItem> for MenuId {
2934
fn from(value: TrayItem) -> Self {
3035
match value {
3136
TrayItem::OpenCap => "open_cap",
37+
TrayItem::RecordDisplay => "record_display",
38+
TrayItem::RecordWindow => "record_window",
39+
TrayItem::RecordArea => "record_area",
3240
TrayItem::PreviousRecordings => "previous_recordings",
3341
TrayItem::PreviousScreenshots => "previous_screenshots",
3442
TrayItem::OpenSettings => "open_settings",
@@ -45,6 +53,9 @@ impl TryFrom<MenuId> for TrayItem {
4553
fn try_from(value: MenuId) -> Result<Self, Self::Error> {
4654
match value.0.as_str() {
4755
"open_cap" => Ok(TrayItem::OpenCap),
56+
"record_display" => Ok(TrayItem::RecordDisplay),
57+
"record_window" => Ok(TrayItem::RecordWindow),
58+
"record_area" => Ok(TrayItem::RecordArea),
4859
"previous_recordings" => Ok(TrayItem::PreviousRecordings),
4960
"previous_screenshots" => Ok(TrayItem::PreviousScreenshots),
5061
"open_settings" => Ok(TrayItem::OpenSettings),
@@ -59,7 +70,28 @@ pub fn create_tray(app: &AppHandle) -> tauri::Result<()> {
5970
let menu = Menu::with_items(
6071
app,
6172
&[
62-
&MenuItem::with_id(app, TrayItem::OpenCap, "New Recording", true, None::<&str>)?,
73+
&MenuItem::with_id(
74+
app,
75+
TrayItem::OpenCap,
76+
"Open Main Window",
77+
true,
78+
None::<&str>,
79+
)?,
80+
&MenuItem::with_id(
81+
app,
82+
TrayItem::RecordDisplay,
83+
"Record Display",
84+
true,
85+
None::<&str>,
86+
)?,
87+
&MenuItem::with_id(
88+
app,
89+
TrayItem::RecordWindow,
90+
"Record Window",
91+
true,
92+
None::<&str>,
93+
)?,
94+
&MenuItem::with_id(app, TrayItem::RecordArea, "Record Area", true, None::<&str>)?,
6395
&PredefinedMenuItem::separator(app)?,
6496
// &MenuItem::with_id(
6597
// app,
@@ -109,6 +141,24 @@ pub fn create_tray(app: &AppHandle) -> tauri::Result<()> {
109141
.await;
110142
});
111143
}
144+
Ok(TrayItem::RecordDisplay) => {
145+
let _ = RequestOpenRecordingPicker {
146+
target_mode: Some(RecordingTargetMode::Display),
147+
}
148+
.emit(&app_handle);
149+
}
150+
Ok(TrayItem::RecordWindow) => {
151+
let _ = RequestOpenRecordingPicker {
152+
target_mode: Some(RecordingTargetMode::Window),
153+
}
154+
.emit(&app_handle);
155+
}
156+
Ok(TrayItem::RecordArea) => {
157+
let _ = RequestOpenRecordingPicker {
158+
target_mode: Some(RecordingTargetMode::Area),
159+
}
160+
.emit(&app_handle);
161+
}
112162
Ok(TrayItem::PreviousRecordings) => {
113163
let _ = RequestOpenSettings {
114164
page: "recordings".to_string(),

apps/desktop/src-tauri/src/windows.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,8 @@ impl ShowCapWindow {
224224
}
225225

226226
if let Some(window) = self.id(app).get(app) {
227+
window.show().ok();
228+
window.unminimize().ok();
227229
window.set_focus().ok();
228230
return Ok(window);
229231
}
@@ -636,7 +638,7 @@ impl ShowCapWindow {
636638
.maximized(false)
637639
.resizable(false)
638640
.fullscreen(false)
639-
.shadow(true)
641+
.shadow(!cfg!(windows))
640642
.always_on_top(true)
641643
.transparent(true)
642644
.visible_on_all_workspaces(true)

apps/desktop/src/routes/(window-chrome)/new-main/MicrophoneSelect.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import { cx } from "cva";
44
import {
55
type Component,
66
type ComponentProps,
7+
createEffect,
78
createSignal,
8-
onMount,
99
Show,
1010
} from "solid-js";
1111
import { trackEvent } from "~/utils/analytics";
@@ -83,12 +83,10 @@ export function MicrophoneSelectBase(props: {
8383
const audioLevel = () =>
8484
(1 - Math.max((dbs() ?? 0) + DB_SCALE, 0) / DB_SCALE) ** 0.5;
8585

86-
// Initialize audio input if needed - only once when component mounts
87-
onMount(() => {
86+
createEffect(() => {
8887
if (!props.value || !permissionGranted() || isInitialized()) return;
8988

9089
setIsInitialized(true);
91-
// Ensure the selected microphone is activated so levels flow in
9290
void handleMicrophoneChange({ name: props.value });
9391
});
9492

apps/desktop/src/routes/(window-chrome)/new-main/index.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ import {
5353
type CaptureWindowWithThumbnail,
5454
commands,
5555
type DeviceOrModelID,
56+
type RecordingTargetMode,
5657
type ScreenCaptureTarget,
5758
} from "~/utils/tauri";
5859
import IconLucideAppWindowMac from "~icons/lucide/app-window-mac";
@@ -434,10 +435,13 @@ function Page() {
434435
createUpdateCheck();
435436

436437
onMount(async () => {
437-
const targetMode = (window as any).__CAP__.initialTargetMode;
438+
const { __CAP__ } = window as typeof window & {
439+
__CAP__?: { initialTargetMode?: RecordingTargetMode | null };
440+
};
441+
const targetMode = __CAP__?.initialTargetMode ?? null;
438442
setOptions({ targetMode });
439-
if (rawOptions.targetMode) commands.openTargetSelectOverlays(null);
440-
else commands.closeTargetSelectOverlays();
443+
if (targetMode) await commands.openTargetSelectOverlays(null);
444+
else await commands.closeTargetSelectOverlays();
441445

442446
const currentWindow = getCurrentWindow();
443447

@@ -616,6 +620,12 @@ function Page() {
616620
const setCamera = createCameraMutation();
617621

618622
onMount(() => {
623+
if (rawOptions.micName) {
624+
setMicInput
625+
.mutateAsync(rawOptions.micName)
626+
.catch((error) => console.error("Failed to set mic input:", error));
627+
}
628+
619629
if (rawOptions.cameraID && "ModelID" in rawOptions.cameraID)
620630
setCamera.mutate({ ModelID: rawOptions.cameraID.ModelID });
621631
else if (rawOptions.cameraID && "DeviceID" in rawOptions.cameraID)

apps/desktop/src/routes/editor/Player.tsx

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -382,52 +382,58 @@ function PreviewCanvas() {
382382
<Show when={latestFrame()}>
383383
{(currentFrame) => {
384384
const padding = 4;
385+
const frameWidth = () => currentFrame().width;
386+
const frameHeight = () => currentFrame().data.height;
385387

386-
const containerAspect = () => {
387-
if (containerBounds.width && containerBounds.height) {
388-
return (
389-
(containerBounds.width - padding * 2) /
390-
(containerBounds.height - padding * 2)
391-
);
392-
}
388+
const availableWidth = () =>
389+
Math.max((containerBounds.width ?? 0) - padding * 2, 0);
390+
const availableHeight = () =>
391+
Math.max((containerBounds.height ?? 0) - padding * 2, 0);
393392

394-
return 1;
393+
const containerAspect = () => {
394+
const width = availableWidth();
395+
const height = availableHeight();
396+
if (width === 0 || height === 0) return 1;
397+
return width / height;
395398
};
396399

397-
const frameAspect = () =>
398-
currentFrame().width / currentFrame().data.height;
400+
const frameAspect = () => {
401+
const width = frameWidth();
402+
const height = frameHeight();
403+
if (width === 0 || height === 0) return containerAspect();
404+
return width / height;
405+
};
399406

400407
const size = () => {
408+
let width: number;
409+
let height: number;
401410
if (frameAspect() < containerAspect()) {
402-
const height = (containerBounds.height ?? 0) - padding * 1;
403-
404-
return {
405-
width: height * frameAspect(),
406-
height,
407-
};
411+
height = availableHeight();
412+
width = height * frameAspect();
413+
} else {
414+
width = availableWidth();
415+
height = width / frameAspect();
408416
}
409417

410-
const width = (containerBounds.width ?? 0) - padding * 2;
411-
412418
return {
413-
width,
414-
height: width / frameAspect(),
419+
width: Math.min(width, frameWidth()),
420+
height: Math.min(height, frameHeight()),
415421
};
416422
};
417423

418424
return (
419425
<div class="flex overflow-hidden absolute inset-0 justify-center items-center h-full">
420426
<canvas
421427
style={{
422-
width: `${size().width - padding * 2}px`,
428+
width: `${size().width}px`,
423429
height: `${size().height}px`,
424430
...gridStyle,
425431
}}
426432
class="rounded"
427433
ref={canvasRef}
428434
id="canvas"
429-
width={currentFrame().width}
430-
height={currentFrame().data.height}
435+
width={frameWidth()}
436+
height={frameHeight()}
431437
/>
432438
</div>
433439
);

crates/recording/src/sources/screen_capture/windows.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,14 @@ impl output_pipeline::AudioSource for SystemAudioSource {
376376
}
377377

378378
fn stop(&mut self) -> impl Future<Output = anyhow::Result<()>> {
379-
let res = self.capturer.pause().map_err(Into::into);
380-
async { res }
379+
let res = self.capturer.pause();
380+
381+
async move {
382+
if let Err(err) = res {
383+
warn!("system audio capturer pause failed: {err}");
384+
}
385+
386+
Ok(())
387+
}
381388
}
382389
}

crates/recording/src/studio_recording.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use std::{
2323
time::{Duration, Instant, SystemTime, UNIX_EPOCH},
2424
};
2525
use tokio::sync::watch;
26-
use tracing::{Instrument, debug, error_span, info, trace};
26+
use tracing::{Instrument, debug, error_span, info, trace, warn};
2727

2828
#[allow(clippy::large_enum_variant)]
2929
enum ActorState {
@@ -311,12 +311,20 @@ impl Pipeline {
311311
cursor.actor.stop();
312312
}
313313

314+
let system_audio = match system_audio.transpose() {
315+
Ok(value) => value,
316+
Err(err) => {
317+
warn!("system audio pipeline failed during stop: {err:#}");
318+
None
319+
}
320+
};
321+
314322
Ok(FinishedPipeline {
315323
start_time: self.start_time,
316324
screen: screen.context("screen")?,
317325
microphone: microphone.transpose().context("microphone")?,
318326
camera: camera.transpose().context("camera")?,
319-
system_audio: system_audio.transpose().context("system_audio")?,
327+
system_audio,
320328
cursor: self.cursor,
321329
})
322330
}

0 commit comments

Comments
 (0)