@@ -13,22 +13,23 @@ use crate::{
1313 } ,
1414 window:: {
1515 dpi:: { LogicalPosition , LogicalSize , PhysicalPosition , PhysicalSize , Position , Size } ,
16- DetachedWindow , PendingWindow ,
16+ DetachedWindow , PendingWindow , WindowEvent ,
1717 } ,
1818 Dispatch , Monitor , Params , Runtime ,
1919 } ,
2020 Icon ,
2121} ;
2222
2323use image:: { GenericImageView , Pixel } ;
24+ use uuid:: Uuid ;
2425use wry:: {
2526 application:: {
2627 dpi:: {
2728 LogicalPosition as WryLogicalPosition , LogicalSize as WryLogicalSize ,
2829 PhysicalPosition as WryPhysicalPosition , PhysicalSize as WryPhysicalSize ,
2930 Position as WryPosition , Size as WrySize ,
3031 } ,
31- event:: { Event , WindowEvent } ,
32+ event:: { Event , WindowEvent as WryWindowEvent } ,
3233 event_loop:: { ControlFlow , EventLoop , EventLoopProxy , EventLoopWindowTarget } ,
3334 monitor:: MonitorHandle ,
3435 window:: { Fullscreen , Icon as WindowIcon , Window , WindowBuilder as WryWindowBuilder , WindowId } ,
@@ -51,6 +52,8 @@ use std::{
5152type CreateWebviewHandler =
5253 Box < dyn FnOnce ( & EventLoopWindowTarget < Message > ) -> crate :: Result < WebView > + Send > ;
5354type MainThreadTask = Box < dyn FnOnce ( ) + Send > ;
55+ type WindowEventHandler = Box < dyn Fn ( & WindowEvent ) + Send > ;
56+ type WindowEventListeners = Arc < Mutex < HashMap < Uuid , WindowEventHandler > > > ;
5457
5558#[ repr( C ) ]
5659#[ derive( Debug ) ]
@@ -86,6 +89,29 @@ impl TryFrom<Icon> for WryIcon {
8689 }
8790}
8891
92+ struct WindowEventWrapper ( Option < WindowEvent > ) ;
93+
94+ impl < ' a > From < & WryWindowEvent < ' a > > for WindowEventWrapper {
95+ fn from ( event : & WryWindowEvent < ' a > ) -> Self {
96+ let event = match event {
97+ WryWindowEvent :: Resized ( size) => WindowEvent :: Resized ( ( * size) . into ( ) ) ,
98+ WryWindowEvent :: Moved ( position) => WindowEvent :: Moved ( ( * position) . into ( ) ) ,
99+ WryWindowEvent :: CloseRequested => WindowEvent :: CloseRequested ,
100+ WryWindowEvent :: Destroyed => WindowEvent :: Destroyed ,
101+ WryWindowEvent :: Focused ( focused) => WindowEvent :: Focused ( * focused) ,
102+ WryWindowEvent :: ScaleFactorChanged {
103+ scale_factor,
104+ new_inner_size,
105+ } => WindowEvent :: ScaleFactorChanged {
106+ scale_factor : * scale_factor,
107+ new_inner_size : ( * * new_inner_size) . into ( ) ,
108+ } ,
109+ _ => return Self ( None ) ,
110+ } ;
111+ Self ( Some ( event) )
112+ }
113+ }
114+
89115impl From < MonitorHandle > for Monitor {
90116 fn from ( monitor : MonitorHandle ) -> Monitor {
91117 Self {
@@ -332,6 +358,7 @@ pub struct WryDispatcher {
332358 window_id : WindowId ,
333359 proxy : EventLoopProxy < Message > ,
334360 task_tx : Sender < MainThreadTask > ,
361+ window_event_listeners : WindowEventListeners ,
335362}
336363
337364macro_rules! dispatcher_getter {
@@ -375,6 +402,16 @@ impl Dispatch for WryDispatcher {
375402 . map_err ( |_| crate :: Error :: FailedToSendMessage )
376403 }
377404
405+ fn on_window_event < F : Fn ( & WindowEvent ) + Send + ' static > ( & self , f : F ) -> Uuid {
406+ let id = Uuid :: new_v4 ( ) ;
407+ self
408+ . window_event_listeners
409+ . lock ( )
410+ . unwrap ( )
411+ . insert ( id, Box :: new ( f) ) ;
412+ id
413+ }
414+
378415 // GETTERS
379416
380417 fn scale_factor ( & self ) -> crate :: Result < f64 > {
@@ -430,11 +467,12 @@ impl Dispatch for WryDispatcher {
430467 let label = pending. label . clone ( ) ;
431468 let proxy = self . proxy . clone ( ) ;
432469 let task_tx = self . task_tx . clone ( ) ;
470+ let window_event_listeners = self . window_event_listeners . clone ( ) ;
433471 self
434472 . proxy
435473 . send_event ( Message :: CreateWebview (
436474 Arc :: new ( Mutex :: new ( Some ( Box :: new ( move |event_loop| {
437- create_webview ( event_loop, proxy, task_tx, pending)
475+ create_webview ( event_loop, proxy, task_tx, window_event_listeners , pending)
438476 } ) ) ) ) ,
439477 tx,
440478 ) )
@@ -444,6 +482,7 @@ impl Dispatch for WryDispatcher {
444482 window_id,
445483 proxy : self . proxy . clone ( ) ,
446484 task_tx : self . task_tx . clone ( ) ,
485+ window_event_listeners : self . window_event_listeners . clone ( ) ,
447486 } ;
448487 Ok ( DetachedWindow { label, dispatcher } )
449488 }
@@ -620,6 +659,7 @@ pub struct Wry {
620659 event_loop : EventLoop < Message > ,
621660 webviews : HashMap < WindowId , WebView > ,
622661 task_tx : Sender < MainThreadTask > ,
662+ window_event_listeners : WindowEventListeners ,
623663 task_rx : Receiver < MainThreadTask > ,
624664}
625665
@@ -634,6 +674,7 @@ impl Runtime for Wry {
634674 webviews : Default :: default ( ) ,
635675 task_tx,
636676 task_rx,
677+ window_event_listeners : Default :: default ( ) ,
637678 } )
638679 }
639680
@@ -647,13 +688,15 @@ impl Runtime for Wry {
647688 & self . event_loop ,
648689 proxy. clone ( ) ,
649690 self . task_tx . clone ( ) ,
691+ self . window_event_listeners . clone ( ) ,
650692 pending,
651693 ) ?;
652694
653695 let dispatcher = WryDispatcher {
654696 window_id : webview. window ( ) . id ( ) ,
655697 proxy,
656698 task_tx : self . task_tx . clone ( ) ,
699+ window_event_listeners : self . window_event_listeners . clone ( ) ,
657700 } ;
658701
659702 self . webviews . insert ( webview. window ( ) . id ( ) , webview) ;
@@ -664,6 +707,7 @@ impl Runtime for Wry {
664707 fn run ( self ) {
665708 let mut webviews = self . webviews ;
666709 let task_rx = self . task_rx ;
710+ let window_event_listeners = self . window_event_listeners . clone ( ) ;
667711 self . event_loop . run ( move |event, event_loop, control_flow| {
668712 * control_flow = ControlFlow :: Wait ;
669713
@@ -678,20 +722,27 @@ impl Runtime for Wry {
678722 }
679723
680724 match event {
681- Event :: WindowEvent { event, window_id } => match event {
682- WindowEvent :: CloseRequested => {
683- webviews. remove ( & window_id) ;
684- if webviews. is_empty ( ) {
685- * control_flow = ControlFlow :: Exit ;
725+ Event :: WindowEvent { event, window_id } => {
726+ if let Some ( event) = WindowEventWrapper :: from ( & event) . 0 {
727+ for handler in window_event_listeners. lock ( ) . unwrap ( ) . values ( ) {
728+ handler ( & event) ;
686729 }
687730 }
688- WindowEvent :: Resized ( _) => {
689- if let Err ( e) = webviews[ & window_id] . resize ( ) {
690- eprintln ! ( "{}" , e) ;
731+ match event {
732+ WryWindowEvent :: CloseRequested => {
733+ webviews. remove ( & window_id) ;
734+ if webviews. is_empty ( ) {
735+ * control_flow = ControlFlow :: Exit ;
736+ }
691737 }
738+ WryWindowEvent :: Resized ( _) => {
739+ if let Err ( e) = webviews[ & window_id] . resize ( ) {
740+ eprintln ! ( "{}" , e) ;
741+ }
742+ }
743+ _ => { }
692744 }
693- _ => { }
694- } ,
745+ }
695746 Event :: UserEvent ( message) => match message {
696747 Message :: Window ( id, window_message) => {
697748 if let Some ( webview) = webviews. get_mut ( & id) {
@@ -797,6 +848,7 @@ fn create_webview<M: Params<Runtime = Wry>>(
797848 event_loop : & EventLoopWindowTarget < Message > ,
798849 proxy : EventLoopProxy < Message > ,
799850 task_tx : Sender < MainThreadTask > ,
851+ window_event_listeners : WindowEventListeners ,
800852 pending : PendingWindow < M > ,
801853) -> crate :: Result < WebView > {
802854 let PendingWindow {
@@ -818,13 +870,19 @@ fn create_webview<M: Params<Runtime = Wry>>(
818870 webview_builder = webview_builder. with_rpc_handler ( create_rpc_handler (
819871 proxy. clone ( ) ,
820872 task_tx. clone ( ) ,
873+ window_event_listeners. clone ( ) ,
821874 label. clone ( ) ,
822875 handler,
823876 ) ) ;
824877 }
825878 if let Some ( handler) = file_drop_handler {
826- webview_builder = webview_builder
827- . with_file_drop_handler ( create_file_drop_handler ( proxy, task_tx, label, handler) ) ;
879+ webview_builder = webview_builder. with_file_drop_handler ( create_file_drop_handler (
880+ proxy,
881+ task_tx,
882+ window_event_listeners,
883+ label,
884+ handler,
885+ ) ) ;
828886 }
829887 for ( scheme, protocol) in webview_attributes. uri_scheme_protocols {
830888 webview_builder = webview_builder. with_custom_protocol ( scheme, move |_window, url| {
@@ -847,6 +905,7 @@ fn create_webview<M: Params<Runtime = Wry>>(
847905fn create_rpc_handler < M : Params < Runtime = Wry > > (
848906 proxy : EventLoopProxy < Message > ,
849907 task_tx : Sender < MainThreadTask > ,
908+ window_event_listeners : WindowEventListeners ,
850909 label : M :: Label ,
851910 handler : WebviewRpcHandler < M > ,
852911) -> Box < dyn Fn ( & Window , WryRpcRequest ) -> Option < RpcResponse > + ' static > {
@@ -857,6 +916,7 @@ fn create_rpc_handler<M: Params<Runtime = Wry>>(
857916 window_id : window. id ( ) ,
858917 proxy : proxy. clone ( ) ,
859918 task_tx : task_tx. clone ( ) ,
919+ window_event_listeners : window_event_listeners. clone ( ) ,
860920 } ,
861921 label : label. clone ( ) ,
862922 } ,
@@ -870,6 +930,7 @@ fn create_rpc_handler<M: Params<Runtime = Wry>>(
870930fn create_file_drop_handler < M : Params < Runtime = Wry > > (
871931 proxy : EventLoopProxy < Message > ,
872932 task_tx : Sender < MainThreadTask > ,
933+ window_event_listeners : WindowEventListeners ,
873934 label : M :: Label ,
874935 handler : FileDropHandler < M > ,
875936) -> Box < dyn Fn ( & Window , WryFileDropEvent ) -> bool + ' static > {
@@ -881,6 +942,7 @@ fn create_file_drop_handler<M: Params<Runtime = Wry>>(
881942 window_id : window. id ( ) ,
882943 proxy : proxy. clone ( ) ,
883944 task_tx : task_tx. clone ( ) ,
945+ window_event_listeners : window_event_listeners. clone ( ) ,
884946 } ,
885947 label : label. clone ( ) ,
886948 } ,
0 commit comments