1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-30 13:20:05 -04:00

Fix ViewportCommand::InnerSize not resizing viewport on Wayland (#4211)

This commit is contained in:
rustbasic
2024-03-31 04:09:28 +09:00
committed by GitHub
parent 5a0a1e96e0
commit 21835c3176
3 changed files with 199 additions and 161 deletions

View File

@@ -76,6 +76,7 @@ pub struct Viewport {
ids: ViewportIdPair,
class: ViewportClass,
builder: ViewportBuilder,
deferred_commands: Vec<egui::viewport::ViewportCommand>,
info: ViewportInfo,
screenshot_requested: bool,
@@ -154,13 +155,11 @@ impl WgpuWinitApp {
} = &mut *running.shared.borrow_mut();
initialize_or_update_viewport(
egui_ctx,
viewports,
ViewportIdPair::ROOT,
ViewportClass::Root,
self.native_options.viewport.clone(),
None,
None,
)
.initialize_window(event_loop, egui_ctx, viewport_from_window, painter);
}
@@ -278,6 +277,9 @@ impl WgpuWinitApp {
let mut viewport_from_window = HashMap::default();
viewport_from_window.insert(window.id(), ViewportId::ROOT);
let mut info = ViewportInfo::default();
egui_winit::update_viewport_info(&mut info, &egui_ctx, &window, true);
let mut viewports = Viewports::default();
viewports.insert(
ViewportId::ROOT,
@@ -285,11 +287,8 @@ impl WgpuWinitApp {
ids: ViewportIdPair::ROOT,
class: ViewportClass::Root,
builder,
info: ViewportInfo {
minimized: window.is_minimized(),
maximized: Some(window.is_maximized()),
..Default::default()
},
deferred_commands: vec![],
info,
screenshot_requested: false,
viewport_ui_cb: None,
window: Some(window),
@@ -603,7 +602,7 @@ impl WgpuWinitRunning {
let Some(window) = window else {
return EventResult::Wait;
};
egui_winit::update_viewport_info(info, &integration.egui_ctx, window);
egui_winit::update_viewport_info(info, &integration.egui_ctx, window, false);
{
crate::profile_scope!("set_window");
@@ -638,7 +637,7 @@ impl WgpuWinitRunning {
// ------------------------------------------------------------
let mut shared = shared.borrow_mut();
let mut shared_mut = shared.borrow_mut();
let SharedState {
egui_ctx,
@@ -646,7 +645,17 @@ impl WgpuWinitRunning {
painter,
viewport_from_window,
focused_viewport,
} = &mut *shared;
} = &mut *shared_mut;
let FullOutput {
platform_output,
textures_delta,
shapes,
pixels_per_point,
viewport_output,
} = full_output;
remove_viewports_not_in(viewports, painter, viewport_from_window, &viewport_output);
let Some(viewport) = viewports.get_mut(&viewport_id) else {
return EventResult::Wait;
@@ -663,14 +672,6 @@ impl WgpuWinitRunning {
return EventResult::Wait;
};
let FullOutput {
platform_output,
textures_delta,
shapes,
pixels_per_point,
viewport_output,
} = full_output;
egui_winit.handle_platform_output(window, platform_output);
let clipped_primitives = egui_ctx.tessellate(shapes, pixels_per_point);
@@ -700,8 +701,10 @@ impl WgpuWinitRunning {
handle_viewport_output(
&integration.egui_ctx,
viewport_output,
&viewport_output,
viewports,
painter,
viewport_from_window,
*focused_viewport,
);
@@ -876,9 +879,7 @@ impl Viewport {
painter.max_texture_side(),
));
self.info.minimized = window.is_minimized();
self.info.maximized = Some(window.is_maximized());
egui_winit::update_viewport_info(&mut self.info, egui_ctx, &window, true);
self.window = Some(window);
}
Err(err) => {
@@ -933,15 +934,8 @@ fn render_immediate_viewport(
..
} = &mut *shared.borrow_mut();
let viewport = initialize_or_update_viewport(
egui_ctx,
viewports,
ids,
ViewportClass::Immediate,
builder,
None,
None,
);
let viewport =
initialize_or_update_viewport(viewports, ids, ViewportClass::Immediate, builder, None);
if viewport.window.is_none() {
viewport.initialize_window(event_loop, egui_ctx, viewport_from_window, painter);
}
@@ -949,7 +943,7 @@ fn render_immediate_viewport(
let (Some(window), Some(egui_winit)) = (&viewport.window, &mut viewport.egui_winit) 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 input = egui_winit.take_egui_input(window);
input.viewports = viewports
@@ -978,13 +972,14 @@ fn render_immediate_viewport(
// ------------------------------------------
let mut shared = shared.borrow_mut();
let mut shared_mut = shared.borrow_mut();
let SharedState {
viewports,
painter,
viewport_from_window,
focused_viewport,
..
} = &mut *shared;
} = &mut *shared_mut;
let Some(viewport) = viewports.get_mut(&ids.this) else {
return;
@@ -1016,14 +1011,37 @@ fn render_immediate_viewport(
egui_winit.handle_platform_output(window, platform_output);
handle_viewport_output(&egui_ctx, viewport_output, viewports, *focused_viewport);
handle_viewport_output(
&egui_ctx,
&viewport_output,
viewports,
painter,
viewport_from_window,
*focused_viewport,
);
}
pub(crate) fn remove_viewports_not_in(
viewports: &mut ViewportIdMap<Viewport>,
painter: &mut egui_wgpu::winit::Painter,
viewport_from_window: &mut HashMap<WindowId, ViewportId>,
viewport_output: &ViewportIdMap<ViewportOutput>,
) {
let active_viewports_ids: ViewportIdSet = viewport_output.keys().copied().collect();
// Prune dead viewports:
viewports.retain(|id, _| active_viewports_ids.contains(id));
viewport_from_window.retain(|_, id| active_viewports_ids.contains(id));
painter.gc_viewports(&active_viewports_ids);
}
/// Add new viewports, and update existing ones:
fn handle_viewport_output(
egui_ctx: &egui::Context,
viewport_output: ViewportIdMap<ViewportOutput>,
viewport_output: &ViewportIdMap<ViewportOutput>,
viewports: &mut ViewportIdMap<Viewport>,
painter: &mut egui_wgpu::winit::Painter,
viewport_from_window: &mut HashMap<WindowId, ViewportId>,
focused_viewport: Option<ViewportId>,
) {
for (
@@ -1033,46 +1051,56 @@ fn handle_viewport_output(
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,
viewports,
ids,
class,
builder,
viewport_ui_cb,
focused_viewport,
);
let viewport =
initialize_or_update_viewport(viewports, ids, class, builder, viewport_ui_cb);
if let Some(window) = viewport.window.as_ref() {
let old_inner_size = window.inner_size();
let is_viewport_focused = 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 {
if let (Some(width), Some(height)) = (
NonZeroU32::new(new_inner_size.width),
NonZeroU32::new(new_inner_size.height),
) {
painter.on_window_resized(viewport_id, width, height);
}
}
}
}
}
remove_viewports_not_in(viewports, painter, viewport_from_window, viewport_output);
}
fn initialize_or_update_viewport<'vp>(
egui_ctx: &egui::Context,
viewports: &'vp mut Viewports,
fn initialize_or_update_viewport(
viewports: &mut Viewports,
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() {
@@ -1090,6 +1118,7 @@ fn initialize_or_update_viewport<'vp>(
ids,
class,
builder,
deferred_commands: vec![],
info: Default::default(),
screenshot_requested: false,
viewport_ui_cb,
@@ -1106,7 +1135,7 @@ fn initialize_or_update_viewport<'vp>(
viewport.ids.parent = ids.parent;
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!(
@@ -1116,18 +1145,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(
egui_ctx,
&mut viewport.info,
delta_commands,
window,
is_viewport_focused,
&mut viewport.screenshot_requested,
);
}
viewport.deferred_commands.append(&mut delta_commands);
entry.into_mut()
}
}