mirror of
https://github.com/emilk/egui.git
synced 2026-09-03 07:10:04 -04:00
Now viewport_sync will process viewport_commands and will create new viewports if is needed!
Some refactoring now processing viewports_commands is in egui_winit::process_viewport_commands And creating new windows and cleaning is in GlowWinitApp::process_viewport_builders
This commit is contained in:
@@ -974,61 +974,90 @@ mod glow_integration {
|
|||||||
let _painter = painter.clone();
|
let _painter = painter.clone();
|
||||||
let time = integration.beagining;
|
let time = integration.beagining;
|
||||||
|
|
||||||
|
let focused = self.is_focused.clone();
|
||||||
|
|
||||||
// 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| {
|
||||||
let window = glutin.read().windows.get(&viewport_id).cloned();
|
'try_render: {
|
||||||
if let Some(window) = window {
|
let window = glutin.read().windows.get(&viewport_id).cloned();
|
||||||
let window = &mut *window.write();
|
if let Some(window) = window {
|
||||||
if let Some(winit_state) = &mut window.egui_winit {
|
let output;
|
||||||
if let Some(win) = window.window.clone() {
|
{
|
||||||
let win = win.read();
|
let window = &mut *window.write();
|
||||||
let mut input = winit_state.take_egui_input(&win);
|
if let Some(winit_state) = &mut window.egui_winit {
|
||||||
input.time = Some(time.elapsed().as_secs_f64());
|
if let Some(win) = window.window.clone() {
|
||||||
let output =
|
let win = win.read();
|
||||||
egui_ctx.run(input, viewport_id, parent_viewport_id, |ctx| {
|
let mut input = winit_state.take_egui_input(&win);
|
||||||
render(ctx, viewport_id, parent_viewport_id);
|
input.time = Some(time.elapsed().as_secs_f64());
|
||||||
});
|
output = egui_ctx.run(
|
||||||
let glutin = &mut *glutin.write();
|
input,
|
||||||
|
viewport_id,
|
||||||
|
parent_viewport_id,
|
||||||
|
|ctx| {
|
||||||
|
render(ctx, viewport_id, parent_viewport_id);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
let glutin = &mut *glutin.write();
|
||||||
|
|
||||||
glutin.current_gl_context = Some(
|
glutin.current_gl_context = Some(
|
||||||
glutin
|
glutin
|
||||||
.current_gl_context
|
.current_gl_context
|
||||||
.take()
|
.take()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.make_not_current()
|
.make_not_current()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.make_current(window.gl_surface.as_ref().unwrap())
|
.make_current(window.gl_surface.as_ref().unwrap())
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let screen_size_in_pixels: [u32; 2] = win.inner_size().into();
|
let screen_size_in_pixels: [u32; 2] =
|
||||||
|
win.inner_size().into();
|
||||||
|
|
||||||
egui_glow::painter::clear(
|
egui_glow::painter::clear(
|
||||||
&_gl,
|
&_gl,
|
||||||
screen_size_in_pixels,
|
screen_size_in_pixels,
|
||||||
[0.0, 0.0, 0.0, 0.0],
|
[0.0, 0.0, 0.0, 0.0],
|
||||||
);
|
);
|
||||||
|
|
||||||
let clipped_primitives = egui_ctx.tessellate(output.shapes);
|
let clipped_primitives = egui_ctx.tessellate(output.shapes);
|
||||||
|
|
||||||
_painter.write().paint_and_update_textures(
|
_painter.write().paint_and_update_textures(
|
||||||
screen_size_in_pixels,
|
screen_size_in_pixels,
|
||||||
egui_ctx.pixels_per_point(),
|
egui_ctx.pixels_per_point(),
|
||||||
&clipped_primitives,
|
&clipped_primitives,
|
||||||
&output.textures_delta,
|
&output.textures_delta,
|
||||||
);
|
);
|
||||||
crate::profile_scope!("swap_buffers");
|
crate::profile_scope!("swap_buffers");
|
||||||
let _ =
|
let _ = window
|
||||||
window
|
.gl_surface
|
||||||
.gl_surface
|
.as_ref()
|
||||||
.as_ref()
|
.expect("failed to get surface to swap buffers")
|
||||||
.expect("failed to get surface to swap buffers")
|
.swap_buffers(
|
||||||
.swap_buffers(glutin.current_gl_context.as_ref().expect(
|
glutin.current_gl_context.as_ref().expect(
|
||||||
"failed to get current context to swap buffers",
|
"failed to get current context to swap buffers",
|
||||||
));
|
),
|
||||||
return;
|
);
|
||||||
|
} else {
|
||||||
|
break 'try_render;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break 'try_render;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Self::process_viewport_builders(glutin.clone(), output.viewports);
|
||||||
|
egui_winit::process_viewport_commands(
|
||||||
|
output.viewport_commands,
|
||||||
|
focused.read().clone(),
|
||||||
|
|id| {
|
||||||
|
glutin
|
||||||
|
.read()
|
||||||
|
.windows
|
||||||
|
.get(&id)
|
||||||
|
.and_then(|w| w.read().window.clone())
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
render(&egui_ctx, 0, 0);
|
render(&egui_ctx, 0, 0);
|
||||||
@@ -1045,6 +1074,65 @@ mod glow_integration {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn process_viewport_builders(
|
||||||
|
glutin_ctx: Arc<RwLock<GlutinWindowContext>>,
|
||||||
|
mut viewports: Vec<(
|
||||||
|
u64,
|
||||||
|
u64,
|
||||||
|
ViewportBuilder,
|
||||||
|
Option<Arc<Box<dyn Fn(&egui::Context, u64, u64) + Sync + Send>>>,
|
||||||
|
)>,
|
||||||
|
) {
|
||||||
|
// 0 is the main viewport/window that will not be known by the egui_ctx
|
||||||
|
let mut active_viewports_ids = vec![0];
|
||||||
|
|
||||||
|
viewports.retain_mut(|(id, _, builder, render)| {
|
||||||
|
if let Some(w) = glutin_ctx.read().windows.get(id) {
|
||||||
|
let mut w = w.write();
|
||||||
|
if w.builder != *builder {
|
||||||
|
if let Some(window) = &mut w.window {
|
||||||
|
if let Ok(pos) = window.read().outer_position() {
|
||||||
|
builder.position = Some((pos.x, pos.y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
w.window = None;
|
||||||
|
w.gl_surface = None;
|
||||||
|
w.render = render.clone();
|
||||||
|
w.builder = builder.clone();
|
||||||
|
w.parent_id = *id;
|
||||||
|
}
|
||||||
|
active_viewports_ids.push(*id);
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for (id, parent, builder, render) in viewports {
|
||||||
|
glutin_ctx.write().windows.insert(
|
||||||
|
id,
|
||||||
|
Arc::new(RwLock::new(Window {
|
||||||
|
builder,
|
||||||
|
gl_surface: None,
|
||||||
|
window: None,
|
||||||
|
window_id: id,
|
||||||
|
egui_winit: None,
|
||||||
|
render: render.clone(),
|
||||||
|
parent_id: parent,
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
active_viewports_ids.push(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut gl_window = glutin_ctx.write();
|
||||||
|
gl_window
|
||||||
|
.windows
|
||||||
|
.retain(|id, _| active_viewports_ids.contains(id));
|
||||||
|
gl_window
|
||||||
|
.window_maps
|
||||||
|
.retain(|_, id| active_viewports_ids.contains(id));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WinitApp for GlowWinitApp {
|
impl WinitApp for GlowWinitApp {
|
||||||
@@ -1343,90 +1431,19 @@ mod glow_integration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0 is the main viewport/window that will not be known by the egui_ctx
|
Self::process_viewport_builders(glutin_ctx.clone(), viewports);
|
||||||
let mut active_viewports_ids = vec![0];
|
|
||||||
|
|
||||||
viewports.retain_mut(|(id, _, builder, render)| {
|
egui_winit::process_viewport_commands(
|
||||||
if let Some(w) = glutin_ctx.read().windows.get(id) {
|
viewport_commands,
|
||||||
let mut w = w.write();
|
*self.is_focused.read(),
|
||||||
if w.builder != *builder {
|
|viewport_id| {
|
||||||
if let Some(window) = &mut w.window {
|
glutin_ctx
|
||||||
if let Ok(pos) = window.read().outer_position() {
|
.read()
|
||||||
builder.position = Some((pos.x, pos.y));
|
.windows
|
||||||
}
|
.get(&viewport_id)
|
||||||
}
|
.and_then(|w| w.read().window.clone())
|
||||||
w.window = None;
|
},
|
||||||
w.gl_surface = None;
|
);
|
||||||
w.render = render.clone();
|
|
||||||
w.builder = builder.clone();
|
|
||||||
w.parent_id = *id;
|
|
||||||
}
|
|
||||||
active_viewports_ids.push(*id);
|
|
||||||
false
|
|
||||||
} else {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
for (id, parent, builder, render) in viewports {
|
|
||||||
glutin_ctx.write().windows.insert(
|
|
||||||
id,
|
|
||||||
Arc::new(RwLock::new(Window {
|
|
||||||
builder,
|
|
||||||
gl_surface: None,
|
|
||||||
window: None,
|
|
||||||
window_id: id,
|
|
||||||
egui_winit: None,
|
|
||||||
render: render.clone(),
|
|
||||||
parent_id: parent,
|
|
||||||
})),
|
|
||||||
);
|
|
||||||
active_viewports_ids.push(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (id, command) in viewport_commands {
|
|
||||||
if let Some(window) = glutin_ctx.read().windows.get(&id) {
|
|
||||||
let window = window.read();
|
|
||||||
|
|
||||||
if let Some(win) = &window.window {
|
|
||||||
let win = win.read();
|
|
||||||
match command {
|
|
||||||
egui::window::ViewportCommand::Drag => {
|
|
||||||
// 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.read().clone() {
|
|
||||||
if focus == id {
|
|
||||||
win.drag_window();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
egui::window::ViewportCommand::InnerSize(width, height) => {
|
|
||||||
win.set_inner_size(PhysicalSize::new(width, height));
|
|
||||||
}
|
|
||||||
egui::window::ViewportCommand::Resize(top, bottom, right, left) => {
|
|
||||||
win.drag_resize_window(match (top, bottom, right, left) {
|
|
||||||
(true, false, false, false) => ResizeDirection::North,
|
|
||||||
(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,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut gl_window = glutin_ctx.write();
|
|
||||||
gl_window
|
|
||||||
.windows
|
|
||||||
.retain(|id, _| active_viewports_ids.contains(id));
|
|
||||||
gl_window
|
|
||||||
.window_maps
|
|
||||||
.retain(|_, id| active_viewports_ids.contains(id));
|
|
||||||
|
|
||||||
control_flow
|
control_flow
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -9,11 +9,14 @@
|
|||||||
|
|
||||||
#![allow(clippy::manual_range_contains)]
|
#![allow(clippy::manual_range_contains)]
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
#[cfg(feature = "accesskit")]
|
#[cfg(feature = "accesskit")]
|
||||||
pub use accesskit_winit;
|
pub use accesskit_winit;
|
||||||
pub use egui;
|
pub use egui;
|
||||||
#[cfg(feature = "accesskit")]
|
#[cfg(feature = "accesskit")]
|
||||||
use egui::accesskit;
|
use egui::accesskit;
|
||||||
|
use egui::{mutex::RwLock, window::ViewportCommand};
|
||||||
pub use winit;
|
pub use winit;
|
||||||
|
|
||||||
pub mod clipboard;
|
pub mod clipboard;
|
||||||
@@ -901,6 +904,47 @@ fn translate_cursor(cursor_icon: egui::CursorIcon) -> Option<winit::window::Curs
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn process_viewport_commands(
|
||||||
|
commands: Vec<(u64, ViewportCommand)>,
|
||||||
|
focused: Option<u64>,
|
||||||
|
get_window: impl Fn(u64) -> Option<Arc<RwLock<winit::window::Window>>>,
|
||||||
|
) {
|
||||||
|
use winit::dpi::PhysicalSize;
|
||||||
|
use winit::window::ResizeDirection;
|
||||||
|
for (viewport_id, command) in commands {
|
||||||
|
if let Some(window) = get_window(viewport_id) {
|
||||||
|
let win = window.read();
|
||||||
|
|
||||||
|
match command {
|
||||||
|
egui::window::ViewportCommand::Drag => {
|
||||||
|
// if this is not checked on x11 the input will be permanently taken until the app is killed!
|
||||||
|
if let Some(focus) = focused {
|
||||||
|
if focus == viewport_id {
|
||||||
|
win.drag_window();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
egui::window::ViewportCommand::InnerSize(width, height) => {
|
||||||
|
win.set_inner_size(PhysicalSize::new(width, height));
|
||||||
|
}
|
||||||
|
egui::window::ViewportCommand::Resize(top, bottom, right, left) => {
|
||||||
|
win.drag_resize_window(match (top, bottom, right, left) {
|
||||||
|
(true, false, false, false) => ResizeDirection::North,
|
||||||
|
(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,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
/// Profiling macro for feature "puffin"
|
/// Profiling macro for feature "puffin"
|
||||||
|
|||||||
Reference in New Issue
Block a user