Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,75 @@ Portions of this software are licensed as follows:
- All third party components are licensed under the original license provided by the owner of the applicable component
- All other content not mentioned above is available under the AGPLv3 license as defined in [LICENSE](https://github.com/CapSoftware/Cap/blob/main/LICENSE)

# Deeplinks

Cap Desktop supports deeplinks via the `cap-desktop://` scheme (Tauri deep link). Actions are passed as a JSON payload in the `value` query param.

**Format**

```
cap-desktop://action?value={JSON}
```

**Examples**

Start recording (screen capture):
```
cap-desktop://action?value={"start_recording":{"capture_mode":{"screen":"Built-in Display"},"camera":null,"mic_label":null,"capture_system_audio":true,"mode":"instant"}}
```

Start recording (window capture):
```
cap-desktop://action?value={"start_recording":{"capture_mode":{"window":"My App"},"camera":null,"mic_label":null,"capture_system_audio":true,"mode":"instant"}}
```

Stop recording (URL-encoded JSON string):
```
cap-desktop://action?value=%22stop_recording%22
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example should URL-encode the JSON value, and for unit actions serde typically expects a JSON string (e.g. "stop_recording") rather than { "stop_recording": {} }.

Suggested change
```
cap-desktop://action?value=%22stop_recording%22


Pause recording (URL-encoded JSON string):
```
cap-desktop://action?value=%22pause_recording%22
```

Resume recording (URL-encoded JSON string):
```
cap-desktop://action?value=%22resume_recording%22
```

Switch microphone (by label):
```
cap-desktop://action?value={"set_microphone":{"mic_label":"MacBook Pro Microphone"}}
```

Switch camera (by device id or model id):
```
cap-desktop://action?value={"set_camera":{"camera":{"DeviceID":"<device-id>"}}}
```

Open settings:
```
cap-desktop://action?value={"open_settings":{"page":"general"}}
```

Open editor (macOS file deeplink):
```
file:///path/to/project
```

## Raycast Extension
A minimal Raycast extension is available under `apps/raycast`. It triggers the same deeplinks above.

Commands included:
- Start Recording (Screen)
- Start Recording (Window)
- Stop Recording
- Pause Recording
- Resume Recording
- Switch Microphone (by label)
- Switch Camera (by device id or model id)

# Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for more information. This guide is a work in progress, and is updated regularly as the app matures.
Expand Down
26 changes: 25 additions & 1 deletion apps/desktop/src-tauri/src/deeplink_actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ pub enum DeepLinkAction {
mode: RecordingMode,
},
StopRecording,
PauseRecording,
ResumeRecording,
SetMicrophone {
mic_label: Option<String>,
},
SetCamera {
camera: Option<DeviceOrModelID>,
},
OpenEditor {
project_path: PathBuf,
},
Expand Down Expand Up @@ -83,7 +91,9 @@ impl TryFrom<&Url> for DeepLinkAction {
#[cfg(target_os = "macos")]
if url.scheme() == "file" {
return Ok(Self::OpenEditor {
project_path: url.to_file_path().unwrap(),
project_path: url
.to_file_path()
.map_err(|_| ActionParseFromUrlError::Invalid)?,
});
}

Expand Down Expand Up @@ -146,6 +156,20 @@ impl DeepLinkAction {
DeepLinkAction::StopRecording => {
crate::recording::stop_recording(app.clone(), app.state()).await
}
DeepLinkAction::PauseRecording => {
crate::recording::pause_recording(app.clone(), app.state()).await
}
DeepLinkAction::ResumeRecording => {
crate::recording::resume_recording(app.clone(), app.state()).await
}
DeepLinkAction::SetMicrophone { mic_label } => {
let state = app.state::<ArcLock<App>>();
crate::set_mic_input(state.clone(), mic_label).await
}
DeepLinkAction::SetCamera { camera } => {
let state = app.state::<ArcLock<App>>();
crate::set_camera_input(app.clone(), state, camera, None).await
}
DeepLinkAction::OpenEditor { project_path } => {
crate::open_project_from_path(Path::new(&project_path), app.clone())
}
Expand Down
Binary file added apps/raycast/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading