Skip to content
Merged
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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ The detailed feature list below describes the Windows application. The Linux bui
- **Specialized Capture Modes:**
- **Scrolling Capture:** Automatically scrolls and stitches vertical, horizontal, or two-axis scrolling windows and web pages.
- **Panoramic Capture:** Pan across a scrollable area at your own pace and stitch it live.
- **Freehand, Multi-Area & Fixed Size:** Lasso an arbitrary shape (transparent outside), select multiple distinct rectangles in one shot, or stamp a fixed-pixel rectangle.
- **Freehand, Multi-Area & Fixed Size:** Lasso an arbitrary shape (transparent outside), select multiple distinct rectangles in one shot, or stamp a fixed-pixel rectangle. Set the fixed size and an optional exact position in the Region options (the gear beside **Area**); on Windows, **Select region on screen…** takes them from a rectangle you drag.
- **Open Menus:** Delayed capture mode designed to grab open context menus and dropdowns.
- **Grab Text (Windows OCR):** Select any area on screen to extract selectable, copyable text instantly.
- **Step Capture:** Record a numbered click-by-click guide automatically—every click captures a screenshot and places a sequential step badge at the cursor.
Expand Down Expand Up @@ -147,7 +147,7 @@ The detailed feature list below describes the Windows application. The Linux bui
<img src="docs/images/recording-toolbar.png" alt="Jiffshot Floating Recording Toolbar" width="680" />
</p>

- **Area, Window & Fullscreen Recording:** Record MP4 video at 15, 24, 30, or 60 FPS. Press `G` while selecting to snap to standard `1920×1080`, `1280×720`, `640×480`, or `320×240` guides.
- **Area, Window & Fullscreen Recording:** Record MP4 video at 15, 24, 30, or 60 FPS. Press `G` while selecting to snap to standard `1920×1080`, `1280×720`, `640×480`, or `320×240` guides, or `1`–`4` to place a rectangle of one of those sizes. For another size, turn on **Fixed region** in the Video Region options (the gear beside **Area**) and set its width and height, from 16 to 8192 pixels; the overlay then offers a rectangle of that size to place. On Windows, **Set position** records that rectangle at a saved X and Y without the overlay, and **Select region on screen…** takes the size (and, with Set position, the position) from a rectangle you drag. The video region is kept separately from the image one.
- **System Audio, Microphone & Webcam:** Record system audio ("what the computer plays"), your microphone (with an optional between-words noise gate), or both mixed together. Add a live circular or rectangular **webcam picture-in-picture** overlay in any corner.
- **Pointer Effects & Live Screen Draw:** Highlight the cursor with a halo, show animated click rings, and draw live arrows, boxes, highlights, and freehand marks directly over the screen while recording (with configurable auto-fade).
- **Live Recording Toolbar:** Pause, resume, restart, minimize, or cancel the recording, and toggle cursor effects, webcam, microphone, system sound, and Screen Draw on the fly—all from a floating toolbar that stays invisible to the recording itself.
Expand Down
51 changes: 49 additions & 2 deletions app/src/win/capture_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
//! which owns the settings.
//!
//! Actions: `tab:N`, `switch:ID`, `menu:NAME`, `pick:ID`, `panel:ID`,
//! `apply:ID:[values]`, `capture`, `stop-interval`, `cancel-schedule`,
//! `editor`, `closed`.
//! `apply:ID:[values]`, `select-image-region:[values]`,
//! `select-video-region:[values]`, `capture`, `stop-interval`,
//! `cancel-schedule`, `editor`, `closed`.

use crate::app;
use crate::vm::{CaptureViewModel, CaptureViewModelSink};
Expand All @@ -28,6 +29,10 @@ struct State {
timelapse: bool,
window: Option<rustolonia::Window>,
serial: u64,
/// The options panel to open again when the window is next shown
/// (after Select region on screen…).
#[cfg(windows)]
reopen_panel: Option<&'static str>,
#[cfg(target_os = "macos")]
scope: Option<AppScope>,
#[cfg(target_os = "macos")]
Expand Down Expand Up @@ -68,6 +73,8 @@ thread_local! {
timelapse: false,
window: None,
serial: 0,
#[cfg(windows)]
reopen_panel: None,
#[cfg(target_os = "macos")]
scope: None,
#[cfg(target_os = "macos")]
Expand Down Expand Up @@ -121,6 +128,10 @@ pub fn show(scope: &AppScope) {
if let Ok(hwnd) = scope.platform_handle(&window) {
crate::winutil::bring_forward(hwnd);
}
#[cfg(windows)]
if let Some(id) = with(|s| s.reopen_panel.take()) {
open_panel(id);
}
}

fn hide() {
Expand Down Expand Up @@ -343,6 +354,18 @@ fn applied(id: &str, values: &str) {
}
}

/// Select region on screen…: keeps the Region options as they stand, then
/// hides the window for the overlay; the capture side shows it again, with
/// the options.
#[cfg(windows)]
fn select_fixed_region(video: bool, values: &str) {
let panel = if video { "video:selection" } else { "image:selection" };
applied(panel, values);
with(|s| s.reopen_panel = Some(panel));
hide();
capture::select_fixed_region(video);
}

#[cfg(target_os = "macos")]
fn select_scheduled_area(values: &str) {
let Ok(values) = serde_json::from_str::<Vec<serde_json::Value>>(values) else {
Expand Down Expand Up @@ -664,6 +687,8 @@ fn act(action: &str) {
}
#[cfg(target_os = "macos")]
"select-scheduled-area" => select_scheduled_area(arg),
#[cfg(windows)]
"select-image-region" | "select-video-region" => select_fixed_region(verb == "select-video-region", arg),
"capture" => {
let (settings, running) = with(|s| (capture_settings(&s.settings, arg), s.timelapse));
#[cfg(target_os = "macos")]
Expand Down Expand Up @@ -949,6 +974,28 @@ mod tests {
});
}

#[cfg(windows)]
#[test]
fn selecting_a_region_on_screen_keeps_the_options_and_reopens_them() {
let mut settings = Settings::default();
settings.capture_window.tab = 1;
with(|s| s.settings = settings);
act("select-video-region:[true,1280,720,true,40,30,0,5]");
with(|s| {
assert!(s.settings.capture_window.video_fixed);
assert_eq!(s.settings.video_fixed_size, (1280, 720));
assert_eq!(s.settings.capture_window.video_fixed_at, Some((40, 30)));
assert_eq!((s.settings.record_fps, s.settings.countdown), (15, 5));
assert_eq!(s.settings.capture_window.tab, 1, "the saved mode stays");
assert_eq!(s.reopen_panel.take(), Some("video:selection"));
});
act("select-image-region:[true,640,480,false,0,0,true]");
with(|s| {
assert_eq!((s.settings.fixed_size, s.settings.capture_window.fixed), ((640, 480), true));
assert_eq!(s.reopen_panel.take(), Some("image:selection"));
});
}

#[test]
fn scoped_form_values_keep_the_target_and_embedded_colons() {
assert_eq!(form_values("image:selection:[true,800,600]"),
Expand Down
7 changes: 7 additions & 0 deletions crates/jiffshot-workflow/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,13 @@ pub mod capture {
super::post_capture_thread(tray::select_scheduled_area)
}

/// Opens the selection overlay to choose the Image (or, with `video`,
/// the Video) Region options' fixed region.
#[cfg(windows)]
pub fn select_fixed_region(video: bool) {
on_capture_thread(move || tray::select_fixed_region(video));
}

pub fn set_run_at_startup(on: bool) {
if !super::post_capture_thread(move || {
tray::set_run_at_startup(on);
Expand Down
Loading
Loading