Finish window::open only when window fully opens
... and run initial `Task` after `window::open` for applications. This fixes certain race conditions.
This commit is contained in:
parent
8c110c1be9
commit
1c1bee6fd8
1 changed files with 22 additions and 25 deletions
|
|
@ -202,6 +202,16 @@ where
|
||||||
};
|
};
|
||||||
|
|
||||||
let (program, task) = runtime.enter(|| P::new(flags));
|
let (program, task) = runtime.enter(|| P::new(flags));
|
||||||
|
let is_daemon = window_settings.is_none();
|
||||||
|
|
||||||
|
let task = if let Some(window_settings) = window_settings {
|
||||||
|
let mut task = Some(task);
|
||||||
|
|
||||||
|
runtime::window::open(window_settings)
|
||||||
|
.then(move |_| task.take().unwrap_or(Task::none()))
|
||||||
|
} else {
|
||||||
|
task
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(stream) = runtime::task::into_stream(task) {
|
if let Some(stream) = runtime::task::into_stream(task) {
|
||||||
runtime.run(stream);
|
runtime.run(stream);
|
||||||
|
|
@ -223,6 +233,7 @@ where
|
||||||
boot_receiver,
|
boot_receiver,
|
||||||
event_receiver,
|
event_receiver,
|
||||||
control_sender,
|
control_sender,
|
||||||
|
is_daemon,
|
||||||
));
|
));
|
||||||
|
|
||||||
let context = task::Context::from_waker(task::noop_waker_ref());
|
let context = task::Context::from_waker(task::noop_waker_ref());
|
||||||
|
|
@ -231,7 +242,7 @@ where
|
||||||
instance: std::pin::Pin<Box<F>>,
|
instance: std::pin::Pin<Box<F>>,
|
||||||
context: task::Context<'static>,
|
context: task::Context<'static>,
|
||||||
id: Option<String>,
|
id: Option<String>,
|
||||||
boot: Option<BootConfig<Message, C>>,
|
boot: Option<BootConfig<C>>,
|
||||||
sender: mpsc::UnboundedSender<Event<Action<Message>>>,
|
sender: mpsc::UnboundedSender<Event<Action<Message>>>,
|
||||||
receiver: mpsc::UnboundedReceiver<Control>,
|
receiver: mpsc::UnboundedReceiver<Control>,
|
||||||
error: Option<Error>,
|
error: Option<Error>,
|
||||||
|
|
@ -242,11 +253,9 @@ where
|
||||||
queued_events: Vec<Event<Action<Message>>>,
|
queued_events: Vec<Event<Action<Message>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BootConfig<Message: 'static, C> {
|
struct BootConfig<C> {
|
||||||
proxy: Proxy<Message>,
|
|
||||||
sender: oneshot::Sender<Boot<C>>,
|
sender: oneshot::Sender<Boot<C>>,
|
||||||
fonts: Vec<Cow<'static, [u8]>>,
|
fonts: Vec<Cow<'static, [u8]>>,
|
||||||
window_settings: Option<window::Settings>,
|
|
||||||
graphics_settings: graphics::Settings,
|
graphics_settings: graphics::Settings,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -255,10 +264,8 @@ where
|
||||||
context,
|
context,
|
||||||
id: settings.id,
|
id: settings.id,
|
||||||
boot: Some(BootConfig {
|
boot: Some(BootConfig {
|
||||||
proxy,
|
|
||||||
sender: boot_sender,
|
sender: boot_sender,
|
||||||
fonts: settings.fonts,
|
fonts: settings.fonts,
|
||||||
window_settings,
|
|
||||||
graphics_settings,
|
graphics_settings,
|
||||||
}),
|
}),
|
||||||
sender: event_sender,
|
sender: event_sender,
|
||||||
|
|
@ -280,10 +287,8 @@ where
|
||||||
{
|
{
|
||||||
fn resumed(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) {
|
fn resumed(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) {
|
||||||
let Some(BootConfig {
|
let Some(BootConfig {
|
||||||
mut proxy,
|
|
||||||
sender,
|
sender,
|
||||||
fonts,
|
fonts,
|
||||||
window_settings,
|
|
||||||
graphics_settings,
|
graphics_settings,
|
||||||
}) = self.boot.take()
|
}) = self.boot.take()
|
||||||
else {
|
else {
|
||||||
|
|
@ -316,23 +321,10 @@ where
|
||||||
compositor,
|
compositor,
|
||||||
clipboard,
|
clipboard,
|
||||||
window: window.id(),
|
window: window.id(),
|
||||||
is_daemon: window_settings.is_none(),
|
|
||||||
})
|
})
|
||||||
.ok()
|
.ok()
|
||||||
.expect("Send boot event");
|
.expect("Send boot event");
|
||||||
|
|
||||||
if let Some(window_settings) = window_settings {
|
|
||||||
let (sender, _receiver) = oneshot::channel();
|
|
||||||
|
|
||||||
proxy.send_action(Action::Window(
|
|
||||||
runtime::window::Action::Open(
|
|
||||||
window::Id::unique(),
|
|
||||||
window_settings,
|
|
||||||
sender,
|
|
||||||
),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok::<_, graphics::Error>(())
|
Ok::<_, graphics::Error>(())
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -490,6 +482,7 @@ where
|
||||||
settings,
|
settings,
|
||||||
title,
|
title,
|
||||||
monitor,
|
monitor,
|
||||||
|
on_open,
|
||||||
} => {
|
} => {
|
||||||
let exit_on_close_request =
|
let exit_on_close_request =
|
||||||
settings.exit_on_close_request;
|
settings.exit_on_close_request;
|
||||||
|
|
@ -567,6 +560,7 @@ where
|
||||||
window,
|
window,
|
||||||
exit_on_close_request,
|
exit_on_close_request,
|
||||||
make_visible: visible,
|
make_visible: visible,
|
||||||
|
on_open,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -608,7 +602,6 @@ struct Boot<C> {
|
||||||
compositor: C,
|
compositor: C,
|
||||||
clipboard: Clipboard,
|
clipboard: Clipboard,
|
||||||
window: winit::window::WindowId,
|
window: winit::window::WindowId,
|
||||||
is_daemon: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Event<Message: 'static> {
|
enum Event<Message: 'static> {
|
||||||
|
|
@ -617,6 +610,7 @@ enum Event<Message: 'static> {
|
||||||
window: winit::window::Window,
|
window: winit::window::Window,
|
||||||
exit_on_close_request: bool,
|
exit_on_close_request: bool,
|
||||||
make_visible: bool,
|
make_visible: bool,
|
||||||
|
on_open: oneshot::Sender<window::Id>,
|
||||||
},
|
},
|
||||||
EventLoopAwakened(winit::event::Event<Message>),
|
EventLoopAwakened(winit::event::Event<Message>),
|
||||||
}
|
}
|
||||||
|
|
@ -629,6 +623,7 @@ enum Control {
|
||||||
settings: window::Settings,
|
settings: window::Settings,
|
||||||
title: String,
|
title: String,
|
||||||
monitor: Option<winit::monitor::MonitorHandle>,
|
monitor: Option<winit::monitor::MonitorHandle>,
|
||||||
|
on_open: oneshot::Sender<window::Id>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -640,6 +635,7 @@ async fn run_instance<P, C>(
|
||||||
mut boot: oneshot::Receiver<Boot<C>>,
|
mut boot: oneshot::Receiver<Boot<C>>,
|
||||||
mut event_receiver: mpsc::UnboundedReceiver<Event<Action<P::Message>>>,
|
mut event_receiver: mpsc::UnboundedReceiver<Event<Action<P::Message>>>,
|
||||||
mut control_sender: mpsc::UnboundedSender<Control>,
|
mut control_sender: mpsc::UnboundedSender<Control>,
|
||||||
|
is_daemon: bool,
|
||||||
) where
|
) where
|
||||||
P: Program + 'static,
|
P: Program + 'static,
|
||||||
C: Compositor<Renderer = P::Renderer> + 'static,
|
C: Compositor<Renderer = P::Renderer> + 'static,
|
||||||
|
|
@ -652,7 +648,6 @@ async fn run_instance<P, C>(
|
||||||
mut compositor,
|
mut compositor,
|
||||||
mut clipboard,
|
mut clipboard,
|
||||||
window: boot_window,
|
window: boot_window,
|
||||||
is_daemon,
|
|
||||||
} = boot.try_recv().ok().flatten().expect("Receive boot");
|
} = boot.try_recv().ok().flatten().expect("Receive boot");
|
||||||
|
|
||||||
let mut window_manager = WindowManager::new();
|
let mut window_manager = WindowManager::new();
|
||||||
|
|
@ -673,6 +668,7 @@ async fn run_instance<P, C>(
|
||||||
window,
|
window,
|
||||||
exit_on_close_request,
|
exit_on_close_request,
|
||||||
make_visible,
|
make_visible,
|
||||||
|
on_open,
|
||||||
} => {
|
} => {
|
||||||
let window = window_manager.insert(
|
let window = window_manager.insert(
|
||||||
id,
|
id,
|
||||||
|
|
@ -708,6 +704,8 @@ async fn run_instance<P, C>(
|
||||||
size: window.size(),
|
size: window.size(),
|
||||||
}),
|
}),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
let _ = on_open.send(id);
|
||||||
}
|
}
|
||||||
Event::EventLoopAwakened(event) => {
|
Event::EventLoopAwakened(event) => {
|
||||||
match event {
|
match event {
|
||||||
|
|
@ -1180,10 +1178,9 @@ fn run_action<P, C>(
|
||||||
settings,
|
settings,
|
||||||
title: program.title(id),
|
title: program.title(id),
|
||||||
monitor,
|
monitor,
|
||||||
|
on_open: channel,
|
||||||
})
|
})
|
||||||
.expect("Send control action");
|
.expect("Send control action");
|
||||||
|
|
||||||
let _ = channel.send(id);
|
|
||||||
}
|
}
|
||||||
window::Action::Close(id) => {
|
window::Action::Close(id) => {
|
||||||
let _ = window_manager.remove(id);
|
let _ = window_manager.remove(id);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue