Repository: DioxusLabs/dioxus
File: packages/desktop/src/webview.rs (Rust)

Code before:
                if let Ok(msg) = serde_json::from_str(&body) {
                    _ = proxy.send_event(UserWindowEvent::Ipc { id: window_id, msg });
                }
            }
        };

        let file_drop_handler = {
            to_owned![file_hover];

            #[cfg(windows)]
            to_owned![dom];

            move |evt: DragDropEvent| {
                // Update the most recent file drop event - when the event comes in from the webview we can use the
                // most recent event to build a new event with the files in it.
                #[cfg(not(windows))]
                file_hover.set(evt);

                // Windows webview blocks HTML-native events when the drop handler is provided.
                // The problem is that the HTML-native events don't provide the file, so we need this.
                // Solution: this glue code to mimic drag drop events.
                #[cfg(windows)]
                {
                    use dioxus_html::prelude::eval;
                    file_hover.set(evt.clone());

                    dom.borrow().in_runtime(|| {
                        ScopeId::ROOT.in_runtime(|| {

                            match evt {
                            wry::DragDropEvent::Drop {
                                paths: _,
                                position: _,
                            } => {
                                eval(
                                    r#"
                                    if (window.dxDragLastElement) {
                                        const dragLeaveEvent = new DragEvent("dragleave", { bubbles: true, cancelable: true });
                                        window.dxDragLastElement.dispatchEvent(dragLeaveEvent);

                                        let data = new DataTransfer();
                                        
                                        // We need to mimic that there are actually files in this event for our native file engine to pick it up.
                                        const file = new File(["content"], "file.txt", { type: "text/plain" });
                                        data.items.add(file);

                                        const dragDropEvent = new DragEvent("drop", { bubbles: true, cancelable: true, dataTransfer: data });
                                        window.dxDragLastElement.dispatchEvent(dragDropEvent);
                                        window.dxDragLastElement = null;
                                    }
                                    "#

Review comment (suggestion):
Instead of wrapping the vdom in a RefCell, can we just make a new message type on WindowUserEvent that executes this with an &mut access to dom? AFAIK `eval` is not sync anyways

Code after:
            move |payload: wry::http::Request<String>| {
                // defer the event to the main thread
                let body = payload.into_body();
                if let Ok(msg) = serde_json::from_str(&body) {
                    _ = proxy.send_event(UserWindowEvent::Ipc { id: window_id, msg });
                }
            }
        };

        let file_drop_handler = {
            to_owned![file_hover];

            #[cfg(windows)]
            let (proxy, window_id) = (shared.proxy.to_owned(), window.id());

            move |evt: DragDropEvent| {
                // Update the most recent file drop event - when the event comes in from the webview we can use the
                // most recent event to build a new event with the files in it.
                #[cfg(not(windows))]
                file_hover.set(evt);

                // Windows webview blocks HTML-native events when the drop handler is provided.
                // The problem is that the HTML-native events don't provide the file, so we need this.
                // Solution: this glue code to mimic drag drop events.
                #[cfg(windows)]
                {
                    file_hover.set(evt.clone());

                    match evt {
                        wry::DragDropEvent::Drop {
                            paths: _,
                            position: _,
                        } => {
                            _ = proxy.send_event(UserWindowEvent::WindowsDragDrop(window_id));
                        }
                        wry::DragDropEvent::Over { position } => {
                            _ = proxy.send_event(UserWindowEvent::WindowsDragOver(
                                window_id, position.0, position.1,
                            ));
                        }
                        wry::DragDropEvent::Leave => {
                            _ = proxy.send_event(UserWindowEvent::WindowsDragLeave(window_id));
                        }
                        _ => {}
                    }
                }

                false
            }
        };