diff --git a/crates/eframe/src/native/run.rs b/crates/eframe/src/native/run.rs index 0d890d76b..27cea9c9b 100644 --- a/crates/eframe/src/native/run.rs +++ b/crates/eframe/src/native/run.rs @@ -462,10 +462,7 @@ mod glow_integration { epaint::ahash::HashMap, NumExt as _, ViewportIdMap, ViewportIdPair, ViewportOutput, ViewportUiCallback, }; - use egui_winit::{ - changes_between_builders, create_winit_window_builder, process_viewport_commands, - EventResponse, - }; + use egui_winit::{create_winit_window_builder, process_viewport_commands, EventResponse}; use glutin::{ display::GetGlDisplay, prelude::{GlDisplay, NotCurrentGlContextSurfaceAccessor, PossiblyCurrentGlContext}, @@ -1263,13 +1260,13 @@ mod glow_integration { viewports.retain_mut( |ViewportOutput { - builder, + builder: new_builder, id_pair: ViewportIdPair { this: id, parent }, viewport_ui_cb, }| { let mut glutin = glutin_ctx.borrow_mut(); - let last_builder = glutin.builders.entry(*id).or_insert(builder.clone()); - let (commands, recreate) = changes_between_builders(builder, last_builder); + let builder = glutin.builders.entry(*id).or_insert(new_builder.clone()); + let (commands, recreate) = builder.patch(new_builder); drop(glutin); if let Some(viewport) = glutin_ctx.borrow().viewports.get(id) { let mut viewport = viewport.borrow_mut(); @@ -2533,7 +2530,7 @@ mod wgpu_integration { ); for ViewportOutput { - mut builder, + builder: mut new_builder, id_pair, viewport_ui_cb, } in out_viewports @@ -2541,15 +2538,14 @@ mod wgpu_integration { let mut builders = builders.borrow_mut(); let mut viewports = viewports.borrow_mut(); - if builder.icon.is_none() { - builder.icon = builders + if new_builder.icon.is_none() { + new_builder.icon = builders .get_mut(&id_pair.parent) .and_then(|w| w.icon.clone()); } - if let Some(last_builder) = builders.get_mut(&id_pair.this) { - let (commands, recreate) = - egui_winit::changes_between_builders(&builder, last_builder); + if let Some(builder) = builders.get_mut(&id_pair.this) { + let (commands, recreate) = builder.patch(&new_builder); if recreate { if let Some(viewport) = viewports.get_mut(&id_pair.this) { @@ -2578,7 +2574,7 @@ mod wgpu_integration { parent_id: id_pair.parent, }, ); - builders.insert(id_pair.this, builder); + builders.insert(id_pair.this, new_builder); } active_viewports_ids.push(id_pair.this); diff --git a/crates/egui-winit/src/lib.rs b/crates/egui-winit/src/lib.rs index 9584e3af6..e76092ce4 100644 --- a/crates/egui-winit/src/lib.rs +++ b/crates/egui-winit/src/lib.rs @@ -9,8 +9,6 @@ #![allow(clippy::manual_range_contains)] -use std::sync::Arc; - #[cfg(feature = "accesskit")] pub use accesskit_winit; pub use egui; @@ -1209,175 +1207,6 @@ pub fn create_winit_window_builder(builder: &ViewportBuilder) -> winit::window:: window_builder } -pub fn changes_between_builders( - new: &ViewportBuilder, - last: &mut ViewportBuilder, -) -> (Vec, bool) { - let mut commands = Vec::new(); - - if let Some(new_title) = &new.title { - if Some(new_title) != last.title.as_ref() { - last.title = Some(new_title.clone()); - commands.push(ViewportCommand::Title(new_title.clone())); - } - } - - if let Some(new_position) = new.position { - if Some(new_position) != last.position { - last.position = Some(new_position); - if let Some(position) = new_position { - commands.push(ViewportCommand::OuterPosition(position)); - } - } - } - - if let Some(new_inner_size) = new.inner_size { - if Some(new_inner_size) != last.inner_size { - last.inner_size = Some(new_inner_size); - if let Some(inner_size) = new_inner_size { - commands.push(ViewportCommand::InnerSize(inner_size)); - } - } - } - - if let Some(new_min_inner_size) = new.min_inner_size { - if Some(new_min_inner_size) != last.min_inner_size { - last.min_inner_size = Some(new_min_inner_size); - commands.push(ViewportCommand::MinInnerSize(new_min_inner_size)); - } - } - - if let Some(new_max_inner_size) = new.max_inner_size { - if Some(new_max_inner_size) != last.max_inner_size { - last.max_inner_size = Some(new_max_inner_size); - commands.push(ViewportCommand::MaxInnerSize(new_max_inner_size)); - } - } - - if let Some(new_fullscreen) = new.fullscreen { - if Some(new_fullscreen) != last.fullscreen { - last.fullscreen = Some(new_fullscreen); - commands.push(ViewportCommand::Fullscreen(new_fullscreen)); - } - } - - if let Some(new_maximized) = new.maximized { - if Some(new_maximized) != last.maximized { - last.maximized = Some(new_maximized); - commands.push(ViewportCommand::Maximized(new_maximized)); - } - } - - if let Some(new_resizable) = new.resizable { - if Some(new_resizable) != last.resizable { - last.resizable = Some(new_resizable); - commands.push(ViewportCommand::Resizable(new_resizable)); - } - } - - if let Some(new_transparent) = new.transparent { - if Some(new_transparent) != last.transparent { - last.transparent = Some(new_transparent); - commands.push(ViewportCommand::Transparent(new_transparent)); - } - } - - if let Some(new_decorations) = new.decorations { - if Some(new_decorations) != last.decorations { - last.decorations = Some(new_decorations); - commands.push(ViewportCommand::Decorations(new_decorations)); - } - } - - if let Some(new_icon) = new.icon.clone() { - let eq = match &new_icon { - Some(icon) => { - if let Some(last_icon) = &last.icon { - matches!(last_icon, Some(last_icon) if Arc::ptr_eq(icon, last_icon)) - } else { - false - } - } - None => last.icon == Some(None), - }; - - if !eq { - commands.push(ViewportCommand::WindowIcon( - new_icon.as_ref().map(|i| i.as_ref().clone()), - )); - last.icon = Some(new_icon); - } - } - - if let Some(new_visible) = new.visible { - if Some(new_visible) != last.active { - last.visible = Some(new_visible); - commands.push(ViewportCommand::Visible(new_visible)); - } - } - - if let Some(new_hittest) = new.hittest { - if Some(new_hittest) != last.hittest { - last.hittest = Some(new_hittest); - commands.push(ViewportCommand::CursorHitTest(new_hittest)); - } - } - - // TODO: Implement compare for windows buttons - - let mut recreate_window = false; - - if let Some(new_active) = new.active { - if Some(new_active) != last.active { - last.active = Some(new_active); - recreate_window = true; - } - } - - if let Some(new_close_button) = new.close_button { - if Some(new_close_button) != last.close_button { - last.close_button = Some(new_close_button); - recreate_window = true; - } - } - - if let Some(new_minimize_button) = new.minimize_button { - if Some(new_minimize_button) != last.minimize_button { - last.minimize_button = Some(new_minimize_button); - recreate_window = true; - } - } - - if let Some(new_maximized_button) = new.maximize_button { - if Some(new_maximized_button) != last.maximize_button { - last.maximize_button = Some(new_maximized_button); - recreate_window = true; - } - } - - if let Some(new_title_hidden) = new.title_hidden { - if Some(new_title_hidden) != last.title_hidden { - last.title_hidden = Some(new_title_hidden); - recreate_window = true; - } - } - - if let Some(new_titlebar_transparent) = new.titlebar_transparent { - if Some(new_titlebar_transparent) != last.titlebar_transparent { - last.titlebar_transparent = Some(new_titlebar_transparent); - recreate_window = true; - } - } - - if let Some(new_fullsize_content_view) = new.fullsize_content_view { - if Some(new_fullsize_content_view) != last.fullsize_content_view { - last.fullsize_content_view = Some(new_fullsize_content_view); - recreate_window = true; - } - } - - (commands, recreate_window) -} // --------------------------------------------------------------------------- mod profiling_scopes { diff --git a/crates/egui/src/viewport.rs b/crates/egui/src/viewport.rs index 01533dd9b..4a73173d0 100644 --- a/crates/egui/src/viewport.rs +++ b/crates/egui/src/viewport.rs @@ -400,6 +400,173 @@ impl ViewportBuilder { self.hittest = Some(value); self } + + pub fn patch(&mut self, new: &ViewportBuilder) -> (Vec, bool) { + let mut commands = Vec::new(); + + if let Some(new_title) = &new.title { + if Some(new_title) != self.title.as_ref() { + self.title = Some(new_title.clone()); + commands.push(ViewportCommand::Title(new_title.clone())); + } + } + + if let Some(new_position) = new.position { + if Some(new_position) != self.position { + self.position = Some(new_position); + if let Some(position) = new_position { + commands.push(ViewportCommand::OuterPosition(position)); + } + } + } + + if let Some(new_inner_size) = new.inner_size { + if Some(new_inner_size) != self.inner_size { + self.inner_size = Some(new_inner_size); + if let Some(inner_size) = new_inner_size { + commands.push(ViewportCommand::InnerSize(inner_size)); + } + } + } + + if let Some(new_min_inner_size) = new.min_inner_size { + if Some(new_min_inner_size) != self.min_inner_size { + self.min_inner_size = Some(new_min_inner_size); + commands.push(ViewportCommand::MinInnerSize(new_min_inner_size)); + } + } + + if let Some(new_max_inner_size) = new.max_inner_size { + if Some(new_max_inner_size) != self.max_inner_size { + self.max_inner_size = Some(new_max_inner_size); + commands.push(ViewportCommand::MaxInnerSize(new_max_inner_size)); + } + } + + if let Some(new_fullscreen) = new.fullscreen { + if Some(new_fullscreen) != self.fullscreen { + self.fullscreen = Some(new_fullscreen); + commands.push(ViewportCommand::Fullscreen(new_fullscreen)); + } + } + + if let Some(new_maximized) = new.maximized { + if Some(new_maximized) != self.maximized { + self.maximized = Some(new_maximized); + commands.push(ViewportCommand::Maximized(new_maximized)); + } + } + + if let Some(new_resizable) = new.resizable { + if Some(new_resizable) != self.resizable { + self.resizable = Some(new_resizable); + commands.push(ViewportCommand::Resizable(new_resizable)); + } + } + + if let Some(new_transparent) = new.transparent { + if Some(new_transparent) != self.transparent { + self.transparent = Some(new_transparent); + commands.push(ViewportCommand::Transparent(new_transparent)); + } + } + + if let Some(new_decorations) = new.decorations { + if Some(new_decorations) != self.decorations { + self.decorations = Some(new_decorations); + commands.push(ViewportCommand::Decorations(new_decorations)); + } + } + + if let Some(new_icon) = new.icon.clone() { + let eq = match &new_icon { + Some(icon) => { + if let Some(self_icon) = &self.icon { + matches!(self_icon, Some(self_icon) if Arc::ptr_eq(icon, self_icon)) + } else { + false + } + } + None => self.icon == Some(None), + }; + + if !eq { + commands.push(ViewportCommand::WindowIcon( + new_icon.as_ref().map(|i| i.as_ref().clone()), + )); + self.icon = Some(new_icon); + } + } + + if let Some(new_visible) = new.visible { + if Some(new_visible) != self.active { + self.visible = Some(new_visible); + commands.push(ViewportCommand::Visible(new_visible)); + } + } + + if let Some(new_hittest) = new.hittest { + if Some(new_hittest) != self.hittest { + self.hittest = Some(new_hittest); + commands.push(ViewportCommand::CursorHitTest(new_hittest)); + } + } + + // TODO: Implement compare for windows buttons + + let mut recreate_window = false; + + if let Some(new_active) = new.active { + if Some(new_active) != self.active { + self.active = Some(new_active); + recreate_window = true; + } + } + + if let Some(new_close_button) = new.close_button { + if Some(new_close_button) != self.close_button { + self.close_button = Some(new_close_button); + recreate_window = true; + } + } + + if let Some(new_minimize_button) = new.minimize_button { + if Some(new_minimize_button) != self.minimize_button { + self.minimize_button = Some(new_minimize_button); + recreate_window = true; + } + } + + if let Some(new_maximized_button) = new.maximize_button { + if Some(new_maximized_button) != self.maximize_button { + self.maximize_button = Some(new_maximized_button); + recreate_window = true; + } + } + + if let Some(new_title_hidden) = new.title_hidden { + if Some(new_title_hidden) != self.title_hidden { + self.title_hidden = Some(new_title_hidden); + recreate_window = true; + } + } + + if let Some(new_titlebar_transparent) = new.titlebar_transparent { + if Some(new_titlebar_transparent) != self.titlebar_transparent { + self.titlebar_transparent = Some(new_titlebar_transparent); + recreate_window = true; + } + } + + if let Some(new_fullsize_content_view) = new.fullsize_content_view { + if Some(new_fullsize_content_view) != self.fullsize_content_view { + self.fullsize_content_view = Some(new_fullsize_content_view); + recreate_window = true; + } + } + + (commands, recreate_window) + } } /// You can send a `ViewportCommand` to the viewport with `Context::viewport_command`