|
@@ -70,7 +70,7 @@ use wry::{
|
|
|
|
|
|
pub use wry::application::window::{Window, WindowBuilder as WryWindowBuilder, WindowId};
|
|
|
|
|
|
-#[cfg(target_os = "windows")]
|
|
|
+#[cfg(windows)]
|
|
|
use wry::webview::WebviewExtWindows;
|
|
|
|
|
|
#[cfg(target_os = "macos")]
|
|
@@ -96,6 +96,8 @@ use std::{
|
|
|
thread::{current as current_thread, ThreadId},
|
|
|
};
|
|
|
|
|
|
+type WebviewId = u64;
|
|
|
+
|
|
|
#[cfg(feature = "system-tray")]
|
|
|
mod system_tray;
|
|
|
#[cfg(feature = "system-tray")]
|
|
@@ -105,14 +107,27 @@ type WebContextStore = Arc<Mutex<HashMap<Option<PathBuf>, WebContext>>>;
|
|
|
// window
|
|
|
type WindowEventHandler = Box<dyn Fn(&WindowEvent) + Send>;
|
|
|
type WindowEventListenersMap = Arc<Mutex<HashMap<Uuid, WindowEventHandler>>>;
|
|
|
-type WindowEventListeners = Arc<Mutex<HashMap<WindowId, WindowEventListenersMap>>>;
|
|
|
+type WindowEventListeners = Arc<Mutex<HashMap<WebviewId, WindowEventListenersMap>>>;
|
|
|
// global shortcut
|
|
|
type GlobalShortcutListeners = Arc<Mutex<HashMap<AcceleratorId, Box<dyn Fn() + Send>>>>;
|
|
|
// menu
|
|
|
pub type MenuEventHandler = Box<dyn Fn(&MenuEvent) + Send>;
|
|
|
-pub type MenuEventListeners = Arc<Mutex<HashMap<WindowId, WindowMenuEventListeners>>>;
|
|
|
+pub type MenuEventListeners = Arc<Mutex<HashMap<WebviewId, WindowMenuEventListeners>>>;
|
|
|
pub type WindowMenuEventListeners = Arc<Mutex<HashMap<Uuid, MenuEventHandler>>>;
|
|
|
|
|
|
+#[derive(Debug, Clone, Default)]
|
|
|
+struct WebviewIdStore(Arc<Mutex<HashMap<WindowId, WebviewId>>>);
|
|
|
+
|
|
|
+impl WebviewIdStore {
|
|
|
+ fn insert(&self, w: WindowId, id: WebviewId) {
|
|
|
+ self.0.lock().unwrap().insert(w, id);
|
|
|
+ }
|
|
|
+
|
|
|
+ fn get(&self, w: &WindowId) -> WebviewId {
|
|
|
+ *self.0.lock().unwrap().get(w).unwrap()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
macro_rules! getter {
|
|
|
($self: ident, $rx: expr, $message: expr) => {{
|
|
|
send_user_message(&$self.context, $message)?;
|
|
@@ -154,6 +169,7 @@ fn send_user_message<T: UserEvent>(context: &Context<T>, message: Message<T>) ->
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
struct Context<T: UserEvent> {
|
|
|
+ webview_id_map: WebviewIdStore,
|
|
|
main_thread_id: ThreadId,
|
|
|
proxy: WryEventLoopProxy<Message<T>>,
|
|
|
window_event_listeners: WindowEventListeners,
|
|
@@ -161,13 +177,60 @@ struct Context<T: UserEvent> {
|
|
|
main_thread: DispatcherMainThreadContext<T>,
|
|
|
}
|
|
|
|
|
|
+impl<T: UserEvent> Context<T> {
|
|
|
+ fn prepare_window(&self, window_id: WebviewId) {
|
|
|
+ self
|
|
|
+ .window_event_listeners
|
|
|
+ .lock()
|
|
|
+ .unwrap()
|
|
|
+ .insert(window_id, WindowEventListenersMap::default());
|
|
|
+
|
|
|
+ self
|
|
|
+ .menu_event_listeners
|
|
|
+ .lock()
|
|
|
+ .unwrap()
|
|
|
+ .insert(window_id, WindowMenuEventListeners::default());
|
|
|
+ }
|
|
|
+
|
|
|
+ fn create_webview(&self, pending: PendingWindow<T, Wry<T>>) -> Result<DetachedWindow<T, Wry<T>>> {
|
|
|
+ let label = pending.label.clone();
|
|
|
+ let menu_ids = pending.menu_ids.clone();
|
|
|
+ let js_event_listeners = pending.js_event_listeners.clone();
|
|
|
+ let context = self.clone();
|
|
|
+ let window_id = rand::random();
|
|
|
+
|
|
|
+ self.prepare_window(window_id);
|
|
|
+
|
|
|
+ self
|
|
|
+ .proxy
|
|
|
+ .send_event(Message::CreateWebview(
|
|
|
+ window_id,
|
|
|
+ Box::new(move |event_loop, web_context| {
|
|
|
+ create_webview(window_id, event_loop, web_context, context, pending)
|
|
|
+ }),
|
|
|
+ ))
|
|
|
+ .map_err(|_| Error::FailedToSendMessage)?;
|
|
|
+
|
|
|
+ let dispatcher = WryDispatcher {
|
|
|
+ window_id,
|
|
|
+ context: self.clone(),
|
|
|
+ };
|
|
|
+ Ok(DetachedWindow {
|
|
|
+ label,
|
|
|
+ dispatcher,
|
|
|
+ menu_ids,
|
|
|
+ js_event_listeners,
|
|
|
+ })
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
#[derive(Debug, Clone)]
|
|
|
struct DispatcherMainThreadContext<T: UserEvent> {
|
|
|
window_target: EventLoopWindowTarget<Message<T>>,
|
|
|
web_context: WebContextStore,
|
|
|
global_shortcut_manager: Arc<Mutex<WryShortcutManager>>,
|
|
|
clipboard_manager: Arc<Mutex<Clipboard>>,
|
|
|
- windows: Arc<Mutex<HashMap<WindowId, WindowWrapper>>>,
|
|
|
+ windows: Arc<Mutex<HashMap<WebviewId, WindowWrapper>>>,
|
|
|
#[cfg(feature = "system-tray")]
|
|
|
tray_context: TrayContext,
|
|
|
}
|
|
@@ -827,7 +890,7 @@ impl WindowBuilder for WindowBuilderWrapper {
|
|
|
Ok(self)
|
|
|
}
|
|
|
|
|
|
- #[cfg(any(target_os = "windows", target_os = "linux"))]
|
|
|
+ #[cfg(any(windows, target_os = "linux"))]
|
|
|
fn skip_taskbar(mut self, skip: bool) -> Self {
|
|
|
self.inner = self.inner.with_skip_taskbar(skip);
|
|
|
self
|
|
@@ -996,12 +1059,13 @@ pub type CreateWebviewClosure<T> = Box<
|
|
|
|
|
|
pub enum Message<T: 'static> {
|
|
|
Task(Box<dyn FnOnce() + Send>),
|
|
|
- Window(WindowId, WindowMessage),
|
|
|
- Webview(WindowId, WebviewMessage),
|
|
|
+ Window(WebviewId, WindowMessage),
|
|
|
+ Webview(WebviewId, WebviewMessage),
|
|
|
#[cfg(feature = "system-tray")]
|
|
|
Tray(TrayMessage),
|
|
|
- CreateWebview(CreateWebviewClosure<T>, Sender<WindowId>),
|
|
|
+ CreateWebview(WebviewId, CreateWebviewClosure<T>),
|
|
|
CreateWindow(
|
|
|
+ WebviewId,
|
|
|
Box<dyn FnOnce() -> (String, WryWindowBuilder) + Send>,
|
|
|
Sender<Result<Weak<Window>>>,
|
|
|
),
|
|
@@ -1028,7 +1092,7 @@ impl<T: UserEvent> Clone for Message<T> {
|
|
|
/// The Tauri [`Dispatch`] for [`Wry`].
|
|
|
#[derive(Debug, Clone)]
|
|
|
pub struct WryDispatcher<T: UserEvent> {
|
|
|
- window_id: WindowId,
|
|
|
+ window_id: WebviewId,
|
|
|
context: Context<T>,
|
|
|
}
|
|
|
|
|
@@ -1198,33 +1262,7 @@ impl<T: UserEvent> Dispatch<T> for WryDispatcher<T> {
|
|
|
&mut self,
|
|
|
pending: PendingWindow<T, Self::Runtime>,
|
|
|
) -> Result<DetachedWindow<T, Self::Runtime>> {
|
|
|
- let (tx, rx) = channel();
|
|
|
- let label = pending.label.clone();
|
|
|
- let menu_ids = pending.menu_ids.clone();
|
|
|
- let js_event_listeners = pending.js_event_listeners.clone();
|
|
|
- let context = self.context.clone();
|
|
|
-
|
|
|
- send_user_message(
|
|
|
- &self.context,
|
|
|
- Message::CreateWebview(
|
|
|
- Box::new(move |event_loop, web_context| {
|
|
|
- create_webview(event_loop, web_context, context, pending)
|
|
|
- }),
|
|
|
- tx,
|
|
|
- ),
|
|
|
- )?;
|
|
|
- let window_id = rx.recv().unwrap();
|
|
|
-
|
|
|
- let dispatcher = WryDispatcher {
|
|
|
- window_id,
|
|
|
- context: self.context.clone(),
|
|
|
- };
|
|
|
- Ok(DetachedWindow {
|
|
|
- label,
|
|
|
- dispatcher,
|
|
|
- menu_ids,
|
|
|
- js_event_listeners,
|
|
|
- })
|
|
|
+ self.context.create_webview(pending)
|
|
|
}
|
|
|
|
|
|
fn set_resizable(&self, resizable: bool) -> Result<()> {
|
|
@@ -1475,7 +1513,8 @@ pub struct Wry<T: UserEvent> {
|
|
|
clipboard_manager: Arc<Mutex<Clipboard>>,
|
|
|
clipboard_manager_handle: ClipboardManagerWrapper<T>,
|
|
|
event_loop: EventLoop<Message<T>>,
|
|
|
- windows: Arc<Mutex<HashMap<WindowId, WindowWrapper>>>,
|
|
|
+ windows: Arc<Mutex<HashMap<WebviewId, WindowWrapper>>>,
|
|
|
+ webview_id_map: WebviewIdStore,
|
|
|
web_context: WebContextStore,
|
|
|
window_event_listeners: WindowEventListeners,
|
|
|
menu_event_listeners: MenuEventListeners,
|
|
@@ -1520,10 +1559,25 @@ impl<T: UserEvent> WryHandle<T> {
|
|
|
f: F,
|
|
|
) -> Result<Weak<Window>> {
|
|
|
let (tx, rx) = channel();
|
|
|
- send_user_message(&self.context, Message::CreateWindow(Box::new(f), tx))?;
|
|
|
+ send_user_message(
|
|
|
+ &self.context,
|
|
|
+ Message::CreateWindow(rand::random(), Box::new(f), tx),
|
|
|
+ )?;
|
|
|
rx.recv().unwrap()
|
|
|
}
|
|
|
|
|
|
+ /// Gets the [`WebviewId'] associated with the given [`WindowId`].
|
|
|
+ pub fn window_id(&self, window_id: WindowId) -> WebviewId {
|
|
|
+ *self
|
|
|
+ .context
|
|
|
+ .webview_id_map
|
|
|
+ .0
|
|
|
+ .lock()
|
|
|
+ .unwrap()
|
|
|
+ .get(&window_id)
|
|
|
+ .unwrap()
|
|
|
+ }
|
|
|
+
|
|
|
/// Send a message to the event loop.
|
|
|
pub fn send_event(&self, message: Message<T>) -> Result<()> {
|
|
|
self
|
|
@@ -1548,32 +1602,7 @@ impl<T: UserEvent> RuntimeHandle<T> for WryHandle<T> {
|
|
|
&self,
|
|
|
pending: PendingWindow<T, Self::Runtime>,
|
|
|
) -> Result<DetachedWindow<T, Self::Runtime>> {
|
|
|
- let (tx, rx) = channel();
|
|
|
- let label = pending.label.clone();
|
|
|
- let menu_ids = pending.menu_ids.clone();
|
|
|
- let js_event_listeners = pending.js_event_listeners.clone();
|
|
|
- let context = self.context.clone();
|
|
|
- send_user_message(
|
|
|
- &self.context,
|
|
|
- Message::CreateWebview(
|
|
|
- Box::new(move |event_loop, web_context| {
|
|
|
- create_webview(event_loop, web_context, context, pending)
|
|
|
- }),
|
|
|
- tx,
|
|
|
- ),
|
|
|
- )?;
|
|
|
- let window_id = rx.recv().unwrap();
|
|
|
-
|
|
|
- let dispatcher = WryDispatcher {
|
|
|
- window_id,
|
|
|
- context: self.context.clone(),
|
|
|
- };
|
|
|
- Ok(DetachedWindow {
|
|
|
- label,
|
|
|
- dispatcher,
|
|
|
- menu_ids,
|
|
|
- js_event_listeners,
|
|
|
- })
|
|
|
+ self.context.create_webview(pending)
|
|
|
}
|
|
|
|
|
|
fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()> {
|
|
@@ -1595,6 +1624,7 @@ impl<T: UserEvent> Wry<T> {
|
|
|
let global_shortcut_manager = Arc::new(Mutex::new(WryShortcutManager::new(&event_loop)));
|
|
|
let clipboard_manager = Arc::new(Mutex::new(Clipboard::new()));
|
|
|
let windows = Arc::new(Mutex::new(HashMap::default()));
|
|
|
+ let webview_id_map = WebviewIdStore::default();
|
|
|
let window_event_listeners = WindowEventListeners::default();
|
|
|
let menu_event_listeners = MenuEventListeners::default();
|
|
|
|
|
@@ -1602,6 +1632,7 @@ impl<T: UserEvent> Wry<T> {
|
|
|
let tray_context = TrayContext::default();
|
|
|
|
|
|
let event_loop_context = Context {
|
|
|
+ webview_id_map: webview_id_map.clone(),
|
|
|
main_thread_id,
|
|
|
proxy,
|
|
|
window_event_listeners: window_event_listeners.clone(),
|
|
@@ -1634,6 +1665,7 @@ impl<T: UserEvent> Wry<T> {
|
|
|
clipboard_manager_handle,
|
|
|
event_loop,
|
|
|
windows,
|
|
|
+ webview_id_map,
|
|
|
web_context,
|
|
|
window_event_listeners,
|
|
|
menu_event_listeners,
|
|
@@ -1674,6 +1706,7 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
|
|
|
fn handle(&self) -> Self::Handle {
|
|
|
WryHandle {
|
|
|
context: Context {
|
|
|
+ webview_id_map: self.webview_id_map.clone(),
|
|
|
main_thread_id: self.main_thread_id,
|
|
|
proxy: self.event_loop.create_proxy(),
|
|
|
window_event_listeners: self.window_event_listeners.clone(),
|
|
@@ -1704,89 +1737,38 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
|
|
|
let menu_ids = pending.menu_ids.clone();
|
|
|
let js_event_listeners = pending.js_event_listeners.clone();
|
|
|
let proxy = self.event_loop.create_proxy();
|
|
|
+ let window_id = rand::random();
|
|
|
+
|
|
|
+ let context = Context {
|
|
|
+ webview_id_map: self.webview_id_map.clone(),
|
|
|
+ main_thread_id: self.main_thread_id,
|
|
|
+ proxy,
|
|
|
+ window_event_listeners: self.window_event_listeners.clone(),
|
|
|
+ menu_event_listeners: self.menu_event_listeners.clone(),
|
|
|
+ main_thread: DispatcherMainThreadContext {
|
|
|
+ window_target: self.event_loop.deref().clone(),
|
|
|
+ web_context: self.web_context.clone(),
|
|
|
+ global_shortcut_manager: self.global_shortcut_manager.clone(),
|
|
|
+ clipboard_manager: self.clipboard_manager.clone(),
|
|
|
+ windows: self.windows.clone(),
|
|
|
+ #[cfg(feature = "system-tray")]
|
|
|
+ tray_context: self.tray_context.clone(),
|
|
|
+ },
|
|
|
+ };
|
|
|
+
|
|
|
+ context.prepare_window(window_id);
|
|
|
+
|
|
|
let webview = create_webview(
|
|
|
+ window_id,
|
|
|
&self.event_loop,
|
|
|
&self.web_context,
|
|
|
- Context {
|
|
|
- main_thread_id: self.main_thread_id,
|
|
|
- proxy: proxy.clone(),
|
|
|
- window_event_listeners: self.window_event_listeners.clone(),
|
|
|
- menu_event_listeners: self.menu_event_listeners.clone(),
|
|
|
- main_thread: DispatcherMainThreadContext {
|
|
|
- window_target: self.event_loop.deref().clone(),
|
|
|
- web_context: self.web_context.clone(),
|
|
|
- global_shortcut_manager: self.global_shortcut_manager.clone(),
|
|
|
- clipboard_manager: self.clipboard_manager.clone(),
|
|
|
- windows: self.windows.clone(),
|
|
|
- #[cfg(feature = "system-tray")]
|
|
|
- tray_context: self.tray_context.clone(),
|
|
|
- },
|
|
|
- },
|
|
|
+ context.clone(),
|
|
|
pending,
|
|
|
)?;
|
|
|
|
|
|
- #[cfg(target_os = "windows")]
|
|
|
- {
|
|
|
- let id = webview.inner.window().id();
|
|
|
- if let WindowHandle::Webview(ref webview) = webview.inner {
|
|
|
- if let Some(controller) = webview.controller() {
|
|
|
- let proxy = self.event_loop.create_proxy();
|
|
|
- let mut token = EventRegistrationToken::default();
|
|
|
- unsafe {
|
|
|
- controller.GotFocus(
|
|
|
- FocusChangedEventHandler::create(Box::new(move |_, _| {
|
|
|
- let _ = proxy.send_event(Message::Webview(
|
|
|
- id,
|
|
|
- WebviewMessage::WebviewEvent(WebviewEvent::Focused(true)),
|
|
|
- ));
|
|
|
- Ok(())
|
|
|
- })),
|
|
|
- &mut token,
|
|
|
- )
|
|
|
- }
|
|
|
- .unwrap();
|
|
|
- let proxy = self.event_loop.create_proxy();
|
|
|
- unsafe {
|
|
|
- controller.LostFocus(
|
|
|
- FocusChangedEventHandler::create(Box::new(move |_, _| {
|
|
|
- let _ = proxy.send_event(Message::Webview(
|
|
|
- id,
|
|
|
- WebviewMessage::WebviewEvent(WebviewEvent::Focused(false)),
|
|
|
- ));
|
|
|
- Ok(())
|
|
|
- })),
|
|
|
- &mut token,
|
|
|
- )
|
|
|
- }
|
|
|
- .unwrap();
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ let dispatcher = WryDispatcher { window_id, context };
|
|
|
|
|
|
- let dispatcher = WryDispatcher {
|
|
|
- window_id: webview.inner.window().id(),
|
|
|
- context: Context {
|
|
|
- main_thread_id: self.main_thread_id,
|
|
|
- proxy,
|
|
|
- window_event_listeners: self.window_event_listeners.clone(),
|
|
|
- menu_event_listeners: self.menu_event_listeners.clone(),
|
|
|
- main_thread: DispatcherMainThreadContext {
|
|
|
- window_target: self.event_loop.deref().clone(),
|
|
|
- web_context: self.web_context.clone(),
|
|
|
- global_shortcut_manager: self.global_shortcut_manager.clone(),
|
|
|
- clipboard_manager: self.clipboard_manager.clone(),
|
|
|
- windows: self.windows.clone(),
|
|
|
- #[cfg(feature = "system-tray")]
|
|
|
- tray_context: self.tray_context.clone(),
|
|
|
- },
|
|
|
- },
|
|
|
- };
|
|
|
-
|
|
|
- self
|
|
|
- .windows
|
|
|
- .lock()
|
|
|
- .unwrap()
|
|
|
- .insert(webview.inner.window().id(), webview);
|
|
|
+ self.windows.lock().unwrap().insert(window_id, webview);
|
|
|
|
|
|
Ok(DetachedWindow {
|
|
|
label,
|
|
@@ -1861,6 +1843,7 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
|
|
|
fn run_iteration<F: FnMut(RunEvent<T>) + 'static>(&mut self, mut callback: F) -> RunIteration {
|
|
|
use wry::application::platform::run_return::EventLoopExtRunReturn;
|
|
|
let windows = self.windows.clone();
|
|
|
+ let webview_id_map = self.webview_id_map.clone();
|
|
|
let web_context = &self.web_context;
|
|
|
let window_event_listeners = self.window_event_listeners.clone();
|
|
|
let menu_event_listeners = self.menu_event_listeners.clone();
|
|
@@ -1886,6 +1869,7 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
|
|
|
EventLoopIterationContext {
|
|
|
callback: &mut callback,
|
|
|
windows: windows.clone(),
|
|
|
+ webview_id_map: webview_id_map.clone(),
|
|
|
window_event_listeners: &window_event_listeners,
|
|
|
global_shortcut_manager: global_shortcut_manager.clone(),
|
|
|
global_shortcut_manager_handle: &global_shortcut_manager_handle,
|
|
@@ -1903,6 +1887,7 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
|
|
|
|
|
|
fn run<F: FnMut(RunEvent<T>) + 'static>(self, mut callback: F) {
|
|
|
let windows = self.windows.clone();
|
|
|
+ let webview_id_map = self.webview_id_map.clone();
|
|
|
let web_context = self.web_context;
|
|
|
let window_event_listeners = self.window_event_listeners.clone();
|
|
|
let menu_event_listeners = self.menu_event_listeners.clone();
|
|
@@ -1919,6 +1904,7 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
|
|
|
control_flow,
|
|
|
EventLoopIterationContext {
|
|
|
callback: &mut callback,
|
|
|
+ webview_id_map: webview_id_map.clone(),
|
|
|
windows: windows.clone(),
|
|
|
window_event_listeners: &window_event_listeners,
|
|
|
global_shortcut_manager: global_shortcut_manager.clone(),
|
|
@@ -1936,7 +1922,8 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
|
|
|
|
|
|
pub struct EventLoopIterationContext<'a, T: UserEvent> {
|
|
|
callback: &'a mut (dyn FnMut(RunEvent<T>) + 'static),
|
|
|
- windows: Arc<Mutex<HashMap<WindowId, WindowWrapper>>>,
|
|
|
+ webview_id_map: WebviewIdStore,
|
|
|
+ windows: Arc<Mutex<HashMap<WebviewId, WindowWrapper>>>,
|
|
|
window_event_listeners: &'a WindowEventListeners,
|
|
|
global_shortcut_manager: Arc<Mutex<WryShortcutManager>>,
|
|
|
global_shortcut_manager_handle: &'a GlobalShortcutManagerHandle<T>,
|
|
@@ -1951,7 +1938,7 @@ struct UserMessageContext<'a> {
|
|
|
global_shortcut_manager: Arc<Mutex<WryShortcutManager>>,
|
|
|
clipboard_manager: Arc<Mutex<Clipboard>>,
|
|
|
menu_event_listeners: &'a MenuEventListeners,
|
|
|
- windows: Arc<Mutex<HashMap<WindowId, WindowWrapper>>>,
|
|
|
+ windows: Arc<Mutex<HashMap<WebviewId, WindowWrapper>>>,
|
|
|
#[cfg(feature = "system-tray")]
|
|
|
tray_context: &'a TrayContext,
|
|
|
}
|
|
@@ -2081,7 +2068,7 @@ fn handle_user_message<T: UserEvent>(
|
|
|
window.set_window_icon(Some(icon));
|
|
|
}
|
|
|
WindowMessage::SetSkipTaskbar(_skip) => {
|
|
|
- #[cfg(any(target_os = "windows", target_os = "linux"))]
|
|
|
+ #[cfg(any(windows, target_os = "linux"))]
|
|
|
window.set_skip_taskbar(_skip);
|
|
|
}
|
|
|
WindowMessage::DragWindow => {
|
|
@@ -2147,34 +2134,30 @@ fn handle_user_message<T: UserEvent>(
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
- Message::CreateWebview(handler, sender) => match handler(event_loop, web_context) {
|
|
|
+ Message::CreateWebview(window_id, handler) => match handler(event_loop, web_context) {
|
|
|
Ok(webview) => {
|
|
|
- let window_id = webview.inner.window().id();
|
|
|
windows
|
|
|
.lock()
|
|
|
.expect("poisoned webview collection")
|
|
|
.insert(window_id, webview);
|
|
|
- sender.send(window_id).unwrap();
|
|
|
}
|
|
|
Err(e) => {
|
|
|
#[cfg(debug_assertions)]
|
|
|
eprintln!("{}", e);
|
|
|
}
|
|
|
},
|
|
|
- Message::CreateWindow(handler, sender) => {
|
|
|
+ Message::CreateWindow(window_id, handler, sender) => {
|
|
|
let (label, builder) = handler();
|
|
|
if let Ok(window) = builder.build(event_loop) {
|
|
|
- let window_id = window.id();
|
|
|
-
|
|
|
window_event_listeners
|
|
|
.lock()
|
|
|
.unwrap()
|
|
|
- .insert(window.id(), WindowEventListenersMap::default());
|
|
|
+ .insert(window_id, WindowEventListenersMap::default());
|
|
|
|
|
|
menu_event_listeners
|
|
|
.lock()
|
|
|
.unwrap()
|
|
|
- .insert(window.id(), WindowMenuEventListeners::default());
|
|
|
+ .insert(window_id, WindowMenuEventListeners::default());
|
|
|
|
|
|
let w = Arc::new(window);
|
|
|
|
|
@@ -2299,6 +2282,7 @@ fn handle_event_loop<T: UserEvent>(
|
|
|
) -> RunIteration {
|
|
|
let EventLoopIterationContext {
|
|
|
callback,
|
|
|
+ webview_id_map,
|
|
|
windows,
|
|
|
window_event_listeners,
|
|
|
global_shortcut_manager,
|
|
@@ -2347,6 +2331,7 @@ fn handle_event_loop<T: UserEvent>(
|
|
|
menu_item_id: menu_id.0,
|
|
|
};
|
|
|
let window_menu_event_listeners = {
|
|
|
+ let window_id = webview_id_map.get(&window_id);
|
|
|
let listeners = menu_event_listeners.lock().unwrap();
|
|
|
listeners.get(&window_id).cloned().unwrap_or_default()
|
|
|
};
|
|
@@ -2390,6 +2375,7 @@ fn handle_event_loop<T: UserEvent>(
|
|
|
Event::WindowEvent {
|
|
|
event, window_id, ..
|
|
|
} => {
|
|
|
+ let window_id = webview_id_map.get(&window_id);
|
|
|
// NOTE(amrbashir): we handle this event here instead of `match` statement below because
|
|
|
// we want to focus the webview as soon as possible, especially on windows.
|
|
|
if event == WryWindowEvent::Focused(true) {
|
|
@@ -2496,8 +2482,8 @@ fn handle_event_loop<T: UserEvent>(
|
|
|
|
|
|
fn on_close_requested<'a, T: UserEvent>(
|
|
|
callback: &'a mut (dyn FnMut(RunEvent<T>) + 'static),
|
|
|
- window_id: WindowId,
|
|
|
- windows: Arc<Mutex<HashMap<WindowId, WindowWrapper>>>,
|
|
|
+ window_id: WebviewId,
|
|
|
+ windows: Arc<Mutex<HashMap<WebviewId, WindowWrapper>>>,
|
|
|
control_flow: &mut ControlFlow,
|
|
|
window_event_listeners: &WindowEventListeners,
|
|
|
menu_event_listeners: MenuEventListeners,
|
|
@@ -2545,8 +2531,8 @@ fn on_close_requested<'a, T: UserEvent>(
|
|
|
|
|
|
fn on_window_close<'a, T: UserEvent>(
|
|
|
callback: &'a mut (dyn FnMut(RunEvent<T>) + 'static),
|
|
|
- window_id: WindowId,
|
|
|
- mut windows: MutexGuard<'a, HashMap<WindowId, WindowWrapper>>,
|
|
|
+ window_id: WebviewId,
|
|
|
+ mut windows: MutexGuard<'a, HashMap<WebviewId, WindowWrapper>>,
|
|
|
control_flow: &mut ControlFlow,
|
|
|
#[cfg(target_os = "linux")] window_event_listeners: &WindowEventListeners,
|
|
|
menu_event_listeners: MenuEventListeners,
|
|
@@ -2641,6 +2627,7 @@ fn to_wry_menu(
|
|
|
}
|
|
|
|
|
|
fn create_webview<T: UserEvent>(
|
|
|
+ window_id: WebviewId,
|
|
|
event_loop: &EventLoopWindowTarget<Message<T>>,
|
|
|
web_context: &WebContextStore,
|
|
|
context: Context<T>,
|
|
@@ -2658,6 +2645,9 @@ fn create_webview<T: UserEvent>(
|
|
|
js_event_listeners,
|
|
|
..
|
|
|
} = pending;
|
|
|
+ let webview_id_map = context.webview_id_map.clone();
|
|
|
+ #[cfg(windows)]
|
|
|
+ let proxy = context.proxy.clone();
|
|
|
|
|
|
let is_window_transparent = window_builder.inner.window.transparent;
|
|
|
let menu_items = if let Some(menu) = window_builder.menu {
|
|
@@ -2670,18 +2660,6 @@ fn create_webview<T: UserEvent>(
|
|
|
};
|
|
|
let window = window_builder.inner.build(event_loop).unwrap();
|
|
|
|
|
|
- context
|
|
|
- .window_event_listeners
|
|
|
- .lock()
|
|
|
- .unwrap()
|
|
|
- .insert(window.id(), WindowEventListenersMap::default());
|
|
|
-
|
|
|
- context
|
|
|
- .menu_event_listeners
|
|
|
- .lock()
|
|
|
- .unwrap()
|
|
|
- .insert(window.id(), WindowMenuEventListeners::default());
|
|
|
-
|
|
|
if window_builder.center {
|
|
|
let _ = center_window(&window, window.inner_size());
|
|
|
}
|
|
@@ -2753,6 +2731,42 @@ fn create_webview<T: UserEvent>(
|
|
|
.build()
|
|
|
.map_err(|e| Error::CreateWebview(Box::new(e)))?;
|
|
|
|
|
|
+ webview_id_map.insert(webview.window().id(), window_id);
|
|
|
+
|
|
|
+ #[cfg(windows)]
|
|
|
+ {
|
|
|
+ if let Some(controller) = webview.controller() {
|
|
|
+ let proxy_ = proxy.clone();
|
|
|
+ let mut token = EventRegistrationToken::default();
|
|
|
+ unsafe {
|
|
|
+ controller.GotFocus(
|
|
|
+ FocusChangedEventHandler::create(Box::new(move |_, _| {
|
|
|
+ let _ = proxy_.send_event(Message::Webview(
|
|
|
+ window_id,
|
|
|
+ WebviewMessage::WebviewEvent(WebviewEvent::Focused(true)),
|
|
|
+ ));
|
|
|
+ Ok(())
|
|
|
+ })),
|
|
|
+ &mut token,
|
|
|
+ )
|
|
|
+ }
|
|
|
+ .unwrap();
|
|
|
+ unsafe {
|
|
|
+ controller.LostFocus(
|
|
|
+ FocusChangedEventHandler::create(Box::new(move |_, _| {
|
|
|
+ let _ = proxy.send_event(Message::Webview(
|
|
|
+ window_id,
|
|
|
+ WebviewMessage::WebviewEvent(WebviewEvent::Focused(false)),
|
|
|
+ ));
|
|
|
+ Ok(())
|
|
|
+ })),
|
|
|
+ &mut token,
|
|
|
+ )
|
|
|
+ }
|
|
|
+ .unwrap();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
Ok(WindowWrapper {
|
|
|
label,
|
|
|
inner: WindowHandle::Webview(webview),
|
|
@@ -2772,7 +2786,13 @@ fn create_ipc_handler<T: UserEvent>(
|
|
|
handler(
|
|
|
DetachedWindow {
|
|
|
dispatcher: WryDispatcher {
|
|
|
- window_id: window.id(),
|
|
|
+ window_id: *context
|
|
|
+ .webview_id_map
|
|
|
+ .0
|
|
|
+ .lock()
|
|
|
+ .unwrap()
|
|
|
+ .get(&window.id())
|
|
|
+ .unwrap(),
|
|
|
context: context.clone(),
|
|
|
},
|
|
|
label: label.clone(),
|
|
@@ -2789,11 +2809,12 @@ fn create_file_drop_handler<T: UserEvent>(
|
|
|
context: &Context<T>,
|
|
|
) -> Box<dyn Fn(&Window, WryFileDropEvent) -> bool + 'static> {
|
|
|
let window_event_listeners = context.window_event_listeners.clone();
|
|
|
+ let webview_id_map = context.webview_id_map.clone();
|
|
|
Box::new(move |window, event| {
|
|
|
let event: FileDropEvent = FileDropEventWrapper(event).into();
|
|
|
let window_event = WindowEvent::FileDrop(event);
|
|
|
let listeners = window_event_listeners.lock().unwrap();
|
|
|
- if let Some(window_listeners) = listeners.get(&window.id()) {
|
|
|
+ if let Some(window_listeners) = listeners.get(&webview_id_map.get(&window.id())) {
|
|
|
let listeners_map = window_listeners.lock().unwrap();
|
|
|
let has_listener = !listeners_map.is_empty();
|
|
|
for listener in listeners_map.values() {
|