mirror of
https://github.com/emilk/egui.git
synced 2026-09-02 06:40:06 -04:00
Fix: First frame of Context::create_viewport_sync was always skiped because we didn't have a window to draw on!
Changes: Now Context::create_viewport_sync returns T, before was Option<T>
This commit is contained in:
@@ -29,6 +29,13 @@ pub const IS_DESKTOP: bool = cfg!(any(
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
thread_local! {
|
||||||
|
/// This makes `Context::create_viewport_sync` to have a native window in the same frame!
|
||||||
|
pub static WINIT_EVENT_LOOP: RwLock<*const EventLoopWindowTarget<UserEvent>> = RwLock::new(std::ptr::null());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum UserEvent {
|
pub enum UserEvent {
|
||||||
RequestRepaint {
|
RequestRepaint {
|
||||||
@@ -152,6 +159,8 @@ fn run_and_return(
|
|||||||
let mut returned_result = Ok(());
|
let mut returned_result = Ok(());
|
||||||
|
|
||||||
event_loop.run_return(|event, event_loop, control_flow| {
|
event_loop.run_return(|event, event_loop, control_flow| {
|
||||||
|
WINIT_EVENT_LOOP.with(|row_event_loop| *row_event_loop.write() = event_loop);
|
||||||
|
|
||||||
let events = match &event {
|
let events = match &event {
|
||||||
winit::event::Event::LoopDestroyed => {
|
winit::event::Event::LoopDestroyed => {
|
||||||
// On Mac, Cmd-Q we get here and then `run_return` doesn't return (despite its name),
|
// On Mac, Cmd-Q we get here and then `run_return` doesn't return (despite its name),
|
||||||
@@ -309,6 +318,8 @@ fn run_and_exit(event_loop: EventLoop<UserEvent>, mut winit_app: impl WinitApp +
|
|||||||
let mut windows_next_repaint_times = HashMap::default();
|
let mut windows_next_repaint_times = HashMap::default();
|
||||||
|
|
||||||
event_loop.run(move |event, event_loop, control_flow| {
|
event_loop.run(move |event, event_loop, control_flow| {
|
||||||
|
WINIT_EVENT_LOOP.with(|row_event_loop| *row_event_loop.write() = event_loop);
|
||||||
|
|
||||||
let events = match event {
|
let events = match event {
|
||||||
winit::event::Event::LoopDestroyed => {
|
winit::event::Event::LoopDestroyed => {
|
||||||
log::debug!("Received Event::LoopDestroyed");
|
log::debug!("Received Event::LoopDestroyed");
|
||||||
@@ -654,89 +665,100 @@ mod glow_integration {
|
|||||||
/// 4. make surface and context current.
|
/// 4. make surface and context current.
|
||||||
///
|
///
|
||||||
/// we presently assume that we will
|
/// we presently assume that we will
|
||||||
#[allow(unsafe_code)]
|
|
||||||
fn on_resume(&mut self, event_loop: &EventLoopWindowTarget<UserEvent>) -> Result<()> {
|
fn on_resume(&mut self, event_loop: &EventLoopWindowTarget<UserEvent>) -> Result<()> {
|
||||||
for win in self.windows.values_mut() {
|
let values = self
|
||||||
let mut win = win.write();
|
.windows
|
||||||
if win.gl_surface.is_some() {
|
.values()
|
||||||
|
.cloned()
|
||||||
|
.collect::<Vec<Arc<RwLock<Window>>>>();
|
||||||
|
for win in values {
|
||||||
|
if win.read().gl_surface.is_some() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
log::debug!("running on_resume fn.");
|
self.init_window(&win, event_loop)?;
|
||||||
// make sure we have a window or create one.
|
|
||||||
let window = win.window.take().unwrap_or_else(|| {
|
|
||||||
log::debug!("window doesn't exist yet. creating one now with finalize_window");
|
|
||||||
Arc::new(RwLock::new(
|
|
||||||
glutin_winit::finalize_window(
|
|
||||||
event_loop,
|
|
||||||
create_winit_window_builder(&win.builder),
|
|
||||||
&self.gl_config,
|
|
||||||
)
|
|
||||||
.expect("failed to finalize glutin window"),
|
|
||||||
))
|
|
||||||
});
|
|
||||||
{
|
|
||||||
let window = window.read();
|
|
||||||
// surface attributes
|
|
||||||
let (width, height): (u32, u32) = window.inner_size().into();
|
|
||||||
let width = std::num::NonZeroU32::new(width.at_least(1)).unwrap();
|
|
||||||
let height = std::num::NonZeroU32::new(height.at_least(1)).unwrap();
|
|
||||||
let surface_attributes = glutin::surface::SurfaceAttributesBuilder::<
|
|
||||||
glutin::surface::WindowSurface,
|
|
||||||
>::new()
|
|
||||||
.build(window.raw_window_handle(), width, height);
|
|
||||||
log::debug!(
|
|
||||||
"creating surface with attributes: {:?}",
|
|
||||||
&surface_attributes
|
|
||||||
);
|
|
||||||
// create surface
|
|
||||||
let gl_surface = unsafe {
|
|
||||||
self.gl_config
|
|
||||||
.display()
|
|
||||||
.create_window_surface(&self.gl_config, &surface_attributes)?
|
|
||||||
};
|
|
||||||
log::debug!(
|
|
||||||
"surface created successfully: {gl_surface:?}.making context current"
|
|
||||||
);
|
|
||||||
// make surface and context current.
|
|
||||||
let not_current_gl_context =
|
|
||||||
if let Some(not_current_context) = self.not_current_gl_context.take() {
|
|
||||||
not_current_context
|
|
||||||
} else {
|
|
||||||
self.current_gl_context
|
|
||||||
.take()
|
|
||||||
.unwrap()
|
|
||||||
.make_not_current()
|
|
||||||
.unwrap()
|
|
||||||
};
|
|
||||||
let current_gl_context = not_current_gl_context.make_current(&gl_surface)?;
|
|
||||||
// try setting swap interval. but its not absolutely necessary, so don't panic on failure.
|
|
||||||
log::debug!("made context current. setting swap interval for surface");
|
|
||||||
if let Err(e) =
|
|
||||||
gl_surface.set_swap_interval(¤t_gl_context, self.swap_interval)
|
|
||||||
{
|
|
||||||
log::error!("failed to set swap interval due to error: {e:?}");
|
|
||||||
}
|
|
||||||
// we will reach this point only once in most platforms except android.
|
|
||||||
// create window/surface/make context current once and just use them forever.
|
|
||||||
|
|
||||||
let native_pixels_per_point = window.scale_factor() as f32;
|
|
||||||
|
|
||||||
if win.egui_winit.is_none() {
|
|
||||||
let mut egui_winit = egui_winit::State::new(event_loop);
|
|
||||||
// egui_winit.set_max_texture_side(max_texture_side);
|
|
||||||
egui_winit.set_pixels_per_point(native_pixels_per_point);
|
|
||||||
win.egui_winit = Some(egui_winit);
|
|
||||||
}
|
|
||||||
|
|
||||||
win.gl_surface = Some(gl_surface);
|
|
||||||
self.current_gl_context = Some(current_gl_context);
|
|
||||||
self.window_maps.insert(window.id(), win.window_id);
|
|
||||||
}
|
|
||||||
win.window = Some(window);
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
pub(crate) fn init_window(
|
||||||
|
&mut self,
|
||||||
|
win: &Arc<RwLock<Window>>,
|
||||||
|
event_loop: &EventLoopWindowTarget<UserEvent>,
|
||||||
|
) -> Result<()> {
|
||||||
|
let mut win = win.write();
|
||||||
|
// make sure we have a window or create one.
|
||||||
|
let window = win.window.take().unwrap_or_else(|| {
|
||||||
|
log::debug!("window doesn't exist yet. creating one now with finalize_window");
|
||||||
|
Arc::new(RwLock::new(
|
||||||
|
glutin_winit::finalize_window(
|
||||||
|
event_loop,
|
||||||
|
create_winit_window_builder(&win.builder),
|
||||||
|
&self.gl_config,
|
||||||
|
)
|
||||||
|
.expect("failed to finalize glutin window"),
|
||||||
|
))
|
||||||
|
});
|
||||||
|
{
|
||||||
|
let window = window.read();
|
||||||
|
// surface attributes
|
||||||
|
let (width, height): (u32, u32) = window.inner_size().into();
|
||||||
|
let width = std::num::NonZeroU32::new(width.at_least(1)).unwrap();
|
||||||
|
let height = std::num::NonZeroU32::new(height.at_least(1)).unwrap();
|
||||||
|
let surface_attributes = glutin::surface::SurfaceAttributesBuilder::<
|
||||||
|
glutin::surface::WindowSurface,
|
||||||
|
>::new()
|
||||||
|
.build(window.raw_window_handle(), width, height);
|
||||||
|
log::debug!(
|
||||||
|
"creating surface with attributes: {:?}",
|
||||||
|
&surface_attributes
|
||||||
|
);
|
||||||
|
// create surface
|
||||||
|
let gl_surface = unsafe {
|
||||||
|
self.gl_config
|
||||||
|
.display()
|
||||||
|
.create_window_surface(&self.gl_config, &surface_attributes)?
|
||||||
|
};
|
||||||
|
log::debug!("surface created successfully: {gl_surface:?}.making context current");
|
||||||
|
// make surface and context current.
|
||||||
|
let not_current_gl_context =
|
||||||
|
if let Some(not_current_context) = self.not_current_gl_context.take() {
|
||||||
|
not_current_context
|
||||||
|
} else {
|
||||||
|
self.current_gl_context
|
||||||
|
.take()
|
||||||
|
.unwrap()
|
||||||
|
.make_not_current()
|
||||||
|
.unwrap()
|
||||||
|
};
|
||||||
|
let current_gl_context = not_current_gl_context.make_current(&gl_surface)?;
|
||||||
|
// try setting swap interval. but its not absolutely necessary, so don't panic on failure.
|
||||||
|
log::debug!("made context current. setting swap interval for surface");
|
||||||
|
if let Err(e) =
|
||||||
|
gl_surface.set_swap_interval(¤t_gl_context, self.swap_interval)
|
||||||
|
{
|
||||||
|
log::error!("failed to set swap interval due to error: {e:?}");
|
||||||
|
}
|
||||||
|
// we will reach this point only once in most platforms except android.
|
||||||
|
// create window/surface/make context current once and just use them forever.
|
||||||
|
|
||||||
|
let native_pixels_per_point = window.scale_factor() as f32;
|
||||||
|
|
||||||
|
if win.egui_winit.is_none() {
|
||||||
|
let mut egui_winit = egui_winit::State::new(event_loop);
|
||||||
|
// egui_winit.set_max_texture_side(max_texture_side);
|
||||||
|
egui_winit.set_pixels_per_point(native_pixels_per_point);
|
||||||
|
win.egui_winit = Some(egui_winit);
|
||||||
|
}
|
||||||
|
|
||||||
|
win.gl_surface = Some(gl_surface);
|
||||||
|
self.current_gl_context = Some(current_gl_context);
|
||||||
|
self.window_maps.insert(window.id(), win.window_id);
|
||||||
|
}
|
||||||
|
win.window = Some(window);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// only applies for android. but we basically drop surface + window and make context not current
|
/// only applies for android. but we basically drop surface + window and make context not current
|
||||||
fn on_suspend(&mut self) -> Result<()> {
|
fn on_suspend(&mut self) -> Result<()> {
|
||||||
log::debug!("received suspend event. dropping window and surface");
|
log::debug!("received suspend event. dropping window and surface");
|
||||||
@@ -1006,8 +1028,19 @@ mod glow_integration {
|
|||||||
|
|
||||||
// Sync Rendering
|
// Sync Rendering
|
||||||
integration.egui_ctx.set_render_sync_callback(
|
integration.egui_ctx.set_render_sync_callback(
|
||||||
move |_viewport_builder, viewport_id, parent_viewport_id, render| {
|
move |viewport_builder, viewport_id, parent_viewport_id, render| {
|
||||||
// TODO: we should use `_viewport_builder` to create a new window in this frame!
|
let has_window = glutin.read().windows.get(&viewport_id).is_some();
|
||||||
|
if !has_window{
|
||||||
|
glutin.write().windows.entry(viewport_id).or_insert(Arc::new(RwLock::new(Window{ builder: viewport_builder, gl_surface: None, window: None, window_id: viewport_id, parent_id: parent_viewport_id, render: None, egui_winit: None })));
|
||||||
|
let win = glutin.read().windows.get(&viewport_id).cloned().unwrap();
|
||||||
|
let event_loop;
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
unsafe{
|
||||||
|
event_loop = WINIT_EVENT_LOOP.with(|event_loop|event_loop.read().as_ref().unwrap());
|
||||||
|
}
|
||||||
|
glutin.write().init_window(&win, event_loop).expect("Cannot init window on egui::Context::create_viewport_sync");
|
||||||
|
}
|
||||||
|
|
||||||
'try_render: {
|
'try_render: {
|
||||||
let window = glutin.read().windows.get(&viewport_id).cloned();
|
let window = glutin.read().windows.get(&viewport_id).cloned();
|
||||||
if let Some(window) = window {
|
if let Some(window) = window {
|
||||||
@@ -1787,7 +1820,7 @@ mod wgpu_integration {
|
|||||||
integration: Arc<RwLock<epi_integration::EpiIntegration>>,
|
integration: Arc<RwLock<epi_integration::EpiIntegration>>,
|
||||||
app: Box<dyn epi::App>,
|
app: Box<dyn epi::App>,
|
||||||
windows: Windows,
|
windows: Windows,
|
||||||
windows_id: HashMap<winit::window::WindowId, ViewportId>,
|
windows_id: Arc<RwLock<HashMap<winit::window::WindowId, ViewportId>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WgpuWinitApp {
|
struct WgpuWinitApp {
|
||||||
@@ -1848,19 +1881,41 @@ mod wgpu_integration {
|
|||||||
let Some(running) = &mut self.running else {return};
|
let Some(running) = &mut self.running else {return};
|
||||||
|
|
||||||
for (id, (window, state, _, _, builder)) in running.windows.write().iter_mut() {
|
for (id, (window, state, _, _, builder)) in running.windows.write().iter_mut() {
|
||||||
if window.is_none() {
|
if window.is_some() {
|
||||||
if let Ok(new_window) = create_winit_window_builder(builder).build(event_loop) {
|
continue;
|
||||||
running.windows_id.insert(new_window.id(), *id);
|
|
||||||
|
|
||||||
if let Err(err) = pollster::block_on(
|
|
||||||
running.painter.write().set_window(*id, Some(&new_window)),
|
|
||||||
) {
|
|
||||||
log::error!("on set_window: viewport_id {id} {err}");
|
|
||||||
}
|
|
||||||
*window = Some(Arc::new(RwLock::new(new_window)));
|
|
||||||
*state.write() = Some(egui_winit::State::new(event_loop));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Self::init_window(
|
||||||
|
*id,
|
||||||
|
builder,
|
||||||
|
&mut running.windows_id.write(),
|
||||||
|
&running.painter,
|
||||||
|
window,
|
||||||
|
state,
|
||||||
|
event_loop,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init_window(
|
||||||
|
id: ViewportId,
|
||||||
|
builder: &ViewportBuilder,
|
||||||
|
windows_id: &mut HashMap<winit::window::WindowId, ViewportId>,
|
||||||
|
painter: &Arc<RwLock<egui_wgpu::winit::Painter>>,
|
||||||
|
window: &mut Option<Arc<RwLock<winit::window::Window>>>,
|
||||||
|
state: &Arc<RwLock<Option<egui_winit::State>>>,
|
||||||
|
event_loop: &EventLoopWindowTarget<UserEvent>,
|
||||||
|
) {
|
||||||
|
if let Ok(new_window) = create_winit_window_builder(builder).build(event_loop) {
|
||||||
|
windows_id.insert(new_window.id(), id);
|
||||||
|
|
||||||
|
if let Err(err) =
|
||||||
|
pollster::block_on(painter.write().set_window(id, Some(&new_window)))
|
||||||
|
{
|
||||||
|
log::error!("on set_window: viewport_id {id} {err}");
|
||||||
|
}
|
||||||
|
*window = Some(Arc::new(RwLock::new(new_window)));
|
||||||
|
*state.write() = Some(egui_winit::State::new(event_loop));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1974,6 +2029,7 @@ mod wgpu_integration {
|
|||||||
|
|
||||||
let mut windows_id = HashMap::default();
|
let mut windows_id = HashMap::default();
|
||||||
windows_id.insert(window.id(), ViewportId::MAIN);
|
windows_id.insert(window.id(), ViewportId::MAIN);
|
||||||
|
let windows_id = Arc::new(RwLock::new(windows_id));
|
||||||
|
|
||||||
let windows = Windows(Arc::new(RwLock::new(HashMap::default())));
|
let windows = Windows(Arc::new(RwLock::new(HashMap::default())));
|
||||||
windows.write().insert(
|
windows.write().insert(
|
||||||
@@ -1993,10 +2049,22 @@ mod wgpu_integration {
|
|||||||
let time = integration.beginning;
|
let time = integration.beginning;
|
||||||
let painter = Arc::new(RwLock::new(painter));
|
let painter = Arc::new(RwLock::new(painter));
|
||||||
let _painter = painter.clone();
|
let _painter = painter.clone();
|
||||||
|
let _windows_id = windows_id.clone();
|
||||||
|
|
||||||
integration.egui_ctx.set_render_sync_callback(
|
integration.egui_ctx.set_render_sync_callback(
|
||||||
move |_viewport_builder, viewport_id, parent_viewport_id, render| {
|
move |viewport_builder, viewport_id, parent_viewport_id, render| {
|
||||||
// TODO: we should use `_viewport_builder` to create a new window in this frame!
|
if _windows.read().get(&viewport_id).is_none(){
|
||||||
|
let mut _windows = _windows.write();
|
||||||
|
let (window, state, _, _, _) = _windows.entry(viewport_id).or_insert((None, Arc::new(RwLock::new(None)), None, viewport_id, viewport_builder.clone()));
|
||||||
|
|
||||||
|
let event_loop;
|
||||||
|
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
unsafe{
|
||||||
|
event_loop = WINIT_EVENT_LOOP.with(|event_loop|event_loop.read().as_ref().unwrap());
|
||||||
|
}
|
||||||
|
Self::init_window(viewport_id, &viewport_builder, &mut _windows_id.write(), &_painter, window, state, event_loop);
|
||||||
|
}
|
||||||
'try_render: {
|
'try_render: {
|
||||||
let window = _windows.read().get(&viewport_id).cloned();
|
let window = _windows.read().get(&viewport_id).cloned();
|
||||||
if let Some(window) = window {
|
if let Some(window) = window {
|
||||||
@@ -2116,6 +2184,7 @@ mod wgpu_integration {
|
|||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|r| {
|
.and_then(|r| {
|
||||||
r.windows_id
|
r.windows_id
|
||||||
|
.read()
|
||||||
.get(&window_id)
|
.get(&window_id)
|
||||||
.and_then(|id| r.windows.read().get(id).map(|w| w.0.clone()))
|
.and_then(|id| r.windows.read().get(id).map(|w| w.0.clone()))
|
||||||
})
|
})
|
||||||
@@ -2173,7 +2242,7 @@ mod wgpu_integration {
|
|||||||
viewport_commands,
|
viewport_commands,
|
||||||
};
|
};
|
||||||
{
|
{
|
||||||
let Some((viewport_id, (Some(window), state, render, parent_viewport_id, _))) = windows_id.get(&window_id).and_then(|id|(windows.read().get(id).map(|w|(*id, w.clone())))) else{return vec![]};
|
let Some((viewport_id, (Some(window), state, render, parent_viewport_id, _))) = windows_id.read().get(&window_id).and_then(|id|(windows.read().get(id).map(|w|(*id, w.clone())))) else{return vec![]};
|
||||||
// This is used to not render a viewport if is sync
|
// This is used to not render a viewport if is sync
|
||||||
if viewport_id != ViewportId::MAIN && render.is_none() {
|
if viewport_id != ViewportId::MAIN && render.is_none() {
|
||||||
if let Some(window) = running.windows.read().get(&parent_viewport_id) {
|
if let Some(window) = running.windows.read().get(&parent_viewport_id) {
|
||||||
@@ -2265,7 +2334,9 @@ mod wgpu_integration {
|
|||||||
windows
|
windows
|
||||||
.write()
|
.write()
|
||||||
.retain(|id, _| active_viewports_ids.contains(id));
|
.retain(|id, _| active_viewports_ids.contains(id));
|
||||||
windows_id.retain(|_, id| active_viewports_ids.contains(id));
|
windows_id
|
||||||
|
.write()
|
||||||
|
.retain(|_, id| active_viewports_ids.contains(id));
|
||||||
painter.write().clean_surfaces(&active_viewports_ids);
|
painter.write().clean_surfaces(&active_viewports_ids);
|
||||||
|
|
||||||
let mut control_flow = vec![EventResult::Wait];
|
let mut control_flow = vec![EventResult::Wait];
|
||||||
@@ -2300,7 +2371,7 @@ mod wgpu_integration {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some((_, (Some(window), _, _, _, _))) = windows_id.get(&window_id).and_then(|id|(windows.read().get(id).map(|w|(*id, w.clone())))) else{return vec![]};
|
let Some((_, (Some(window), _, _, _, _))) = windows_id.read().get(&window_id).and_then(|id|(windows.read().get(id).map(|w|(*id, w.clone())))) else{return vec![]};
|
||||||
integration
|
integration
|
||||||
.write()
|
.write()
|
||||||
.maybe_autosave(app.as_mut(), window.clone());
|
.maybe_autosave(app.as_mut(), window.clone());
|
||||||
@@ -2402,7 +2473,7 @@ mod wgpu_integration {
|
|||||||
// See: https://github.com/rust-windowing/winit/issues/208
|
// See: https://github.com/rust-windowing/winit/issues/208
|
||||||
// This solves an issue where the app would panic when minimizing on Windows.
|
// This solves an issue where the app would panic when minimizing on Windows.
|
||||||
if let Some(viewport_id) =
|
if let Some(viewport_id) =
|
||||||
running.windows_id.get(window_id).copied()
|
running.windows_id.read().get(window_id).copied()
|
||||||
{
|
{
|
||||||
if physical_size.width > 0 && physical_size.height > 0 {
|
if physical_size.width > 0 && physical_size.height > 0 {
|
||||||
running.painter.write().on_window_resized(
|
running.painter.write().on_window_resized(
|
||||||
@@ -2418,7 +2489,7 @@ mod wgpu_integration {
|
|||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if let Some(viewport_id) =
|
if let Some(viewport_id) =
|
||||||
running.windows_id.get(window_id).copied()
|
running.windows_id.read().get(window_id).copied()
|
||||||
{
|
{
|
||||||
repaint_asap = true;
|
repaint_asap = true;
|
||||||
running.painter.write().on_window_resized(
|
running.painter.write().on_window_resized(
|
||||||
@@ -2437,11 +2508,10 @@ mod wgpu_integration {
|
|||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
let event_response = if let Some((id, (_, state, _, _, _))) = running
|
let event_response = if let Some((id, (_, state, _, _, _))) =
|
||||||
.windows_id
|
running.windows_id.read().get(window_id).and_then(|id| {
|
||||||
.get(window_id)
|
running.windows.read().get(id).map(|w| (*id, w.clone()))
|
||||||
.and_then(|id| running.windows.read().get(id).map(|w| (*id, w.clone())))
|
}) {
|
||||||
{
|
|
||||||
if let Some(state) = &mut *state.write() {
|
if let Some(state) = &mut *state.write() {
|
||||||
Some(running.integration.write().on_event(
|
Some(running.integration.write().on_event(
|
||||||
running.app.as_mut(),
|
running.app.as_mut(),
|
||||||
@@ -2482,6 +2552,7 @@ mod wgpu_integration {
|
|||||||
if let Some(running) = &mut self.running {
|
if let Some(running) = &mut self.running {
|
||||||
if let Some((_, state, _, _, _)) = running
|
if let Some((_, state, _, _, _)) = running
|
||||||
.windows_id
|
.windows_id
|
||||||
|
.read()
|
||||||
.get(window_id)
|
.get(window_id)
|
||||||
.and_then(|id| running.windows.read().get(id).cloned())
|
.and_then(|id| running.windows.read().get(id).cloned())
|
||||||
{
|
{
|
||||||
@@ -2503,7 +2574,7 @@ mod wgpu_integration {
|
|||||||
fn get_window_id(&self, id: &winit::window::WindowId) -> Option<ViewportId> {
|
fn get_window_id(&self, id: &winit::window::WindowId) -> Option<ViewportId> {
|
||||||
self.running
|
self.running
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|r| r.windows_id.get(id).copied())
|
.and_then(|r| r.windows_id.read().get(id).copied())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -396,7 +396,7 @@ impl<'open> Window<'open> {
|
|||||||
.with_max_inner_size(Some((max_size.x as u32, max_size.y as u32)));
|
.with_max_inner_size(Some((max_size.x as u32, max_size.y as u32)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx.create_viewport_sync(window_builder, move |ctx| {
|
return Some(ctx.create_viewport_sync(window_builder, move |ctx| {
|
||||||
let mut op = is_open;
|
let mut op = is_open;
|
||||||
let open = if show_close_button {
|
let open = if show_close_button {
|
||||||
Some(&mut op)
|
Some(&mut op)
|
||||||
@@ -625,7 +625,7 @@ impl<'open> Window<'open> {
|
|||||||
inner: content_inner,
|
inner: content_inner,
|
||||||
response: full_response,
|
response: full_response,
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let frame = frame.unwrap_or_else(|| Frame::window(&ctx.style()));
|
let frame = frame.unwrap_or_else(|| Frame::window(&ctx.style()));
|
||||||
|
|||||||
@@ -2318,7 +2318,7 @@ impl Context {
|
|||||||
&self,
|
&self,
|
||||||
viewport_builder: ViewportBuilder,
|
viewport_builder: ViewportBuilder,
|
||||||
func: impl FnOnce(&Context) -> T,
|
func: impl FnOnce(&Context) -> T,
|
||||||
) -> Option<T> {
|
) -> T {
|
||||||
if !self.force_embedding() {
|
if !self.force_embedding() {
|
||||||
let mut viewport_id = ViewportId::MAIN;
|
let mut viewport_id = ViewportId::MAIN;
|
||||||
let mut parent_viewport_id = ViewportId::MAIN;
|
let mut parent_viewport_id = ViewportId::MAIN;
|
||||||
@@ -2355,9 +2355,9 @@ impl Context {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
out
|
out.expect("egui backend is implemented incorrectly! Context::set_render_sync_callback")
|
||||||
} else {
|
} else {
|
||||||
Some(func(self))
|
func(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user