@@ -22,11 +22,12 @@ use tracing::{debug, error, warn};
2222
2323use crate :: {
2424 App , ArcLock , RequestScreenCapturePrewarm , fake_window,
25- general_settings:: { AppTheme , GeneralSettingsStore } ,
25+ general_settings:: { self , AppTheme , GeneralSettingsStore } ,
2626 permissions,
2727 recording_settings:: RecordingTargetMode ,
2828 target_select_overlay:: WindowFocusManager ,
2929} ;
30+ use cap_recording:: sources:: screen_capture:: WindowExclusion ;
3031
3132#[ cfg( target_os = "macos" ) ]
3233const DEFAULT_TRAFFIC_LIGHTS_INSET : LogicalPosition < f64 > = LogicalPosition :: new ( 12.0 , 12.0 ) ;
@@ -250,6 +251,9 @@ impl ShowCapWindow {
250251 . map ( |s| s. enable_new_recording_flow )
251252 . unwrap_or_default ( ) ;
252253
254+ let title = CapWindowId :: Main . title ( ) ;
255+ let should_protect = should_protect_window ( app, & title) ;
256+
253257 let window = self
254258 . window_builder ( app, if new_recording_flow { "/new-main" } else { "/" } )
255259 . resizable ( false )
@@ -258,7 +262,7 @@ impl ShowCapWindow {
258262 . minimizable ( false )
259263 . always_on_top ( true )
260264 . visible_on_all_workspaces ( true )
261- . content_protected ( false )
265+ . content_protected ( should_protect )
262266 . center ( )
263267 . initialization_script ( format ! (
264268 "
@@ -296,6 +300,12 @@ impl ShowCapWindow {
296300 return Err ( tauri:: Error :: WindowNotFound ) ;
297301 } ;
298302
303+ let title = CapWindowId :: TargetSelectOverlay {
304+ display_id : display_id. clone ( ) ,
305+ }
306+ . title ( ) ;
307+ let should_protect = should_protect_window ( app, & title) ;
308+
299309 let mut window_builder = self
300310 . window_builder (
301311 app,
@@ -305,7 +315,7 @@ impl ShowCapWindow {
305315 . resizable ( false )
306316 . fullscreen ( false )
307317 . shadow ( false )
308- . content_protected ( true )
318+ . content_protected ( should_protect )
309319 . always_on_top ( true )
310320 . visible_on_all_workspaces ( true )
311321 . skip_taskbar ( true )
@@ -516,6 +526,12 @@ impl ShowCapWindow {
516526 return Err ( tauri:: Error :: WindowNotFound ) ;
517527 } ;
518528
529+ let title = CapWindowId :: WindowCaptureOccluder {
530+ screen_id : screen_id. clone ( ) ,
531+ }
532+ . title ( ) ;
533+ let should_protect = should_protect_window ( app, & title) ;
534+
519535 #[ cfg( target_os = "macos" ) ]
520536 let position = display. raw_handle ( ) . logical_position ( ) ;
521537
@@ -532,7 +548,7 @@ impl ShowCapWindow {
532548 . shadow ( false )
533549 . always_on_top ( true )
534550 . visible_on_all_workspaces ( true )
535- . content_protected ( true )
551+ . content_protected ( should_protect )
536552 . skip_taskbar ( true )
537553 . inner_size ( bounds. width ( ) , bounds. height ( ) )
538554 . position ( position. x ( ) , position. y ( ) )
@@ -550,13 +566,16 @@ impl ShowCapWindow {
550566 window
551567 }
552568 Self :: CaptureArea { screen_id } => {
569+ let title = CapWindowId :: CaptureArea . title ( ) ;
570+ let should_protect = should_protect_window ( app, & title) ;
571+
553572 let mut window_builder = self
554573 . window_builder ( app, "/capture-area" )
555574 . maximized ( false )
556575 . fullscreen ( false )
557576 . shadow ( false )
558577 . always_on_top ( true )
559- . content_protected ( true )
578+ . content_protected ( should_protect )
560579 . skip_taskbar ( true )
561580 . closable ( true )
562581 . decorations ( false )
@@ -604,6 +623,9 @@ impl ShowCapWindow {
604623 let width = 250.0 ;
605624 let height = 40.0 ;
606625
626+ let title = CapWindowId :: InProgressRecording . title ( ) ;
627+ let should_protect = should_protect_window ( app, & title) ;
628+
607629 let window = self
608630 . window_builder ( app, "/in-progress-recording" )
609631 . maximized ( false )
@@ -613,7 +635,7 @@ impl ShowCapWindow {
613635 . always_on_top ( true )
614636 . transparent ( true )
615637 . visible_on_all_workspaces ( true )
616- . content_protected ( true )
638+ . content_protected ( should_protect )
617639 . inner_size ( width, height)
618640 . position (
619641 ( ( monitor. size ( ) . width as f64 ) / monitor. scale_factor ( ) - width) / 2.0 ,
@@ -634,6 +656,9 @@ impl ShowCapWindow {
634656 window
635657 }
636658 Self :: RecordingsOverlay => {
659+ let title = CapWindowId :: RecordingsOverlay . title ( ) ;
660+ let should_protect = should_protect_window ( app, & title) ;
661+
637662 let window = self
638663 . window_builder ( app, "/recordings-overlay" )
639664 . maximized ( false )
@@ -643,7 +668,7 @@ impl ShowCapWindow {
643668 . always_on_top ( true )
644669 . visible_on_all_workspaces ( true )
645670 . accept_first_mouse ( true )
646- . content_protected ( true )
671+ . content_protected ( should_protect )
647672 . inner_size (
648673 ( monitor. size ( ) . width as f64 ) / monitor. scale_factor ( ) ,
649674 ( monitor. size ( ) . height as f64 ) / monitor. scale_factor ( ) ,
@@ -840,6 +865,34 @@ fn position_traffic_lights_impl(
840865 . ok ( ) ;
841866}
842867
868+ fn should_protect_window ( app : & AppHandle < Wry > , window_title : & str ) -> bool {
869+ let matches = |list : & [ WindowExclusion ] | {
870+ list. iter ( )
871+ . any ( |entry| entry. matches ( None , None , Some ( window_title) ) )
872+ } ;
873+
874+ GeneralSettingsStore :: get ( app)
875+ . ok ( )
876+ . flatten ( )
877+ . map ( |settings| matches ( & settings. excluded_windows ) )
878+ . unwrap_or_else ( || matches ( & general_settings:: default_excluded_windows ( ) ) )
879+ }
880+
881+ #[ tauri:: command]
882+ #[ specta:: specta]
883+ pub fn refresh_window_content_protection ( app : AppHandle < Wry > ) -> Result < ( ) , String > {
884+ for ( label, window) in app. webview_windows ( ) {
885+ if let Ok ( id) = CapWindowId :: from_str ( & label) {
886+ let title = id. title ( ) ;
887+ window
888+ . set_content_protected ( should_protect_window ( & app, & title) )
889+ . map_err ( |e| e. to_string ( ) ) ?;
890+ }
891+ }
892+
893+ Ok ( ( ) )
894+ }
895+
843896// Credits: tauri-plugin-window-state
844897trait MonitorExt {
845898 fn intersects (
0 commit comments