@@ -144,6 +144,42 @@ mod macos {
144144 visible == YES
145145 }
146146 }
147+ /// Set window click-through (ignores mouse events)
148+ pub fn set_window_click_through ( window : & Window , click_through : bool ) {
149+ use objc:: runtime:: Object ;
150+ use objc:: { msg_send, sel, sel_impl} ;
151+
152+ let handle = match HasWindowHandle :: window_handle ( window) {
153+ Ok ( h) => h,
154+ Err ( e) => {
155+ tracing:: warn!( "Failed to get window handle: {:?}" , e) ;
156+ return ;
157+ }
158+ } ;
159+
160+ let raw_window_handle:: RawWindowHandle :: AppKit ( appkit_handle) = handle. as_raw ( ) else {
161+ tracing:: warn!( "Not an AppKit window handle" ) ;
162+ return ;
163+ } ;
164+
165+ let ns_view = appkit_handle. ns_view . as_ptr ( ) as * mut Object ;
166+
167+ unsafe {
168+ let ns_window: * mut Object = msg_send ! [ ns_view, window] ;
169+ if ns_window. is_null ( ) {
170+ tracing:: warn!( "Failed to get NSWindow from NSView" ) ;
171+ return ;
172+ }
173+
174+ let ignore: objc:: runtime:: BOOL = if click_through {
175+ objc:: runtime:: YES
176+ } else {
177+ objc:: runtime:: NO
178+ } ;
179+ let _: ( ) = msg_send ! [ ns_window, setIgnoresMouseEvents: ignore] ;
180+ tracing:: info!( "Set window click-through: {}" , click_through) ;
181+ }
182+ }
147183}
148184
149185#[ cfg( target_os = "windows" ) ]
@@ -253,6 +289,39 @@ mod windows_impl {
253289
254290 unsafe { IsWindowVisible ( hwnd) . as_bool ( ) }
255291 }
292+
293+ /// Set window click-through (ignores mouse events)
294+ pub fn set_window_click_through ( window : & Window , click_through : bool ) {
295+ use windows:: Win32 :: UI :: WindowsAndMessaging :: {
296+ GetWindowLongW , SetWindowLongW , GWL_EXSTYLE , WS_EX_TRANSPARENT , WS_EX_LAYERED ,
297+ } ;
298+
299+ let handle = match HasWindowHandle :: window_handle ( window) {
300+ Ok ( h) => h,
301+ Err ( e) => {
302+ tracing:: warn!( "Failed to get window handle: {:?}" , e) ;
303+ return ;
304+ }
305+ } ;
306+
307+ let raw_window_handle:: RawWindowHandle :: Win32 ( win32_handle) = handle. as_raw ( ) else {
308+ tracing:: warn!( "Not a Win32 window handle" ) ;
309+ return ;
310+ } ;
311+
312+ let hwnd = HWND ( win32_handle. hwnd . get ( ) as * mut _ ) ;
313+
314+ unsafe {
315+ let ex_style = GetWindowLongW ( hwnd, GWL_EXSTYLE ) ;
316+ let new_style = if click_through {
317+ ex_style | WS_EX_TRANSPARENT . 0 as i32 | WS_EX_LAYERED . 0 as i32
318+ } else {
319+ ex_style & !( WS_EX_TRANSPARENT . 0 as i32 )
320+ } ;
321+ SetWindowLongW ( hwnd, GWL_EXSTYLE , new_style) ;
322+ tracing:: info!( "Set window click-through: {}" , click_through) ;
323+ }
324+ }
256325}
257326
258327#[ cfg( not( any( target_os = "macos" , target_os = "windows" ) ) ) ]
@@ -278,13 +347,18 @@ mod other {
278347 pub fn is_window_visible ( _window : & Window ) -> bool {
279348 true
280349 }
350+
351+ /// Set window click-through (no-op on unsupported platforms)
352+ pub fn set_window_click_through ( _window : & Window , _click_through : bool ) {
353+ tracing:: warn!( "Click-through is not supported on this platform" ) ;
354+ }
281355}
282356
283357#[ cfg( target_os = "macos" ) ]
284- pub use macos:: { hide_window, is_window_visible, set_window_always_on_top, show_window} ;
358+ pub use macos:: { hide_window, is_window_visible, set_window_always_on_top, set_window_click_through , show_window} ;
285359
286360#[ cfg( target_os = "windows" ) ]
287- pub use windows_impl:: { hide_window, is_window_visible, set_window_always_on_top, show_window} ;
361+ pub use windows_impl:: { hide_window, is_window_visible, set_window_always_on_top, set_window_click_through , show_window} ;
288362
289363#[ cfg( not( any( target_os = "macos" , target_os = "windows" ) ) ) ]
290- pub use other:: { hide_window, is_window_visible, set_window_always_on_top, show_window} ;
364+ pub use other:: { hide_window, is_window_visible, set_window_always_on_top, set_window_click_through , show_window} ;
0 commit comments