mirror of
https://github.com/emilk/egui.git
synced 2026-08-31 05:40:03 -04:00
Fix ViewportCommand::InnerSize not resizing viewport on Wayland (#4211)
This commit is contained in:
@@ -23,8 +23,7 @@ use winit::{
|
||||
|
||||
use egui::{
|
||||
epaint::ahash::HashMap, DeferredViewportUiCallback, ImmediateViewport, ViewportBuilder,
|
||||
ViewportClass, ViewportId, ViewportIdMap, ViewportIdPair, ViewportIdSet, ViewportInfo,
|
||||
ViewportOutput,
|
||||
ViewportClass, ViewportId, ViewportIdMap, ViewportIdPair, ViewportInfo, ViewportOutput,
|
||||
};
|
||||
#[cfg(feature = "accesskit")]
|
||||
use egui_winit::accesskit_winit;
|
||||
@@ -103,6 +102,7 @@ struct Viewport {
|
||||
ids: ViewportIdPair,
|
||||
class: ViewportClass,
|
||||
builder: ViewportBuilder,
|
||||
deferred_commands: Vec<egui::viewport::ViewportCommand>,
|
||||
info: ViewportInfo,
|
||||
screenshot_requested: bool,
|
||||
|
||||
@@ -554,7 +554,7 @@ impl GlowWinitRunning {
|
||||
let Some(window) = viewport.window.as_ref() else {
|
||||
return EventResult::Wait;
|
||||
};
|
||||
egui_winit::update_viewport_info(&mut viewport.info, &egui_ctx, window);
|
||||
egui_winit::update_viewport_info(&mut viewport.info, &egui_ctx, window, false);
|
||||
|
||||
let Some(egui_winit) = viewport.egui_winit.as_mut() else {
|
||||
return EventResult::Wait;
|
||||
@@ -640,6 +640,8 @@ impl GlowWinitRunning {
|
||||
viewport_output,
|
||||
} = full_output;
|
||||
|
||||
glutin.remove_viewports_not_in(&viewport_output);
|
||||
|
||||
let GlutinWindowContext {
|
||||
viewports,
|
||||
current_gl_context,
|
||||
@@ -649,6 +651,7 @@ impl GlowWinitRunning {
|
||||
let Some(viewport) = viewports.get_mut(&viewport_id) else {
|
||||
return EventResult::Wait;
|
||||
};
|
||||
|
||||
viewport.info.events.clear(); // they should have been processed
|
||||
let window = viewport.window.clone().unwrap();
|
||||
let gl_surface = viewport.gl_surface.as_ref().unwrap();
|
||||
@@ -715,7 +718,7 @@ impl GlowWinitRunning {
|
||||
}
|
||||
}
|
||||
|
||||
glutin.handle_viewport_output(event_loop, &integration.egui_ctx, viewport_output);
|
||||
glutin.handle_viewport_output(event_loop, &integration.egui_ctx, &viewport_output);
|
||||
|
||||
integration.report_frame_time(frame_timer.total_time_sec()); // don't count auto-save time as part of regular frame time
|
||||
|
||||
@@ -998,8 +1001,7 @@ impl GlutinWindowContext {
|
||||
if let Some(window) = &window {
|
||||
viewport_from_window.insert(window.id(), ViewportId::ROOT);
|
||||
window_from_viewport.insert(ViewportId::ROOT, window.id());
|
||||
info.minimized = window.is_minimized();
|
||||
info.maximized = Some(window.is_maximized());
|
||||
egui_winit::update_viewport_info(&mut info, egui_ctx, window, true);
|
||||
}
|
||||
|
||||
let mut viewports = ViewportIdMap::default();
|
||||
@@ -1009,6 +1011,7 @@ impl GlutinWindowContext {
|
||||
ids: ViewportIdPair::ROOT,
|
||||
class: ViewportClass::Root,
|
||||
builder: viewport_builder,
|
||||
deferred_commands: vec![],
|
||||
info,
|
||||
screenshot_requested: false,
|
||||
viewport_ui_cb: None,
|
||||
@@ -1090,8 +1093,8 @@ impl GlutinWindowContext {
|
||||
&window,
|
||||
&viewport.builder,
|
||||
);
|
||||
viewport.info.minimized = window.is_minimized();
|
||||
viewport.info.maximized = Some(window.is_maximized());
|
||||
|
||||
egui_winit::update_viewport_info(&mut viewport.info, &self.egui_ctx, &window, true);
|
||||
viewport.window.insert(Arc::new(window))
|
||||
};
|
||||
|
||||
@@ -1212,16 +1215,27 @@ impl GlutinWindowContext {
|
||||
self.gl_config.display().get_proc_address(addr)
|
||||
}
|
||||
|
||||
pub(crate) fn remove_viewports_not_in(
|
||||
&mut self,
|
||||
viewport_output: &ViewportIdMap<ViewportOutput>,
|
||||
) {
|
||||
// GC old viewports
|
||||
self.viewports
|
||||
.retain(|id, _| viewport_output.contains_key(id));
|
||||
self.viewport_from_window
|
||||
.retain(|_, id| viewport_output.contains_key(id));
|
||||
self.window_from_viewport
|
||||
.retain(|id, _| viewport_output.contains_key(id));
|
||||
}
|
||||
|
||||
fn handle_viewport_output(
|
||||
&mut self,
|
||||
event_loop: &EventLoopWindowTarget<UserEvent>,
|
||||
egui_ctx: &egui::Context,
|
||||
viewport_output: ViewportIdMap<ViewportOutput>,
|
||||
viewport_output: &ViewportIdMap<ViewportOutput>,
|
||||
) {
|
||||
crate::profile_function!();
|
||||
|
||||
let active_viewports_ids: ViewportIdSet = viewport_output.keys().copied().collect();
|
||||
|
||||
for (
|
||||
viewport_id,
|
||||
ViewportOutput {
|
||||
@@ -1229,58 +1243,60 @@ impl GlutinWindowContext {
|
||||
class,
|
||||
builder,
|
||||
viewport_ui_cb,
|
||||
commands,
|
||||
mut commands,
|
||||
repaint_delay: _, // ignored - we listened to the repaint callback instead
|
||||
},
|
||||
) in viewport_output
|
||||
) in viewport_output.clone()
|
||||
{
|
||||
let ids = ViewportIdPair::from_self_and_parent(viewport_id, parent);
|
||||
|
||||
let viewport = initialize_or_update_viewport(
|
||||
egui_ctx,
|
||||
&mut self.viewports,
|
||||
ids,
|
||||
class,
|
||||
builder,
|
||||
viewport_ui_cb,
|
||||
self.focused_viewport,
|
||||
);
|
||||
|
||||
if let Some(window) = &viewport.window {
|
||||
let old_inner_size = window.inner_size();
|
||||
|
||||
let is_viewport_focused = self.focused_viewport == Some(viewport_id);
|
||||
viewport.deferred_commands.append(&mut commands);
|
||||
|
||||
egui_winit::process_viewport_commands(
|
||||
egui_ctx,
|
||||
&mut viewport.info,
|
||||
commands,
|
||||
std::mem::take(&mut viewport.deferred_commands),
|
||||
window,
|
||||
is_viewport_focused,
|
||||
&mut viewport.screenshot_requested,
|
||||
);
|
||||
|
||||
// For Wayland : https://github.com/emilk/egui/issues/4196
|
||||
if cfg!(target_os = "linux") {
|
||||
let new_inner_size = window.inner_size();
|
||||
if new_inner_size != old_inner_size {
|
||||
self.resize(viewport_id, new_inner_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create windows for any new viewports:
|
||||
self.initialize_all_windows(event_loop);
|
||||
|
||||
// GC old viewports
|
||||
self.viewports
|
||||
.retain(|id, _| active_viewports_ids.contains(id));
|
||||
self.viewport_from_window
|
||||
.retain(|_, id| active_viewports_ids.contains(id));
|
||||
self.window_from_viewport
|
||||
.retain(|id, _| active_viewports_ids.contains(id));
|
||||
self.remove_viewports_not_in(viewport_output);
|
||||
}
|
||||
}
|
||||
|
||||
fn initialize_or_update_viewport<'vp>(
|
||||
egu_ctx: &egui::Context,
|
||||
viewports: &'vp mut ViewportIdMap<Viewport>,
|
||||
fn initialize_or_update_viewport(
|
||||
viewports: &mut ViewportIdMap<Viewport>,
|
||||
ids: ViewportIdPair,
|
||||
class: ViewportClass,
|
||||
mut builder: ViewportBuilder,
|
||||
viewport_ui_cb: Option<Arc<dyn Fn(&egui::Context) + Send + Sync>>,
|
||||
focused_viewport: Option<ViewportId>,
|
||||
) -> &'vp mut Viewport {
|
||||
) -> &mut Viewport {
|
||||
crate::profile_function!();
|
||||
|
||||
if builder.icon.is_none() {
|
||||
@@ -1298,6 +1314,7 @@ fn initialize_or_update_viewport<'vp>(
|
||||
ids,
|
||||
class,
|
||||
builder,
|
||||
deferred_commands: vec![],
|
||||
info: Default::default(),
|
||||
screenshot_requested: false,
|
||||
viewport_ui_cb,
|
||||
@@ -1315,7 +1332,7 @@ fn initialize_or_update_viewport<'vp>(
|
||||
viewport.class = class;
|
||||
viewport.viewport_ui_cb = viewport_ui_cb;
|
||||
|
||||
let (delta_commands, recreate) = viewport.builder.patch(builder);
|
||||
let (mut delta_commands, recreate) = viewport.builder.patch(builder);
|
||||
|
||||
if recreate {
|
||||
log::debug!(
|
||||
@@ -1325,18 +1342,10 @@ fn initialize_or_update_viewport<'vp>(
|
||||
);
|
||||
viewport.window = None;
|
||||
viewport.egui_winit = None;
|
||||
} else if let Some(window) = &viewport.window {
|
||||
let is_viewport_focused = focused_viewport == Some(ids.this);
|
||||
egui_winit::process_viewport_commands(
|
||||
egu_ctx,
|
||||
&mut viewport.info,
|
||||
delta_commands,
|
||||
window,
|
||||
is_viewport_focused,
|
||||
&mut viewport.screenshot_requested,
|
||||
);
|
||||
}
|
||||
|
||||
viewport.deferred_commands.append(&mut delta_commands);
|
||||
|
||||
entry.into_mut()
|
||||
}
|
||||
}
|
||||
@@ -1366,13 +1375,11 @@ fn render_immediate_viewport(
|
||||
let mut glutin = glutin.borrow_mut();
|
||||
|
||||
initialize_or_update_viewport(
|
||||
egui_ctx,
|
||||
&mut glutin.viewports,
|
||||
ids,
|
||||
ViewportClass::Immediate,
|
||||
builder,
|
||||
None,
|
||||
None,
|
||||
);
|
||||
|
||||
if let Err(err) = glutin.initialize_window(viewport_id, event_loop) {
|
||||
@@ -1392,7 +1399,7 @@ fn render_immediate_viewport(
|
||||
let (Some(egui_winit), Some(window)) = (&mut viewport.egui_winit, &viewport.window) else {
|
||||
return;
|
||||
};
|
||||
egui_winit::update_viewport_info(&mut viewport.info, egui_ctx, window);
|
||||
egui_winit::update_viewport_info(&mut viewport.info, egui_ctx, window, false);
|
||||
|
||||
let mut raw_input = egui_winit.take_egui_input(window);
|
||||
raw_input.viewports = glutin
|
||||
@@ -1480,7 +1487,7 @@ fn render_immediate_viewport(
|
||||
|
||||
egui_winit.handle_platform_output(window, platform_output);
|
||||
|
||||
glutin.handle_viewport_output(event_loop, egui_ctx, viewport_output);
|
||||
glutin.handle_viewport_output(event_loop, egui_ctx, &viewport_output);
|
||||
}
|
||||
|
||||
#[cfg(feature = "__screenshot")]
|
||||
|
||||
Reference in New Issue
Block a user