@@ -384,6 +384,10 @@ let nativeWindowsCaptureWebcamTargetPath: string | null = null;
384384let nativeWindowsCaptureRecordingId : number | null = null ;
385385let nativeWindowsCursorOffsetMs = 0 ;
386386let nativeWindowsCursorCaptureMode : CursorCaptureMode = "editable-overlay" ;
387+ let nativeWindowsCursorRecordingStartMs = 0 ;
388+ let nativeWindowsPauseStartedAtMs : number | null = null ;
389+ let nativeWindowsPauseRanges : Array < { startMs : number ; endMs : number } > = [ ] ;
390+ let nativeWindowsIsPaused = false ;
387391const NATIVE_WINDOWS_CAPTURE_STOP_TIMEOUT_MS = 15_000 ;
388392let nativeMacCaptureProcess : ChildProcessWithoutNullStreams | null = null ;
389393let nativeMacCaptureOutput = "" ;
@@ -873,6 +877,18 @@ function completeNativeMacCursorPauseRange(endMs = Date.now()) {
873877 nativeMacPauseStartedAtMs = null ;
874878}
875879
880+ function completeNativeWindowsCursorPauseRange ( endMs = Date . now ( ) ) {
881+ if ( nativeWindowsPauseStartedAtMs === null || nativeWindowsCursorRecordingStartMs <= 0 ) {
882+ return ;
883+ }
884+
885+ nativeWindowsPauseRanges . push ( {
886+ startMs : Math . max ( 0 , nativeWindowsPauseStartedAtMs - nativeWindowsCursorRecordingStartMs ) ,
887+ endMs : Math . max ( 0 , endMs - nativeWindowsCursorRecordingStartMs ) ,
888+ } ) ;
889+ nativeWindowsPauseStartedAtMs = null ;
890+ }
891+
876892function waitForNativeWindowsCaptureStart ( proc : ChildProcessWithoutNullStreams ) {
877893 return new Promise < void > ( ( resolve , reject ) => {
878894 const timer = setTimeout ( ( ) => {
@@ -1583,9 +1599,14 @@ export function registerIpcHandlers(
15831599 nativeWindowsCaptureRecordingId = recordingId ;
15841600 nativeWindowsCursorOffsetMs = 0 ;
15851601 nativeWindowsCursorCaptureMode = cursorCaptureMode ;
1602+ nativeWindowsCursorRecordingStartMs = 0 ;
1603+ nativeWindowsPauseStartedAtMs = null ;
1604+ nativeWindowsPauseRanges = [ ] ;
1605+ nativeWindowsIsPaused = false ;
15861606
15871607 const cursorStartTimeMs = Date . now ( ) ;
15881608 if ( cursorCaptureMode === "editable-overlay" ) {
1609+ nativeWindowsCursorRecordingStartMs = cursorStartTimeMs ;
15891610 await startCursorRecording ( cursorStartTimeMs ) ;
15901611 console . info ( "[native-wgc] cursor sampler ready" , {
15911612 cursorStartTimeMs,
@@ -1635,6 +1656,10 @@ export function registerIpcHandlers(
16351656 nativeWindowsCaptureRecordingId = null ;
16361657 nativeWindowsCursorOffsetMs = 0 ;
16371658 nativeWindowsCursorCaptureMode = "editable-overlay" ;
1659+ nativeWindowsCursorRecordingStartMs = 0 ;
1660+ nativeWindowsPauseStartedAtMs = null ;
1661+ nativeWindowsPauseRanges = [ ] ;
1662+ nativeWindowsIsPaused = false ;
16381663 await stopCursorRecording ( ) ;
16391664 return { success : false , error : String ( error ) } ;
16401665 }
@@ -1836,6 +1861,50 @@ export function registerIpcHandlers(
18361861 }
18371862 } ) ;
18381863
1864+ ipcMain . handle ( "pause-native-windows-recording" , async ( ) => {
1865+ const proc = nativeWindowsCaptureProcess ;
1866+ if ( ! proc ) {
1867+ return { success : false , error : "Native Windows capture is not running." } ;
1868+ }
1869+ if ( nativeWindowsIsPaused ) {
1870+ return { success : true } ;
1871+ }
1872+ if ( ! proc . stdin . writable ) {
1873+ return { success : false , error : "Native Windows capture command channel is closed." } ;
1874+ }
1875+
1876+ try {
1877+ proc . stdin . write ( "pause\n" ) ;
1878+ nativeWindowsIsPaused = true ;
1879+ nativeWindowsPauseStartedAtMs = Date . now ( ) ;
1880+ return { success : true } ;
1881+ } catch ( error ) {
1882+ return { success : false , error : error instanceof Error ? error . message : String ( error ) } ;
1883+ }
1884+ } ) ;
1885+
1886+ ipcMain . handle ( "resume-native-windows-recording" , async ( ) => {
1887+ const proc = nativeWindowsCaptureProcess ;
1888+ if ( ! proc ) {
1889+ return { success : false , error : "Native Windows capture is not running." } ;
1890+ }
1891+ if ( ! nativeWindowsIsPaused ) {
1892+ return { success : true } ;
1893+ }
1894+ if ( ! proc . stdin . writable ) {
1895+ return { success : false , error : "Native Windows capture command channel is closed." } ;
1896+ }
1897+
1898+ try {
1899+ proc . stdin . write ( "resume\n" ) ;
1900+ completeNativeWindowsCursorPauseRange ( ) ;
1901+ nativeWindowsIsPaused = false ;
1902+ return { success : true } ;
1903+ } catch ( error ) {
1904+ return { success : false , error : error instanceof Error ? error . message : String ( error ) } ;
1905+ }
1906+ } ) ;
1907+
18391908 ipcMain . handle ( "stop-native-windows-recording" , async ( _ , discard ?: boolean ) => {
18401909 const proc = nativeWindowsCaptureProcess ;
18411910 const preferredPath = nativeWindowsCaptureTargetPath ;
@@ -1848,6 +1917,7 @@ export function registerIpcHandlers(
18481917 }
18491918
18501919 try {
1920+ completeNativeWindowsCursorPauseRange ( ) ;
18511921 const stoppedPathPromise = waitForNativeWindowsCaptureStop ( proc ) ;
18521922 proc . stdin . write ( "stop\n" ) ;
18531923 const stoppedPath = await stoppedPathPromise ;
@@ -1872,6 +1942,7 @@ export function registerIpcHandlers(
18721942 }
18731943
18741944 if ( cursorCaptureMode === "editable-overlay" ) {
1945+ compactPendingCursorTelemetryPauseRanges ( nativeWindowsPauseRanges ) ;
18751946 shiftPendingCursorTelemetry ( nativeWindowsCursorOffsetMs ) ;
18761947 await writePendingCursorTelemetry ( screenVideoPath ) ;
18771948 }
@@ -1913,6 +1984,10 @@ export function registerIpcHandlers(
19131984 nativeWindowsCaptureRecordingId = null ;
19141985 nativeWindowsCursorOffsetMs = 0 ;
19151986 nativeWindowsCursorCaptureMode = "editable-overlay" ;
1987+ nativeWindowsCursorRecordingStartMs = 0 ;
1988+ nativeWindowsPauseStartedAtMs = null ;
1989+ nativeWindowsPauseRanges = [ ] ;
1990+ nativeWindowsIsPaused = false ;
19161991 const source = selectedSource || { name : "Screen" } ;
19171992 if ( onRecordingStateChange ) {
19181993 onRecordingStateChange ( false , source . name ) ;
0 commit comments