@@ -25,7 +25,11 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
2525 malicious_origins : HashSet :: new ( ) ,
2626 } ) ) ;
2727
28- // We refresh the ads window every 5 minutes for performance
28+ // We refresh the ads window every 5 minutes to mitigate memory leak issues.
29+ // While this loop doesn't include explicit checks to see if the window is still
30+ // visible when we refresh, the Aditude wrapper will not make any ad requests
31+ // unless Chromium reports the page as visible. The refresh does not reset the
32+ // visibility state.
2933 let app = app. clone ( ) ;
3034 tauri:: async_runtime:: spawn ( async move {
3135 loop {
@@ -92,14 +96,21 @@ pub async fn init_ads_window<R: Runtime>(
9296 }
9397
9498 if let Ok ( ( position, size) ) = get_webview_position ( & app, dpr) {
95- if let Some ( webview) = app. webviews ( ) . get ( "ads-window" ) {
99+ let webview = if let Some ( webview) = app. webviews ( ) . get ( "ads-window" ) {
100+ // set both the `hide`/`show` state and `position`,
101+ // to ensure that the webview is actually shown/hidden
96102 if state. shown {
97- let _ = webview. set_position ( position) ;
98- let _ = webview. set_size ( size) ;
103+ webview. show ( ) . ok ( ) ;
104+ webview. set_position ( position) . ok ( ) ;
105+ webview. set_size ( size) . ok ( ) ;
99106 } else {
100- let _ =
101- webview. set_position ( PhysicalPosition :: new ( -1000 , -1000 ) ) ;
107+ webview. hide ( ) . ok ( ) ;
108+ webview
109+ . set_position ( PhysicalPosition :: new ( -1000 , -1000 ) )
110+ . ok ( ) ;
102111 }
112+
113+ Some ( webview. clone ( ) )
103114 } else if let Some ( window) = app. get_window ( "main" ) {
104115 let webview = window. add_child (
105116 tauri:: webview:: WebviewBuilder :: new (
@@ -109,10 +120,16 @@ pub async fn init_ads_window<R: Runtime>(
109120 ) ,
110121 )
111122 . initialization_script_for_all_frames ( include_str ! ( "ads-init.js" ) )
123+ // We use a standard Chrome user agent for compatibility with our ad provider,
124+ // since Tauri is not recognized by ad providers by default.
125+ // Aditude has separately informed SSPs and IVT vendors that this traffic
126+ // originates from a desktop app.
112127 . user_agent ( "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36" )
113128 . zoom_hotkeys_enabled ( false )
114129 . transparent ( true )
115130 . on_new_window ( |_, _| tauri:: webview:: NewWindowResponse :: Deny ) ,
131+ // set both the `hide`/`show` state and `position`,
132+ // to ensure that the webview is actually shown/hidden
116133 if state. shown {
117134 position
118135 } else {
@@ -121,6 +138,12 @@ pub async fn init_ads_window<R: Runtime>(
121138 size,
122139 ) ?;
123140
141+ if state. shown {
142+ webview. show ( ) . ok ( ) ;
143+ } else {
144+ webview. hide ( ) . ok ( ) ;
145+ }
146+
124147 webview. with_webview ( #[ allow( unused_variables) ] |webview2| {
125148 #[ cfg( windows) ]
126149 {
@@ -137,7 +160,67 @@ pub async fn init_ads_window<R: Runtime>(
137160 unsafe { webview2_8. SetIsMuted ( true ) } . ok ( ) ;
138161 }
139162 } ) ?;
140- }
163+
164+ Some ( webview)
165+ } else {
166+ None
167+ } ;
168+
169+ let Some ( webview) = webview. clone ( ) else {
170+ return Ok ( ( ) ) ;
171+ } ;
172+
173+ // tauri::async_runtime::spawn(async move {
174+ // loop {
175+ // webview.with_webview(|wv| {
176+ // #[cfg(windows)]
177+ // {
178+ // use webview2_com::ExecuteScriptCompletedHandler;
179+
180+ // let core_webview2 = unsafe {
181+ // webview.controller().CoreWebView2().unwrap()
182+ // };
183+
184+ // let handler = ExecuteScriptCompletedHandler::create(Box::new(
185+ // move |hr: windows_core::Result<()>, result: String| {
186+ // if hr.is_ok() {
187+ // let hidden: bool = serde_json::from_str(&result).unwrap_or(true);
188+ // tracing::error!("!! ads wv hidden? {}", hidden);
189+ // }
190+ // Ok(())
191+ // },
192+ // ) as Box<_>);
193+
194+ // unsafe {
195+ // let _ = core_webview2.ExecuteScript(
196+ // windows_core::w!("document.hidden"),
197+ // &handler,
198+ // );
199+ // }
200+ // }
201+
202+ // #[cfg(not(windows))]
203+ // {
204+ // use webkit2gtk::WebViewExt;
205+
206+ // wv.inner().evaluate_javascript(
207+ // "document.hidden",
208+ // None,
209+ // None,
210+ // None::<&webkit2gtk::gio::Cancellable>,
211+ // |result| {
212+ // use javascriptcore::ValueExt;
213+
214+ // let hidden = result.map(|v| v.to_boolean());
215+ // tracing::error!("!! ads wv hidden? {hidden:?}");
216+ // },
217+ // );
218+ // }
219+ // });
220+
221+ // tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
222+ // }
223+ // });
141224 }
142225
143226 Ok ( ( ) )
@@ -161,8 +244,11 @@ pub async fn show_ads_window<R: Runtime>(
161244
162245 if state. shown {
163246 let ( position, size) = get_webview_position ( & app, dpr) ?;
164- let _ = webview. set_size ( size) ;
165- let _ = webview. set_position ( position) ;
247+ // set both the `hide`/`show` state and `position`,
248+ // to ensure that the webview is actually shown/hidden
249+ webview. set_size ( size) . ok ( ) ;
250+ webview. set_position ( position) . ok ( ) ;
251+ webview. show ( ) . ok ( ) ;
166252 }
167253 }
168254
@@ -184,7 +270,12 @@ pub async fn hide_ads_window<R: Runtime>(
184270 state. modal_shown = true ;
185271 }
186272
187- let _ = webview. set_position ( PhysicalPosition :: new ( -1000 , -1000 ) ) ;
273+ // set both the `hide`/`show` state and `position`,
274+ // to ensure that the webview is actually shown/hidden
275+ webview
276+ . set_position ( PhysicalPosition :: new ( -1000 , -1000 ) )
277+ . ok ( ) ;
278+ webview. hide ( ) . ok ( ) ;
188279 }
189280
190281 Ok ( ( ) )
0 commit comments