@@ -388,6 +388,18 @@ function editorPatch(document: AxcutDocument, args: SetEditorSettingsArgs): Edit
388388 return patch ;
389389}
390390
391+ /** A rect and a pan sent together that place the window in two different spots. At full size
392+ * there is no room to place it in, so any pan agrees with the rect there. */
393+ function cropFramingConflict ( args : SetEditorSettingsArgs ) : string | null {
394+ const { webcamCropRegion : region , webcamCropPan : pan } = args ;
395+ if ( ! region || ! pan ) return null ;
396+ const agrees = ( offset : number , size : number , share : number ) =>
397+ Math . abs ( offset - share * ( 1 - size ) ) < 1e-6 ;
398+ return agrees ( region . x , region . width , pan . x ) && agrees ( region . y , region . height , pan . y )
399+ ? null
400+ : "webcamCropRegion and webcamCropPan place the framing in two different spots: send one of them, or both as getCurrentDocument returns them." ;
401+ }
402+
391403/** Every key a patch sets, `cursor.*` for the cursor's: what the result reports as applied. */
392404function patchKeys ( patch : EditorSettingsPatch ) : string [ ] {
393405 const { cursor, ...rest } = patch ;
@@ -406,6 +418,8 @@ export function executeSetEditorSettings(
406418 if ( ! parsed . success ) {
407419 return { ok : false , resultJson : JSON . stringify ( { error : parsed . error . message } ) } ;
408420 }
421+ const conflict = cropFramingConflict ( parsed . data ) ;
422+ if ( conflict ) return { ok : false , resultJson : JSON . stringify ( { error : conflict } ) } ;
409423 const patch = editorPatch ( document , parsed . data ) ;
410424 const keys = patchKeys ( patch ) ;
411425 if ( keys . length === 0 ) {
0 commit comments