mirror of
https://github.com/emilk/egui.git
synced 2026-09-02 06:40:06 -04:00
create_viewport_sync prep Glutin
WGPU Unimplemented again, use Arc<RwLock<T>> for a lot of things
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
//! Note that this file contains two similar paths - one for [`glow`], one for [`wgpu`].
|
//! Note that this file contains two similar paths - one for [`glow`], one for [`wgpu`].
|
||||||
//! When making changes to one you often also want to apply it to the other.
|
//! When making changes to one you often also want to apply it to the other.
|
||||||
|
|
||||||
use std::time::Instant;
|
use std::{sync::Arc, time::Instant};
|
||||||
|
|
||||||
use egui::{epaint::ahash::HashMap, window::ViewportBuilder};
|
use egui::{epaint::ahash::HashMap, mutex::RwLock, window::ViewportBuilder};
|
||||||
use raw_window_handle::{HasRawDisplayHandle as _, HasRawWindowHandle as _};
|
use raw_window_handle::{HasRawDisplayHandle as _, HasRawWindowHandle as _};
|
||||||
use winit::{
|
use winit::{
|
||||||
event_loop::{ControlFlow, EventLoop, EventLoopBuilder, EventLoopProxy, EventLoopWindowTarget},
|
event_loop::{ControlFlow, EventLoop, EventLoopBuilder, EventLoopProxy, EventLoopWindowTarget},
|
||||||
@@ -72,9 +72,12 @@ trait WinitApp {
|
|||||||
|
|
||||||
fn is_focused(&self, window_id: winit::window::WindowId) -> bool;
|
fn is_focused(&self, window_id: winit::window::WindowId) -> bool;
|
||||||
|
|
||||||
fn integration(&self) -> Option<&EpiIntegration>;
|
fn integration(&self) -> Option<Arc<RwLock<EpiIntegration>>>;
|
||||||
|
|
||||||
fn window(&self, window_id: winit::window::WindowId) -> Option<&winit::window::Window>;
|
fn window(
|
||||||
|
&self,
|
||||||
|
window_id: winit::window::WindowId,
|
||||||
|
) -> Option<Arc<RwLock<winit::window::Window>>>;
|
||||||
|
|
||||||
fn get_window_winit_id(&self, id: u64) -> Option<winit::window::WindowId>;
|
fn get_window_winit_id(&self, id: u64) -> Option<winit::window::WindowId>;
|
||||||
fn get_window_id(&self, id: &winit::window::WindowId) -> Option<u64>;
|
fn get_window_id(&self, id: &winit::window::WindowId) -> Option<u64>;
|
||||||
@@ -248,7 +251,7 @@ fn run_and_return(
|
|||||||
for (window_id, repaint_time) in windows_next_repaint_times.clone().iter() {
|
for (window_id, repaint_time) in windows_next_repaint_times.clone().iter() {
|
||||||
if *repaint_time <= Instant::now() {
|
if *repaint_time <= Instant::now() {
|
||||||
if let Some(window) = winit_app.window(*window_id) {
|
if let Some(window) = winit_app.window(*window_id) {
|
||||||
window.request_redraw();
|
window.read().request_redraw();
|
||||||
windows_next_repaint_times.remove(window_id);
|
windows_next_repaint_times.remove(window_id);
|
||||||
control_flow.set_poll();
|
control_flow.set_poll();
|
||||||
} else {
|
} else {
|
||||||
@@ -387,7 +390,7 @@ fn run_and_exit(event_loop: EventLoop<UserEvent>, mut winit_app: impl WinitApp +
|
|||||||
if *repaint_time <= Instant::now() {
|
if *repaint_time <= Instant::now() {
|
||||||
if let Some(window) = winit_app.window(*window_id) {
|
if let Some(window) = winit_app.window(*window_id) {
|
||||||
log::trace!("request_redraw");
|
log::trace!("request_redraw");
|
||||||
window.request_redraw();
|
window.read().request_redraw();
|
||||||
windows_next_repaint_times.remove(window_id);
|
windows_next_repaint_times.remove(window_id);
|
||||||
}
|
}
|
||||||
control_flow.set_poll();
|
control_flow.set_poll();
|
||||||
@@ -416,7 +419,9 @@ fn run_and_exit(event_loop: EventLoop<UserEvent>, mut winit_app: impl WinitApp +
|
|||||||
mod glow_integration {
|
mod glow_integration {
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use egui::{epaint::ahash::HashMap, window::ViewportBuilder, NumExt as _, ViewportRender};
|
use egui::{
|
||||||
|
epaint::ahash::HashMap, mutex::RwLock, window::ViewportBuilder, NumExt as _, ViewportRender,
|
||||||
|
};
|
||||||
use egui_winit::EventResponse;
|
use egui_winit::EventResponse;
|
||||||
use glutin::{
|
use glutin::{
|
||||||
display::GetGlDisplay,
|
display::GetGlDisplay,
|
||||||
@@ -446,17 +451,17 @@ mod glow_integration {
|
|||||||
struct GlowWinitRunning {
|
struct GlowWinitRunning {
|
||||||
gl: Arc<glow::Context>,
|
gl: Arc<glow::Context>,
|
||||||
painter: egui_glow::Painter,
|
painter: egui_glow::Painter,
|
||||||
integration: epi_integration::EpiIntegration,
|
integration: Arc<RwLock<epi_integration::EpiIntegration>>,
|
||||||
app: Box<dyn epi::App>,
|
app: Box<dyn epi::App>,
|
||||||
// Conceptually this will be split out eventually so that the rest of the state
|
// Conceptually this will be split out eventually so that the rest of the state
|
||||||
// can be persistent.
|
// can be persistent.
|
||||||
gl_window: GlutinWindowContext,
|
glutin_ctx: Arc<RwLock<GlutinWindowContext>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Window {
|
struct Window {
|
||||||
builder: ViewportBuilder,
|
builder: ViewportBuilder,
|
||||||
gl_surface: Option<glutin::surface::Surface<glutin::surface::WindowSurface>>,
|
gl_surface: Option<glutin::surface::Surface<glutin::surface::WindowSurface>>,
|
||||||
window: Option<winit::window::Window>,
|
window: Option<Arc<RwLock<winit::window::Window>>>,
|
||||||
window_id: u64,
|
window_id: u64,
|
||||||
parent_id: u64,
|
parent_id: u64,
|
||||||
render: Option<Arc<Box<ViewportRender>>>,
|
render: Option<Arc<Box<ViewportRender>>>,
|
||||||
@@ -478,9 +483,11 @@ mod glow_integration {
|
|||||||
struct GlutinWindowContext {
|
struct GlutinWindowContext {
|
||||||
swap_interval: glutin::surface::SwapInterval,
|
swap_interval: glutin::surface::SwapInterval,
|
||||||
gl_config: glutin::config::Config,
|
gl_config: glutin::config::Config,
|
||||||
|
|
||||||
current_gl_context: Option<glutin::context::PossiblyCurrentContext>,
|
current_gl_context: Option<glutin::context::PossiblyCurrentContext>,
|
||||||
not_current_gl_context: Option<glutin::context::NotCurrentContext>,
|
not_current_gl_context: Option<glutin::context::NotCurrentContext>,
|
||||||
windows: Vec<Window>,
|
|
||||||
|
windows: HashMap<u64, Arc<RwLock<Window>>>,
|
||||||
window_maps: HashMap<winit::window::WindowId, u64>,
|
window_maps: HashMap<winit::window::WindowId, u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -592,6 +599,20 @@ mod glow_integration {
|
|||||||
window_maps.insert(window.id(), 0);
|
window_maps.insert(window.id(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut windows = HashMap::default();
|
||||||
|
windows.insert(
|
||||||
|
0,
|
||||||
|
Arc::new(RwLock::new(Window {
|
||||||
|
builder: window_builder,
|
||||||
|
gl_surface: None,
|
||||||
|
window: window.map(|w| Arc::new(RwLock::new(w))),
|
||||||
|
window_id: 0,
|
||||||
|
egui_winit: None,
|
||||||
|
render: None,
|
||||||
|
parent_id: 0,
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
|
||||||
// the fun part with opengl gl is that we never know whether there is an error. the context creation might have failed, but
|
// the fun part with opengl gl is that we never know whether there is an error. the context creation might have failed, but
|
||||||
// it could keep working until we try to make surface current or swap buffers or something else. future glutin improvements might
|
// it could keep working until we try to make surface current or swap buffers or something else. future glutin improvements might
|
||||||
// help us start from scratch again if we fail context creation and go back to preferEgl or try with different config etc..
|
// help us start from scratch again if we fail context creation and go back to preferEgl or try with different config etc..
|
||||||
@@ -601,15 +622,7 @@ mod glow_integration {
|
|||||||
gl_config,
|
gl_config,
|
||||||
current_gl_context: None,
|
current_gl_context: None,
|
||||||
not_current_gl_context,
|
not_current_gl_context,
|
||||||
windows: vec![Window {
|
windows,
|
||||||
builder: window_builder,
|
|
||||||
gl_surface: None,
|
|
||||||
window,
|
|
||||||
window_id: 0,
|
|
||||||
egui_winit: None,
|
|
||||||
render: None,
|
|
||||||
parent_id: 0,
|
|
||||||
}],
|
|
||||||
window_maps,
|
window_maps,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -624,7 +637,8 @@ mod glow_integration {
|
|||||||
/// we presently assume that we will
|
/// we presently assume that we will
|
||||||
#[allow(unsafe_code)]
|
#[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.iter_mut() {
|
for (_, win) in self.windows.iter_mut() {
|
||||||
|
let mut win = win.write();
|
||||||
if win.gl_surface.is_some() {
|
if win.gl_surface.is_some() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -632,13 +646,17 @@ mod glow_integration {
|
|||||||
// make sure we have a window or create one.
|
// make sure we have a window or create one.
|
||||||
let window = win.window.take().unwrap_or_else(|| {
|
let window = win.window.take().unwrap_or_else(|| {
|
||||||
log::debug!("window doesn't exist yet. creating one now with finalize_window");
|
log::debug!("window doesn't exist yet. creating one now with finalize_window");
|
||||||
|
Arc::new(RwLock::new(
|
||||||
glutin_winit::finalize_window(
|
glutin_winit::finalize_window(
|
||||||
event_loop,
|
event_loop,
|
||||||
create_winit_window_builder(&win.builder),
|
create_winit_window_builder(&win.builder),
|
||||||
&self.gl_config,
|
&self.gl_config,
|
||||||
)
|
)
|
||||||
.expect("failed to finalize glutin window")
|
.expect("failed to finalize glutin window"),
|
||||||
|
))
|
||||||
});
|
});
|
||||||
|
{
|
||||||
|
let window = window.read();
|
||||||
// surface attributes
|
// surface attributes
|
||||||
let (width, height): (u32, u32) = window.inner_size().into();
|
let (width, height): (u32, u32) = window.inner_size().into();
|
||||||
let width = std::num::NonZeroU32::new(width.at_least(1)).unwrap();
|
let width = std::num::NonZeroU32::new(width.at_least(1)).unwrap();
|
||||||
@@ -657,7 +675,9 @@ mod glow_integration {
|
|||||||
.display()
|
.display()
|
||||||
.create_window_surface(&self.gl_config, &surface_attributes)?
|
.create_window_surface(&self.gl_config, &surface_attributes)?
|
||||||
};
|
};
|
||||||
log::debug!("surface created successfully: {gl_surface:?}.making context current");
|
log::debug!(
|
||||||
|
"surface created successfully: {gl_surface:?}.making context current"
|
||||||
|
);
|
||||||
// make surface and context current.
|
// make surface and context current.
|
||||||
let not_current_gl_context =
|
let not_current_gl_context =
|
||||||
if let Some(not_current_context) = self.not_current_gl_context.take() {
|
if let Some(not_current_context) = self.not_current_gl_context.take() {
|
||||||
@@ -693,6 +713,7 @@ mod glow_integration {
|
|||||||
self.current_gl_context = Some(current_gl_context);
|
self.current_gl_context = Some(current_gl_context);
|
||||||
self.window_maps.insert(window.id(), win.window_id);
|
self.window_maps.insert(window.id(), win.window_id);
|
||||||
window.request_redraw();
|
window.request_redraw();
|
||||||
|
}
|
||||||
win.window = Some(window);
|
win.window = Some(window);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -701,7 +722,8 @@ mod glow_integration {
|
|||||||
/// 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");
|
||||||
for window in self.windows.iter_mut() {
|
for (_, window) in self.windows.iter_mut() {
|
||||||
|
let mut window = window.write();
|
||||||
window.gl_surface.take();
|
window.gl_surface.take();
|
||||||
window.window.take();
|
window.window.take();
|
||||||
}
|
}
|
||||||
@@ -714,18 +736,19 @@ mod glow_integration {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn window(&self, index: usize) -> &winit::window::Window {
|
fn window(&self, window_id: u64) -> Arc<RwLock<Window>> {
|
||||||
self.windows[index]
|
self.windows
|
||||||
.window
|
.get(&window_id)
|
||||||
.as_ref()
|
.map(|w| w.clone())
|
||||||
.expect("winit window doesn't exist")
|
.expect("winit window doesn't exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resize(&mut self, window_id: u64, physical_size: winit::dpi::PhysicalSize<u32>) {
|
fn resize(&mut self, window_id: u64, physical_size: winit::dpi::PhysicalSize<u32>) {
|
||||||
let width = std::num::NonZeroU32::new(physical_size.width.at_least(1)).unwrap();
|
let width = std::num::NonZeroU32::new(physical_size.width.at_least(1)).unwrap();
|
||||||
let height = std::num::NonZeroU32::new(physical_size.height.at_least(1)).unwrap();
|
let height = std::num::NonZeroU32::new(physical_size.height.at_least(1)).unwrap();
|
||||||
for window in self.windows.iter_mut() {
|
|
||||||
if window.window_id == window_id {
|
if let Some(window) = self.windows.get(&window_id) {
|
||||||
|
let mut window = window.write();
|
||||||
if let Some(gl_surface) = &window.gl_surface {
|
if let Some(gl_surface) = &window.gl_surface {
|
||||||
self.current_gl_context = Some(
|
self.current_gl_context = Some(
|
||||||
self.current_gl_context
|
self.current_gl_context
|
||||||
@@ -746,7 +769,6 @@ mod glow_integration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn get_proc_address(&self, addr: &std::ffi::CStr) -> *const std::ffi::c_void {
|
fn get_proc_address(&self, addr: &std::ffi::CStr) -> *const std::ffi::c_void {
|
||||||
self.gl_config.display().get_proc_address(addr)
|
self.gl_config.display().get_proc_address(addr)
|
||||||
@@ -757,13 +779,13 @@ mod glow_integration {
|
|||||||
repaint_proxy: Arc<egui::mutex::Mutex<EventLoopProxy<UserEvent>>>,
|
repaint_proxy: Arc<egui::mutex::Mutex<EventLoopProxy<UserEvent>>>,
|
||||||
app_name: String,
|
app_name: String,
|
||||||
native_options: epi::NativeOptions,
|
native_options: epi::NativeOptions,
|
||||||
running: Option<GlowWinitRunning>,
|
running: Arc<RwLock<Option<GlowWinitRunning>>>,
|
||||||
|
|
||||||
// Note that since this `AppCreator` is FnOnce we are currently unable to support
|
// Note that since this `AppCreator` is FnOnce we are currently unable to support
|
||||||
// re-initializing the `GlowWinitRunning` state on Android if the application
|
// re-initializing the `GlowWinitRunning` state on Android if the application
|
||||||
// suspends and resumes.
|
// suspends and resumes.
|
||||||
app_creator: Option<epi::AppCreator>,
|
app_creator: Option<epi::AppCreator>,
|
||||||
is_focused: Option<u64>,
|
is_focused: Arc<RwLock<Option<u64>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GlowWinitApp {
|
impl GlowWinitApp {
|
||||||
@@ -777,9 +799,9 @@ mod glow_integration {
|
|||||||
repaint_proxy: Arc::new(egui::mutex::Mutex::new(event_loop.create_proxy())),
|
repaint_proxy: Arc::new(egui::mutex::Mutex::new(event_loop.create_proxy())),
|
||||||
app_name: app_name.to_owned(),
|
app_name: app_name.to_owned(),
|
||||||
native_options,
|
native_options,
|
||||||
running: None,
|
running: Arc::new(RwLock::new(None)),
|
||||||
app_creator: Some(app_creator),
|
app_creator: Some(app_creator),
|
||||||
is_focused: Some(0),
|
is_focused: Arc::new(RwLock::new(Some(0))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -801,8 +823,11 @@ mod glow_integration {
|
|||||||
};
|
};
|
||||||
glutin_window_context.on_resume(event_loop)?;
|
glutin_window_context.on_resume(event_loop)?;
|
||||||
|
|
||||||
if let Some(window) = &glutin_window_context.windows[0].window {
|
if let Some(window) = &glutin_window_context.windows.get(&0) {
|
||||||
epi_integration::apply_native_options_to_window(window, native_options);
|
let window = window.read();
|
||||||
|
if let Some(window) = &window.window {
|
||||||
|
epi_integration::apply_native_options_to_window(&window.read(), native_options);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let gl = unsafe {
|
let gl = unsafe {
|
||||||
@@ -837,11 +862,14 @@ mod glow_integration {
|
|||||||
egui_glow::Painter::new(gl.clone(), "", self.native_options.shader_version)
|
egui_glow::Painter::new(gl.clone(), "", self.native_options.shader_version)
|
||||||
.unwrap_or_else(|error| panic!("some OpenGL error occurred {}\n", error));
|
.unwrap_or_else(|error| panic!("some OpenGL error occurred {}\n", error));
|
||||||
|
|
||||||
let system_theme = system_theme(gl_window.window(0), &self.native_options);
|
let system_theme = system_theme(
|
||||||
|
&gl_window.window(0).read().window.as_ref().unwrap().read(),
|
||||||
|
&self.native_options,
|
||||||
|
);
|
||||||
let mut integration = epi_integration::EpiIntegration::new(
|
let mut integration = epi_integration::EpiIntegration::new(
|
||||||
event_loop,
|
event_loop,
|
||||||
painter.max_texture_side(),
|
painter.max_texture_side(),
|
||||||
gl_window.window(0),
|
&gl_window.window(0).read().window.as_ref().unwrap().read(),
|
||||||
system_theme,
|
system_theme,
|
||||||
&self.app_name,
|
&self.app_name,
|
||||||
&self.native_options,
|
&self.native_options,
|
||||||
@@ -852,10 +880,11 @@ mod glow_integration {
|
|||||||
);
|
);
|
||||||
#[cfg(feature = "accesskit")]
|
#[cfg(feature = "accesskit")]
|
||||||
{
|
{
|
||||||
let window = &mut gl_window.windows[0];
|
let window = gl_window.windows.get(&0).unwrap();
|
||||||
|
let window = &mut *window.write();
|
||||||
integration.init_accesskit(
|
integration.init_accesskit(
|
||||||
window.egui_winit.as_mut().unwrap(),
|
window.egui_winit.as_mut().unwrap(),
|
||||||
window.window.as_ref().unwrap(),
|
&window.window.as_ref().unwrap().read(),
|
||||||
self.repaint_proxy.lock().clone(),
|
self.repaint_proxy.lock().clone(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -868,9 +897,24 @@ mod glow_integration {
|
|||||||
|
|
||||||
integration.egui_ctx.set_desktop(true);
|
integration.egui_ctx.set_desktop(true);
|
||||||
|
|
||||||
gl_window.window(0).set_ime_allowed(true);
|
gl_window
|
||||||
|
.window(0)
|
||||||
|
.read()
|
||||||
|
.window
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.read()
|
||||||
|
.set_ime_allowed(true);
|
||||||
if self.native_options.mouse_passthrough {
|
if self.native_options.mouse_passthrough {
|
||||||
gl_window.window(0).set_cursor_hittest(false).unwrap();
|
gl_window
|
||||||
|
.window(0)
|
||||||
|
.read()
|
||||||
|
.window
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.read()
|
||||||
|
.set_cursor_hittest(false)
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -894,31 +938,35 @@ mod glow_integration {
|
|||||||
|
|
||||||
let app_creator = std::mem::take(&mut self.app_creator)
|
let app_creator = std::mem::take(&mut self.app_creator)
|
||||||
.expect("Single-use AppCreator has unexpectedly already been taken");
|
.expect("Single-use AppCreator has unexpectedly already been taken");
|
||||||
let mut app = app_creator(&epi::CreationContext {
|
let mut app;
|
||||||
|
{
|
||||||
|
let window = gl_window.window(0);
|
||||||
|
let window = &mut *window.write();
|
||||||
|
app = app_creator(&epi::CreationContext {
|
||||||
egui_ctx: integration.egui_ctx.clone(),
|
egui_ctx: integration.egui_ctx.clone(),
|
||||||
integration_info: integration.frame.info(),
|
integration_info: integration.frame.info(),
|
||||||
storage: integration.frame.storage(),
|
storage: integration.frame.storage(),
|
||||||
gl: Some(gl.clone()),
|
gl: Some(gl.clone()),
|
||||||
#[cfg(feature = "wgpu")]
|
#[cfg(feature = "wgpu")]
|
||||||
wgpu_render_state: None,
|
wgpu_render_state: None,
|
||||||
raw_display_handle: gl_window.window(0).raw_display_handle(),
|
raw_display_handle: window.window.as_ref().unwrap().read().raw_display_handle(),
|
||||||
raw_window_handle: gl_window.window(0).raw_window_handle(),
|
raw_window_handle: window.window.as_ref().unwrap().read().raw_window_handle(),
|
||||||
});
|
});
|
||||||
|
|
||||||
if app.warm_up_enabled() {
|
if app.warm_up_enabled() {
|
||||||
let window = &mut gl_window.windows[0];
|
|
||||||
integration.warm_up(
|
integration.warm_up(
|
||||||
app.as_mut(),
|
app.as_mut(),
|
||||||
window.window.as_ref().unwrap(),
|
&window.window.as_ref().unwrap().read(),
|
||||||
window.egui_winit.as_mut().unwrap(),
|
window.egui_winit.as_mut().unwrap(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.running = Some(GlowWinitRunning {
|
*self.running.write() = Some(GlowWinitRunning {
|
||||||
gl_window,
|
glutin_ctx: Arc::new(RwLock::new(gl_window)),
|
||||||
gl,
|
gl,
|
||||||
painter,
|
painter,
|
||||||
integration,
|
integration: Arc::new(RwLock::new(integration)),
|
||||||
app,
|
app,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -929,31 +977,36 @@ mod glow_integration {
|
|||||||
impl WinitApp for GlowWinitApp {
|
impl WinitApp for GlowWinitApp {
|
||||||
fn frame_nr(&self) -> u64 {
|
fn frame_nr(&self) -> u64 {
|
||||||
self.running
|
self.running
|
||||||
|
.read()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map_or(0, |r| r.integration.egui_ctx.frame_nr())
|
.map_or(0, |r| r.integration.read().egui_ctx.frame_nr())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_focused(&self, window_id: winit::window::WindowId) -> bool {
|
fn is_focused(&self, window_id: winit::window::WindowId) -> bool {
|
||||||
if let Some(is_focused) = self.is_focused {
|
if let Some(is_focused) = self.is_focused.read().as_ref() {
|
||||||
if let Some(running) = &self.running {
|
if let Some(running) = self.running.read().as_ref() {
|
||||||
if let Some(window_id) = running.gl_window.window_maps.get(&window_id) {
|
if let Some(window_id) = running.glutin_ctx.read().window_maps.get(&window_id) {
|
||||||
return is_focused == *window_id;
|
return *is_focused == *window_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn integration(&self) -> Option<&EpiIntegration> {
|
fn integration(&self) -> Option<Arc<RwLock<EpiIntegration>>> {
|
||||||
self.running.as_ref().map(|r| &r.integration)
|
self.running.read().as_ref().map(|r| r.integration.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn window(&self, window_id: winit::window::WindowId) -> Option<&winit::window::Window> {
|
fn window(
|
||||||
self.running.as_ref().and_then(|r| {
|
&self,
|
||||||
for window in r.gl_window.windows.iter() {
|
window_id: winit::window::WindowId,
|
||||||
if let Some(window) = &window.window {
|
) -> Option<Arc<RwLock<winit::window::Window>>> {
|
||||||
if window.id() == window_id {
|
self.running.read().as_ref().and_then(|r| {
|
||||||
return Some(window);
|
let glutin_ctx = r.glutin_ctx.read();
|
||||||
|
if let Some(viewport_id) = glutin_ctx.window_maps.get(&window_id) {
|
||||||
|
if let Some(viewport) = glutin_ctx.windows.get(viewport_id) {
|
||||||
|
if let Some(window) = viewport.read().window.as_ref() {
|
||||||
|
return Some(window.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -962,68 +1015,63 @@ mod glow_integration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_window_winit_id(&self, id: u64) -> Option<winit::window::WindowId> {
|
fn get_window_winit_id(&self, id: u64) -> Option<winit::window::WindowId> {
|
||||||
self.running.as_ref().and_then(|r| {
|
self.running.read().as_ref().and_then(|r| {
|
||||||
for window in r.gl_window.windows.iter() {
|
if let Some(window) = r.glutin_ctx.read().windows.get(&id) {
|
||||||
if window.window_id == id {
|
return window.read().window.as_ref().map(|w| w.read().id());
|
||||||
return window.window.as_ref().map(|w| w.id());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_window_id(&self, id: &winit::window::WindowId) -> Option<u64> {
|
fn get_window_id(&self, id: &winit::window::WindowId) -> Option<u64> {
|
||||||
self.running.as_ref().and_then(|r| {
|
self.running
|
||||||
for window in r.gl_window.windows.iter() {
|
.read()
|
||||||
if let Some(win) = &window.window {
|
.as_ref()
|
||||||
if win.id() == *id {
|
.and_then(|r| r.glutin_ctx.read().window_maps.get(id).cloned())
|
||||||
return Some(window.window_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn save_and_destroy(&mut self) {
|
fn save_and_destroy(&mut self) {
|
||||||
if let Some(mut running) = self.running.take() {
|
if let Some(mut running) = self.running.write().take() {
|
||||||
running
|
running.integration.write().save(
|
||||||
.integration
|
running.app.as_mut(),
|
||||||
.save(running.app.as_mut(), running.gl_window.window(0));
|
&running
|
||||||
|
.glutin_ctx
|
||||||
|
.read()
|
||||||
|
.window(0)
|
||||||
|
.read()
|
||||||
|
.window
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.read(),
|
||||||
|
);
|
||||||
running.app.on_exit(Some(&running.gl));
|
running.app.on_exit(Some(&running.gl));
|
||||||
running.painter.destroy();
|
running.painter.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_ui_and_paint(&mut self, window_id: winit::window::WindowId) -> Vec<EventResult> {
|
fn run_ui_and_paint(&mut self, window_id: winit::window::WindowId) -> Vec<EventResult> {
|
||||||
if let Some(running) = &mut self.running {
|
if self.running.read().is_none() {
|
||||||
let mut windows_indexes = vec![];
|
return vec![EventResult::Wait];
|
||||||
for (i, window) in running.gl_window.windows.iter().enumerate() {
|
|
||||||
if let Some(window) = &window.window {
|
|
||||||
if window.id() == window_id {
|
|
||||||
windows_indexes.push(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut inner = |window_index| {
|
if let Some(viewport_id) = self.get_window_id(&window_id) {
|
||||||
#[cfg(feature = "puffin")]
|
#[cfg(feature = "puffin")]
|
||||||
puffin::GlobalProfiler::lock().new_frame();
|
puffin::GlobalProfiler::lock().new_frame();
|
||||||
crate::profile_scope!("frame");
|
crate::profile_scope!("frame");
|
||||||
|
|
||||||
|
let mut running = self.running.write();
|
||||||
let GlowWinitRunning {
|
let GlowWinitRunning {
|
||||||
gl_window,
|
glutin_ctx: gl_window,
|
||||||
gl,
|
gl,
|
||||||
app,
|
app,
|
||||||
integration,
|
integration,
|
||||||
painter,
|
painter,
|
||||||
} = running;
|
} = running.as_mut().unwrap();
|
||||||
|
|
||||||
let mut window_map = HashMap::default();
|
let mut window_map = HashMap::default();
|
||||||
for window in gl_window.windows.iter() {
|
for (id, window) in gl_window.read().windows.iter() {
|
||||||
if let Some(win) = &window.window {
|
if let Some(win) = &window.read().window {
|
||||||
window_map.insert(window.window_id, win.id());
|
window_map.insert(*id, win.read().id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1039,8 +1087,10 @@ mod glow_integration {
|
|||||||
let control_flow;
|
let control_flow;
|
||||||
{
|
{
|
||||||
// let window = gl_window.window(window_index);
|
// let window = gl_window.window(window_index);
|
||||||
let win: Option<&mut Window> = gl_window.windows.get_mut(window_index);
|
let win = gl_window.read().windows.get(&viewport_id).cloned();
|
||||||
let win = win.unwrap();
|
let win = win.unwrap();
|
||||||
|
{
|
||||||
|
let mut gl_window = gl_window.write();
|
||||||
gl_window.current_gl_context = Some(
|
gl_window.current_gl_context = Some(
|
||||||
gl_window
|
gl_window
|
||||||
.current_gl_context
|
.current_gl_context
|
||||||
@@ -1048,20 +1098,34 @@ mod glow_integration {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.make_not_current()
|
.make_not_current()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.make_current(win.gl_surface.as_ref().unwrap())
|
.make_current(win.read().gl_surface.as_ref().unwrap())
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
let screen_size_in_pixels: [u32; 2] =
|
let screen_size_in_pixels: [u32; 2] = win
|
||||||
win.window.as_ref().unwrap().inner_size().into();
|
.read()
|
||||||
|
.window
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.read()
|
||||||
|
.inner_size()
|
||||||
|
.into();
|
||||||
|
|
||||||
win.window.as_mut().unwrap().set_transparent(true);
|
win.write()
|
||||||
|
.window
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.read()
|
||||||
|
.set_transparent(true);
|
||||||
egui_glow::painter::clear(
|
egui_glow::painter::clear(
|
||||||
gl,
|
gl,
|
||||||
screen_size_in_pixels,
|
screen_size_in_pixels,
|
||||||
app.clear_color(&integration.egui_ctx.style().visuals),
|
app.clear_color(&integration.read().egui_ctx.style().visuals),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
{
|
||||||
|
let win = &mut *win.write();
|
||||||
egui::FullOutput {
|
egui::FullOutput {
|
||||||
platform_output,
|
platform_output,
|
||||||
repaint_after,
|
repaint_after,
|
||||||
@@ -1069,33 +1133,35 @@ mod glow_integration {
|
|||||||
shapes,
|
shapes,
|
||||||
viewports,
|
viewports,
|
||||||
viewport_commands,
|
viewport_commands,
|
||||||
} = integration.update(
|
} = integration.write().update(
|
||||||
app.as_mut(),
|
app.as_mut(),
|
||||||
win.window.as_ref().unwrap(),
|
&win.window.as_ref().unwrap().read(),
|
||||||
win.egui_winit.as_mut().unwrap(),
|
win.egui_winit.as_mut().unwrap(),
|
||||||
win.render.clone(),
|
win.render.clone(),
|
||||||
win.window_id,
|
win.window_id,
|
||||||
win.parent_id,
|
win.parent_id,
|
||||||
);
|
);
|
||||||
|
|
||||||
integration.handle_platform_output(
|
integration.write().handle_platform_output(
|
||||||
win.window.as_ref().unwrap(),
|
&win.window.as_ref().unwrap().read(),
|
||||||
platform_output,
|
platform_output,
|
||||||
win.egui_winit.as_mut().unwrap(),
|
win.egui_winit.as_mut().unwrap(),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
let clipped_primitives = {
|
let clipped_primitives = {
|
||||||
crate::profile_scope!("tessellate");
|
crate::profile_scope!("tessellate");
|
||||||
integration.egui_ctx.tessellate(shapes)
|
integration.read().egui_ctx.tessellate(shapes)
|
||||||
};
|
};
|
||||||
|
|
||||||
painter.paint_and_update_textures(
|
painter.paint_and_update_textures(
|
||||||
screen_size_in_pixels,
|
screen_size_in_pixels,
|
||||||
integration.egui_ctx.pixels_per_point(),
|
integration.read().egui_ctx.pixels_per_point(),
|
||||||
&clipped_primitives,
|
&clipped_primitives,
|
||||||
&textures_delta,
|
&textures_delta,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let mut integration = integration.write();
|
||||||
|
{
|
||||||
let screenshot_requested =
|
let screenshot_requested =
|
||||||
&mut integration.frame.output.screenshot_requested;
|
&mut integration.frame.output.screenshot_requested;
|
||||||
|
|
||||||
@@ -1105,22 +1171,29 @@ mod glow_integration {
|
|||||||
integration.frame.screenshot.set(Some(screenshot));
|
integration.frame.screenshot.set(Some(screenshot));
|
||||||
}
|
}
|
||||||
|
|
||||||
integration.post_rendering(app.as_mut(), win.window.as_ref().unwrap());
|
integration.post_rendering(
|
||||||
|
app.as_mut(),
|
||||||
{
|
&win.read().window.as_ref().unwrap().read(),
|
||||||
crate::profile_scope!("swap_buffers");
|
|
||||||
let _ =
|
|
||||||
win.gl_surface
|
|
||||||
.as_ref()
|
|
||||||
.expect("failed to get surface to swap buffers")
|
|
||||||
.swap_buffers(
|
|
||||||
gl_window.current_gl_context.as_ref().expect(
|
|
||||||
"failed to get current context to swap buffers",
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
integration.post_present(win.window.as_ref().unwrap());
|
{
|
||||||
|
crate::profile_scope!("swap_buffers");
|
||||||
|
let _ = win
|
||||||
|
.read()
|
||||||
|
.gl_surface
|
||||||
|
.as_ref()
|
||||||
|
.expect("failed to get surface to swap buffers")
|
||||||
|
.swap_buffers(
|
||||||
|
gl_window
|
||||||
|
.read()
|
||||||
|
.current_gl_context
|
||||||
|
.as_ref()
|
||||||
|
.expect("failed to get current context to swap buffers"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
integration.post_present(&win.read().window.as_ref().unwrap().read());
|
||||||
|
|
||||||
#[cfg(feature = "__screenshot")]
|
#[cfg(feature = "__screenshot")]
|
||||||
// give it time to settle:
|
// give it time to settle:
|
||||||
@@ -1173,9 +1246,10 @@ mod glow_integration {
|
|||||||
.collect::<Vec<EventResult>>()
|
.collect::<Vec<EventResult>>()
|
||||||
};
|
};
|
||||||
|
|
||||||
integration.maybe_autosave(app.as_mut(), win.window.as_ref().unwrap());
|
integration
|
||||||
|
.maybe_autosave(app.as_mut(), &win.read().window.as_ref().unwrap().read());
|
||||||
|
|
||||||
if win.window.as_ref().unwrap().is_minimized() == Some(true) {
|
if win.read().window.as_ref().unwrap().read().is_minimized() == Some(true) {
|
||||||
// On Mac, a minimized Window uses up all CPU:
|
// On Mac, a minimized Window uses up all CPU:
|
||||||
// https://github.com/emilk/egui/issues/325
|
// https://github.com/emilk/egui/issues/325
|
||||||
crate::profile_scope!("bg_sleep");
|
crate::profile_scope!("bg_sleep");
|
||||||
@@ -1187,11 +1261,11 @@ mod glow_integration {
|
|||||||
let mut active_viewports_ids = vec![0];
|
let mut active_viewports_ids = vec![0];
|
||||||
|
|
||||||
viewports.retain_mut(|(id, _, builder, render)| {
|
viewports.retain_mut(|(id, _, builder, render)| {
|
||||||
for w in gl_window.windows.iter_mut() {
|
if let Some(w) = gl_window.read().windows.get(id) {
|
||||||
if w.window_id == *id {
|
let mut w = w.write();
|
||||||
if w.builder != *builder {
|
if w.builder != *builder {
|
||||||
if let Some(window) = &mut w.window {
|
if let Some(window) = &mut w.window {
|
||||||
if let Ok(pos) = window.outer_position() {
|
if let Ok(pos) = window.read().outer_position() {
|
||||||
builder.position = Some((pos.x, pos.y));
|
builder.position = Some((pos.x, pos.y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1202,14 +1276,16 @@ mod glow_integration {
|
|||||||
w.parent_id = *id;
|
w.parent_id = *id;
|
||||||
}
|
}
|
||||||
active_viewports_ids.push(*id);
|
active_viewports_ids.push(*id);
|
||||||
return false;
|
false
|
||||||
}
|
} else {
|
||||||
}
|
|
||||||
true
|
true
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
for (id, parent, builder, render) in viewports {
|
for (id, parent, builder, render) in viewports {
|
||||||
gl_window.windows.push(Window {
|
gl_window.write().windows.insert(
|
||||||
|
id,
|
||||||
|
Arc::new(RwLock::new(Window {
|
||||||
builder,
|
builder,
|
||||||
gl_surface: None,
|
gl_surface: None,
|
||||||
window: None,
|
window: None,
|
||||||
@@ -1217,19 +1293,21 @@ mod glow_integration {
|
|||||||
egui_winit: None,
|
egui_winit: None,
|
||||||
render: render.clone(),
|
render: render.clone(),
|
||||||
parent_id: parent,
|
parent_id: parent,
|
||||||
});
|
})),
|
||||||
|
);
|
||||||
active_viewports_ids.push(id);
|
active_viewports_ids.push(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Make this more efficient
|
|
||||||
for (id, command) in viewport_commands {
|
for (id, command) in viewport_commands {
|
||||||
for window in gl_window.windows.iter() {
|
if let Some(window) = gl_window.read().windows.get(&id) {
|
||||||
if window.window_id == id {
|
let window = window.read();
|
||||||
|
|
||||||
if let Some(win) = &window.window {
|
if let Some(win) = &window.window {
|
||||||
|
let win = win.read();
|
||||||
match command {
|
match command {
|
||||||
egui::window::ViewportCommand::Drag => {
|
egui::window::ViewportCommand::Drag => {
|
||||||
// if this is not checked on x11 the input will be permanently taken until the app is killed!
|
// if this is not checked on x11 the input will be permanently taken until the app is killed!
|
||||||
if let Some(focus) = self.is_focused {
|
if let Some(focus) = self.is_focused.read().clone() {
|
||||||
if focus == id {
|
if focus == id {
|
||||||
win.drag_window();
|
win.drag_window();
|
||||||
}
|
}
|
||||||
@@ -1238,68 +1316,34 @@ mod glow_integration {
|
|||||||
egui::window::ViewportCommand::InnerSize(width, height) => {
|
egui::window::ViewportCommand::InnerSize(width, height) => {
|
||||||
win.set_inner_size(PhysicalSize::new(width, height));
|
win.set_inner_size(PhysicalSize::new(width, height));
|
||||||
}
|
}
|
||||||
egui::window::ViewportCommand::Resize(
|
egui::window::ViewportCommand::Resize(top, bottom, right, left) => {
|
||||||
top,
|
win.drag_resize_window(match (top, bottom, right, left) {
|
||||||
bottom,
|
(true, false, false, false) => ResizeDirection::North,
|
||||||
right,
|
(false, true, false, false) => ResizeDirection::South,
|
||||||
left,
|
(false, false, true, false) => ResizeDirection::East,
|
||||||
) => {
|
(false, false, false, true) => ResizeDirection::West,
|
||||||
win.drag_resize_window(
|
(true, false, true, false) => ResizeDirection::NorthEast,
|
||||||
match (top, bottom, right, left) {
|
(false, true, true, false) => ResizeDirection::SouthEast,
|
||||||
(true, false, false, false) => {
|
(true, false, false, true) => ResizeDirection::NorthWest,
|
||||||
ResizeDirection::North
|
(false, true, false, true) => ResizeDirection::SouthWest,
|
||||||
}
|
|
||||||
(false, true, false, false) => {
|
|
||||||
ResizeDirection::South
|
|
||||||
}
|
|
||||||
(false, false, true, false) => {
|
|
||||||
ResizeDirection::East
|
|
||||||
}
|
|
||||||
(false, false, false, true) => {
|
|
||||||
ResizeDirection::West
|
|
||||||
}
|
|
||||||
(true, false, true, false) => {
|
|
||||||
ResizeDirection::NorthEast
|
|
||||||
}
|
|
||||||
(false, true, true, false) => {
|
|
||||||
ResizeDirection::SouthEast
|
|
||||||
}
|
|
||||||
(true, false, false, true) => {
|
|
||||||
ResizeDirection::NorthWest
|
|
||||||
}
|
|
||||||
(false, true, false, true) => {
|
|
||||||
ResizeDirection::SouthWest
|
|
||||||
}
|
|
||||||
_ => ResizeDirection::East,
|
_ => ResizeDirection::East,
|
||||||
},
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_window
|
gl_window
|
||||||
|
.write()
|
||||||
.windows
|
.windows
|
||||||
.retain(|w| active_viewports_ids.contains(&w.window_id));
|
.retain(|id, _| active_viewports_ids.contains(id));
|
||||||
gl_window
|
gl_window
|
||||||
|
.write()
|
||||||
.window_maps
|
.window_maps
|
||||||
.retain(|_, id| active_viewports_ids.contains(id));
|
.retain(|_, id| active_viewports_ids.contains(id));
|
||||||
|
|
||||||
control_flow
|
control_flow
|
||||||
};
|
|
||||||
|
|
||||||
let mut events = vec![EventResult::Wait];
|
|
||||||
|
|
||||||
for event in windows_indexes
|
|
||||||
.into_iter()
|
|
||||||
.map(|window_index| inner(window_index))
|
|
||||||
{
|
|
||||||
events.extend(event)
|
|
||||||
}
|
|
||||||
events
|
|
||||||
} else {
|
} else {
|
||||||
vec![EventResult::Wait]
|
vec![EventResult::Wait]
|
||||||
}
|
}
|
||||||
@@ -1315,33 +1359,55 @@ mod glow_integration {
|
|||||||
// first resume event.
|
// first resume event.
|
||||||
// we can actually move this outside of event loop.
|
// we can actually move this outside of event loop.
|
||||||
// and just run the on_resume fn of gl_window
|
// and just run the on_resume fn of gl_window
|
||||||
if self.running.is_none() {
|
if self.running.read().is_none() {
|
||||||
self.init_run_state(event_loop)?;
|
self.init_run_state(event_loop)?;
|
||||||
} else {
|
} else {
|
||||||
// not the first resume event. create whatever you need.
|
// not the first resume event. create whatever you need.
|
||||||
self.running
|
self.running
|
||||||
|
.write()
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.gl_window
|
.glutin_ctx
|
||||||
|
.write()
|
||||||
.on_resume(event_loop)?;
|
.on_resume(event_loop)?;
|
||||||
}
|
}
|
||||||
EventResult::RepaintNow(self.running.as_ref().unwrap().gl_window.window(0).id())
|
EventResult::RepaintNow(
|
||||||
|
self.running
|
||||||
|
.read()
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.glutin_ctx
|
||||||
|
.read()
|
||||||
|
.window(0)
|
||||||
|
.read()
|
||||||
|
.window
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.read()
|
||||||
|
.id(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
winit::event::Event::Suspended => {
|
winit::event::Event::Suspended => {
|
||||||
self.running.as_mut().unwrap().gl_window.on_suspend()?;
|
self.running
|
||||||
|
.write()
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.glutin_ctx
|
||||||
|
.write()
|
||||||
|
.on_suspend()?;
|
||||||
|
|
||||||
EventResult::Wait
|
EventResult::Wait
|
||||||
}
|
}
|
||||||
|
|
||||||
winit::event::Event::MainEventsCleared => {
|
winit::event::Event::MainEventsCleared => {
|
||||||
if let Some(running) = self.running.as_mut() {
|
if let Some(running) = self.running.read().as_ref() {
|
||||||
let _ = running.gl_window.on_resume(event_loop);
|
let _ = running.glutin_ctx.write().on_resume(event_loop);
|
||||||
}
|
}
|
||||||
EventResult::Wait
|
EventResult::Wait
|
||||||
}
|
}
|
||||||
|
|
||||||
winit::event::Event::WindowEvent { event, window_id } => {
|
winit::event::Event::WindowEvent { event, window_id } => {
|
||||||
if let Some(running) = &mut self.running {
|
if let Some(running) = self.running.write().as_mut() {
|
||||||
// On Windows, if a window is resized by the user, it should repaint synchronously, inside the
|
// On Windows, if a window is resized by the user, it should repaint synchronously, inside the
|
||||||
// event handler.
|
// event handler.
|
||||||
//
|
//
|
||||||
@@ -1359,8 +1425,15 @@ mod glow_integration {
|
|||||||
|
|
||||||
match &event {
|
match &event {
|
||||||
winit::event::WindowEvent::Focused(new_focused) => {
|
winit::event::WindowEvent::Focused(new_focused) => {
|
||||||
self.is_focused = new_focused
|
*self.is_focused.write() = new_focused
|
||||||
.then(|| running.gl_window.window_maps.get(window_id).cloned())
|
.then(|| {
|
||||||
|
running
|
||||||
|
.glutin_ctx
|
||||||
|
.write()
|
||||||
|
.window_maps
|
||||||
|
.get(window_id)
|
||||||
|
.cloned()
|
||||||
|
})
|
||||||
.flatten();
|
.flatten();
|
||||||
}
|
}
|
||||||
winit::event::WindowEvent::Resized(physical_size) => {
|
winit::event::WindowEvent::Resized(physical_size) => {
|
||||||
@@ -1369,9 +1442,10 @@ mod glow_integration {
|
|||||||
// Resize with 0 width and height is used by winit to signal a minimize event on Windows.
|
// Resize with 0 width and height is used by winit to signal a minimize event on Windows.
|
||||||
// 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.
|
||||||
|
let glutin_ctx = &mut *running.glutin_ctx.write();
|
||||||
if physical_size.width > 0 && physical_size.height > 0 {
|
if physical_size.width > 0 && physical_size.height > 0 {
|
||||||
if let Some(id) = running.gl_window.window_maps.get(window_id) {
|
if let Some(id) = glutin_ctx.window_maps.get(window_id) {
|
||||||
running.gl_window.resize(*id, *physical_size);
|
glutin_ctx.resize(*id, *physical_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1379,20 +1453,23 @@ mod glow_integration {
|
|||||||
new_inner_size,
|
new_inner_size,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
|
let glutin_ctx = &mut *running.glutin_ctx.write();
|
||||||
repaint_asap = true;
|
repaint_asap = true;
|
||||||
if let Some(id) = running.gl_window.window_maps.get(window_id) {
|
if let Some(id) = glutin_ctx.window_maps.get(window_id) {
|
||||||
running.gl_window.resize(*id, **new_inner_size);
|
glutin_ctx.resize(*id, **new_inner_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
winit::event::WindowEvent::CloseRequested
|
winit::event::WindowEvent::CloseRequested
|
||||||
if running
|
if running
|
||||||
.gl_window
|
.glutin_ctx
|
||||||
|
.write()
|
||||||
.windows
|
.windows
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|window| {
|
.flat_map(|(_, window)| {
|
||||||
if let Some(win) = &window.window {
|
if let Some(win) = window.read().window.as_ref() {
|
||||||
|
let win = win.read();
|
||||||
if win.id() == *window_id {
|
if win.id() == *window_id {
|
||||||
Some(window.window_id)
|
Some(window.read().window_id)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@@ -1403,7 +1480,7 @@ mod glow_integration {
|
|||||||
.flat_map(|id| if id == 0 { Some(()) } else { None })
|
.flat_map(|id| if id == 0 { Some(()) } else { None })
|
||||||
.count()
|
.count()
|
||||||
== 1
|
== 1
|
||||||
&& running.integration.should_close() =>
|
&& running.integration.read().should_close() =>
|
||||||
{
|
{
|
||||||
log::debug!("Received WindowEvent::CloseRequested");
|
log::debug!("Received WindowEvent::CloseRequested");
|
||||||
return Ok(EventResult::Exit);
|
return Ok(EventResult::Exit);
|
||||||
@@ -1412,24 +1489,32 @@ mod glow_integration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let event_response = 'res: {
|
let event_response = 'res: {
|
||||||
for window in running.gl_window.windows.iter_mut() {
|
let glutin_ctx = running.glutin_ctx.read();
|
||||||
if window.window.as_ref().unwrap().id() == *window_id {
|
if let Some(viewport_id) =
|
||||||
break 'res running.integration.on_event(
|
glutin_ctx.window_maps.get(window_id).cloned()
|
||||||
|
{
|
||||||
|
if let Some(viewport) =
|
||||||
|
glutin_ctx.windows.get(&viewport_id).cloned()
|
||||||
|
{
|
||||||
|
let viewport = &mut *viewport.write();
|
||||||
|
|
||||||
|
break 'res running.integration.write().on_event(
|
||||||
running.app.as_mut(),
|
running.app.as_mut(),
|
||||||
event,
|
event,
|
||||||
window_id,
|
window_id,
|
||||||
window.egui_winit.as_mut().unwrap(),
|
viewport.egui_winit.as_mut().unwrap(),
|
||||||
window.window_id,
|
viewport.window_id,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EventResponse {
|
EventResponse {
|
||||||
consumed: false,
|
consumed: false,
|
||||||
repaint: false,
|
repaint: false,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if running.integration.should_close() {
|
if running.integration.read().should_close() {
|
||||||
EventResult::Exit
|
EventResult::Exit
|
||||||
} else if event_response.repaint {
|
} else if event_response.repaint {
|
||||||
if repaint_asap {
|
if repaint_asap {
|
||||||
@@ -1448,20 +1533,21 @@ mod glow_integration {
|
|||||||
winit::event::Event::UserEvent(UserEvent::AccessKitActionRequest(
|
winit::event::Event::UserEvent(UserEvent::AccessKitActionRequest(
|
||||||
accesskit_winit::ActionRequestEvent { request, window_id },
|
accesskit_winit::ActionRequestEvent { request, window_id },
|
||||||
)) => {
|
)) => {
|
||||||
if let Some(running) = &mut self.running {
|
if let Some(running) = self.running.read().as_ref() {
|
||||||
for window in running.gl_window.windows.iter_mut() {
|
let glutin_ctx = running.glutin_ctx.read();
|
||||||
if window.window.as_ref().unwrap().id() == *window_id {
|
if let Some(viewport_id) = glutin_ctx.window_maps.get(window_id).cloned() {
|
||||||
running.integration.on_accesskit_action_request(
|
if let Some(viewport) = glutin_ctx.windows.get(&viewport_id).cloned() {
|
||||||
|
let mut viewport = viewport.write();
|
||||||
|
running.integration.write().on_accesskit_action_request(
|
||||||
request.clone(),
|
request.clone(),
|
||||||
window_id,
|
window_id,
|
||||||
window.egui_winit.as_mut().unwrap(),
|
viewport.egui_winit.as_mut().unwrap(),
|
||||||
);
|
)
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// As a form of user input, accessibility actions should
|
// As a form of user input, accessibility actions should
|
||||||
// lead to a repaint.
|
// lead to a repaint.
|
||||||
EventResult::RepaintNext(running.gl_window.window(0).id())
|
EventResult::RepaintNext(*window_id)
|
||||||
} else {
|
} else {
|
||||||
EventResult::Wait
|
EventResult::Wait
|
||||||
}
|
}
|
||||||
@@ -1726,16 +1812,21 @@ mod wgpu_integration {
|
|||||||
self.is_focused
|
self.is_focused
|
||||||
}
|
}
|
||||||
|
|
||||||
fn integration(&self) -> Option<&EpiIntegration> {
|
fn integration(&self) -> Option<Arc<RwLock<EpiIntegration>>> {
|
||||||
self.running.as_ref().map(|r| &r.integration)
|
todo!()
|
||||||
|
// self.running.as_ref().map(|r| r.integration)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn window(&self, window_id: winit::window::WindowId) -> Option<&winit::window::Window> {
|
fn window(
|
||||||
self.running
|
&self,
|
||||||
.as_ref()
|
window_id: winit::window::WindowId,
|
||||||
.and_then(|r| r.windows_id.get(&window_id).map(|id| r.windows.get(id)))
|
) -> Option<Arc<RwLock<winit::window::Window>>> {
|
||||||
.flatten()
|
todo!()
|
||||||
.and_then(|w| w.0.as_ref())
|
// self.running
|
||||||
|
// .as_ref()
|
||||||
|
// .and_then(|r| r.windows_id.get(&window_id).map(|id| r.windows.get(id)))
|
||||||
|
// .flatten()
|
||||||
|
// .and_then(|w| w.0.as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_window_winit_id(&self, id: u64) -> Option<winit::window::WindowId> {
|
fn get_window_winit_id(&self, id: u64) -> Option<winit::window::WindowId> {
|
||||||
|
|||||||
Reference in New Issue
Block a user