55use super :: InvokeResponse ;
66#[ cfg( any( dialog_open, dialog_save) ) ]
77use crate :: api:: dialog:: FileDialogBuilder ;
8- use crate :: api:: dialog:: { ask as ask_dialog, message as message_dialog, AskResponse } ;
8+ use crate :: {
9+ api:: dialog:: { ask as ask_dialog, message as message_dialog, AskResponse } ,
10+ Params , Window ,
11+ } ;
912use serde:: Deserialize ;
1013
1114use std:: path:: PathBuf ;
@@ -68,15 +71,16 @@ pub enum Cmd {
6871}
6972
7073impl Cmd {
71- pub fn run ( self ) -> crate :: Result < InvokeResponse > {
74+ #[ allow( unused_variables) ]
75+ pub fn run < P : Params > ( self , window : Window < P > ) -> crate :: Result < InvokeResponse > {
7276 match self {
7377 #[ cfg( dialog_open) ]
74- Self :: OpenDialog { options } => open ( options) ,
78+ Self :: OpenDialog { options } => open ( window , options) ,
7579 #[ cfg( not( dialog_open) ) ]
7680 Self :: OpenDialog { .. } => Err ( crate :: Error :: ApiNotAllowlisted ( "dialog > open" . to_string ( ) ) ) ,
7781
7882 #[ cfg( dialog_save) ]
79- Self :: SaveDialog { options } => save ( options) ,
83+ Self :: SaveDialog { options } => save ( window , options) ,
8084 #[ cfg( not( dialog_save) ) ]
8185 Self :: SaveDialog { .. } => Err ( crate :: Error :: ApiNotAllowlisted ( "dialog > save" . to_string ( ) ) ) ,
8286
@@ -139,10 +143,39 @@ fn set_default_path(
139143 }
140144}
141145
146+ #[ cfg( windows) ]
147+ struct WindowParent {
148+ hwnd : * mut std:: ffi:: c_void ,
149+ }
150+
151+ #[ cfg( windows) ]
152+ unsafe impl raw_window_handle:: HasRawWindowHandle for WindowParent {
153+ fn raw_window_handle ( & self ) -> raw_window_handle:: RawWindowHandle {
154+ let mut handle = raw_window_handle:: windows:: WindowsHandle :: empty ( ) ;
155+ handle. hwnd = self . hwnd ;
156+ raw_window_handle:: RawWindowHandle :: Windows ( handle)
157+ }
158+ }
159+
160+ #[ cfg( windows) ]
161+ fn parent < P : Params > ( window : Window < P > ) -> crate :: Result < WindowParent > {
162+ Ok ( WindowParent {
163+ hwnd : window. hwnd ( ) ?,
164+ } )
165+ }
166+
142167/// Shows an open dialog.
143168#[ cfg( dialog_open) ]
144- pub fn open ( options : OpenDialogOptions ) -> crate :: Result < InvokeResponse > {
169+ #[ allow( unused_variables) ]
170+ pub fn open < P : Params > (
171+ window : Window < P > ,
172+ options : OpenDialogOptions ,
173+ ) -> crate :: Result < InvokeResponse > {
145174 let mut dialog_builder = FileDialogBuilder :: new ( ) ;
175+ #[ cfg( windows) ]
176+ {
177+ dialog_builder = dialog_builder. set_parent ( & parent ( window) ?) ;
178+ }
146179 if let Some ( default_path) = options. default_path {
147180 if !default_path. exists ( ) {
148181 return Err ( crate :: Error :: DialogDefaultPathNotExists ( default_path) ) ;
@@ -165,8 +198,16 @@ pub fn open(options: OpenDialogOptions) -> crate::Result<InvokeResponse> {
165198
166199/// Shows a save dialog.
167200#[ cfg( dialog_save) ]
168- pub fn save ( options : SaveDialogOptions ) -> crate :: Result < InvokeResponse > {
201+ #[ allow( unused_variables) ]
202+ pub fn save < P : Params > (
203+ window : Window < P > ,
204+ options : SaveDialogOptions ,
205+ ) -> crate :: Result < InvokeResponse > {
169206 let mut dialog_builder = FileDialogBuilder :: new ( ) ;
207+ #[ cfg( windows) ]
208+ {
209+ dialog_builder = dialog_builder. set_parent ( & parent ( window) ?) ;
210+ }
170211 if let Some ( default_path) = options. default_path {
171212 if !default_path. exists ( ) {
172213 return Err ( crate :: Error :: DialogDefaultPathNotExists ( default_path) ) ;
0 commit comments